/* * The contents of this file are subject to the Initial * Developer's Public License Version 1.0 (the "License"); * you may not use this file except in compliance with the * License. You may obtain a copy of the License at * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. * * Software distributed under the License is distributed AS IS, * WITHOUT WARRANTY OF ANY KIND, either express or implied. * See the License for the specific language governing rights * and limitations under the License. * * The Original Code was created by Adriano dos Santos Fernandes * for the Firebird Open Source RDBMS project. * * Copyright (c) 2008 Adriano dos Santos Fernandes * and all contributors signed below. * * All Rights Reserved. * Contributor(s): ______________________________________. */ #ifndef DSQL_DDL_NODES_H #define DSQL_DDL_NODES_H #include "../jrd/blr.h" #include "../jrd/dyn.h" #include "../jrd/msg_encode.h" #include "../dsql/node.h" #include "../dsql/make_proto.h" #include "../dsql/BlrWriter.h" #include "../dsql/Nodes.h" #include "../common/classes/array.h" #include "../common/classes/ByteChunk.h" #include "../common/classes/Nullable.h" #include "../jrd/vio_proto.h" #include "../dsql/errd_proto.h" namespace Jrd { class CompoundStmtNode; struct ValueSourceClause { ValueSourceClause(MemoryPool& p) : value(NULL), source(p) { } dsql_nod* value; Firebird::string source; }; class DbFileClause { public: DbFileClause(MemoryPool& p, const DbFileClause& o) : name(p, o.name), start(o.start), length(o.length) { } explicit DbFileClause(MemoryPool& p, const Firebird::PathName& aName) : name(p, aName), start(0), length(0) { } public: Firebird::PathName name; // File name SLONG start; // Starting page SLONG length; // File length in pages }; class ExternalClause { public: ExternalClause(MemoryPool& p, const ExternalClause& o) : name(p, o.name), engine(p, o.engine), udfModule(p, o.udfModule) { } explicit ExternalClause(MemoryPool& p) : name(p), engine(p), udfModule(p) { } public: Firebird::string name; Firebird::MetaName engine; Firebird::string udfModule; }; class TypeClause { public: TypeClause(MemoryPool& pool, dsql_fld* aField, const Firebird::MetaName& aCollate); virtual ~TypeClause() {} public: void resolve(DsqlCompilerScratch* dsqlScratch, bool modifying = false); void setup(DsqlCompilerScratch* dsqlScratch); public: virtual void print(Firebird::string& text) const; public: USHORT type; FLD_LENGTH length; SSHORT scale; SSHORT subType; USHORT segLength; USHORT precision; USHORT charLength; SSHORT charSetId; SSHORT collationId; SSHORT textType; bool collateSpecified; bool fullDomain; bool notNull; Firebird::MetaName fieldSource; Firebird::MetaName typeOfTable; Firebird::MetaName typeOfName; public: dsql_fld* legacyField; Firebird::MetaName collate; }; class ParameterClause : public TypeClause { public: ParameterClause(MemoryPool& pool, dsql_fld* field, const Firebird::MetaName& aCollate, ValueSourceClause* aDefaultClause, dsql_nod* aLegacyParameter); public: void print(Firebird::string& text) const; public: Firebird::MetaName name; ValueSourceClause* defaultClause; dsql_nod* legacyParameter; Nullable udfMechanism; }; template class RecreateNode : public DdlNode { public: RecreateNode(MemoryPool& p, CreateNode* aCreateNode) : DdlNode(p), createNode(aCreateNode), dropNode(p, createNode->name) { dropNode.silent = true; } public: virtual void print(Firebird::string& text, Firebird::Array& /*nodes*/) const { text.printf("RecreateNode\n"); } virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction) { // run all statements under savepoint control AutoSavePoint savePoint(tdbb, transaction); dropNode.execute(tdbb, dsqlScratch, transaction); createNode->execute(tdbb, dsqlScratch, transaction); savePoint.release(); // everything is ok } virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch) { createNode->dsqlPass(dsqlScratch); dropNode.dsqlPass(dsqlScratch); return DdlNode::dsqlPass(dsqlScratch); } protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(ERROR_CODE) << createNode->name; } protected: CreateNode* createNode; DropNode dropNode; }; class AlterCharSetNode : public DdlNode { public: AlterCharSetNode(MemoryPool& pool, const Firebird::MetaName& aCharSet, const Firebird::MetaName& aDefaultCollation) : DdlNode(pool), charSet(pool, aCharSet), defaultCollation(pool, aDefaultCollation) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_alter_charset_failed) << charSet; } private: Firebird::MetaName charSet; Firebird::MetaName defaultCollation; }; class CommentOnNode : public DdlNode { public: CommentOnNode(MemoryPool& pool, int aObjType, const Firebird::MetaName& aObjName, const Firebird::MetaName& aSubName, const Firebird::string& aText, const char* aTextCharSet) : DdlNode(pool), objType(aObjType), objName(pool, aObjName), subName(pool, aSubName), text(pool, aText), textCharSet(aTextCharSet) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { /*** ASF: FIXME: When returning, str is destroyed but its pointer is recorded. Firebird::string str(objName.c_str()); if (subName.hasData()) str.append(".").append(subName.c_str()); statusVector << Firebird::Arg::Gds(isc_dsql_comment_on_failed) << str; ***/ statusVector << Firebird::Arg::Gds(isc_dsql_comment_on_failed) << objName; } private: int objType; Firebird::MetaName objName; Firebird::MetaName subName; Firebird::string text; const char* textCharSet; }; class CreateAlterFunctionNode : public DdlNode { public: CreateAlterFunctionNode(MemoryPool& pool, const Firebird::MetaName& aName) : DdlNode(pool), name(pool, aName), create(true), alter(false), external(NULL), deterministic(false), parameters(pool), returnType(pool, NULL, NULL, NULL, NULL), localDeclList(NULL), source(pool), body(NULL), compiled(false), invalid(false), package(pool), packageOwner(pool), privateScope(false), udfReturnPos(0) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(createAlterCode(create, alter, isc_dsql_create_func_failed, isc_dsql_alter_func_failed, isc_dsql_create_alter_func_failed)) << name; } private: bool isUdf() const { return external && external->udfModule.hasData(); } void executeCreate(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); bool executeAlter(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction, bool secondPass, bool runTriggers); void storeArgument(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction, unsigned pos, const ParameterClause& parameter, const bid* comment); void compile(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch); void collectParamComments(thread_db* tdbb, jrd_tra* transaction, MetaNameBidMap& items); public: Firebird::MetaName name; bool create; bool alter; ExternalClause* external; bool deterministic; Firebird::Array parameters; ParameterClause returnType; NestConst localDeclList; Firebird::string source; NestConst body; bool compiled; bool invalid; Firebird::MetaName package; Firebird::string packageOwner; bool privateScope; SLONG udfReturnPos; }; class AlterExternalFunctionNode : public DdlNode { public: AlterExternalFunctionNode(MemoryPool& p, const Firebird::MetaName& aName) : DdlNode(p), name(p, aName), clauses(p) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_alter_func_failed) << name; } public: Firebird::MetaName name; ExternalClause clauses; }; class DropFunctionNode : public DdlNode { public: DropFunctionNode(MemoryPool& pool, const Firebird::MetaName& aName) : DdlNode(pool), name(pool, aName), silent(false), package(pool) { } public: static void dropArguments(thread_db* tdbb, jrd_tra* transaction, const Firebird::MetaName& functionName, const Firebird::MetaName& packageName); public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_drop_func_failed) << name; } public: Firebird::MetaName name; bool silent; Firebird::MetaName package; }; typedef RecreateNode RecreateFunctionNode; class CreateAlterProcedureNode : public DdlNode { public: CreateAlterProcedureNode(MemoryPool& pool, const Firebird::MetaName& aName) : DdlNode(pool), name(pool, aName), create(true), alter(false), external(NULL), parameters(pool), returns(pool), source(pool), localDeclList(NULL), body(NULL), compiled(false), invalid(false), package(pool), packageOwner(pool), privateScope(false) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(createAlterCode(create, alter, isc_dsql_create_proc_failed, isc_dsql_alter_proc_failed, isc_dsql_create_alter_proc_failed)) << name; } private: void executeCreate(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); bool executeAlter(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction, bool secondPass, bool runTriggers); void storeParameter(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction, USHORT type, unsigned pos, const ParameterClause& parameter, const bid* comment); void compile(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch); void collectParamComments(thread_db* tdbb, jrd_tra* transaction, MetaNameBidMap& items); public: Firebird::MetaName name; bool create; bool alter; ExternalClause* external; Firebird::Array parameters; Firebird::Array returns; Firebird::string source; NestConst localDeclList; NestConst body; bool compiled; bool invalid; Firebird::MetaName package; Firebird::string packageOwner; bool privateScope; }; class DropProcedureNode : public DdlNode { public: DropProcedureNode(MemoryPool& pool, const Firebird::MetaName& aName) : DdlNode(pool), name(pool, aName), silent(false), package(pool) { } public: static void dropParameters(thread_db* tdbb, jrd_tra* transaction, const Firebird::MetaName& procedureName, const Firebird::MetaName& packageName); public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_drop_proc_failed) << name; } public: Firebird::MetaName name; bool silent; Firebird::MetaName package; }; typedef RecreateNode RecreateProcedureNode; class TriggerDefinition { public: explicit TriggerDefinition(MemoryPool& p) : name(p), relationName(p), external(NULL), source(p), systemFlag(fb_sysflag_user), fkTrigger(false) { } void store(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); bool modify(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void preModify(thread_db* /*tdbb*/, DsqlCompilerScratch* /*dsqlScratch*/, jrd_tra* /*transaction*/) { } virtual void postModify(thread_db* /*tdbb*/, DsqlCompilerScratch* /*dsqlScratch*/, jrd_tra* /*transaction*/) { } public: Firebird::MetaName name; Firebird::MetaName relationName; Nullable type; Nullable active; Nullable position; ExternalClause* external; Firebird::string source; Firebird::ByteChunk blrData; Firebird::ByteChunk debugData; USHORT systemFlag; bool fkTrigger; }; class CreateAlterTriggerNode : public DdlNode, public TriggerDefinition { public: CreateAlterTriggerNode(MemoryPool& p, const Firebird::MetaName& aName) : DdlNode(p), TriggerDefinition(p), create(true), alter(false), localDeclList(NULL), body(NULL), compiled(false), invalid(false) { name = aName; } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(createAlterCode(create, alter, isc_dsql_create_trigger_failed, isc_dsql_alter_trigger_failed, isc_dsql_create_alter_trigger_failed)) << name; } virtual void preModify(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction) { if (alter) { executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_ALTER_TRIGGER, name); } } virtual void postModify(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction) { if (alter) { executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_ALTER_TRIGGER, name); } } private: void executeCreate(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); void compile(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch); static inline bool hasOldContext(const unsigned value) { const unsigned val1 = ((value + 1) >> 1) & 3; const unsigned val2 = ((value + 1) >> 3) & 3; const unsigned val3 = ((value + 1) >> 5) & 3; return (val1 && val1 != 1) || (val2 && val2 != 1) || (val3 && val3 != 1); } static inline bool hasNewContext(const unsigned value) { const unsigned val1 = ((value + 1) >> 1) & 3; const unsigned val2 = ((value + 1) >> 3) & 3; const unsigned val3 = ((value + 1) >> 5) & 3; return (val1 && val1 != 3) || (val2 && val2 != 3) || (val3 && val3 != 3); } public: bool create; bool alter; NestConst localDeclList; NestConst body; bool compiled; bool invalid; }; class DropTriggerNode : public DdlNode { public: DropTriggerNode(MemoryPool& p, const Firebird::MetaName& aName) : DdlNode(p), name(p, aName), silent(false) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_drop_trigger_failed) << name; } public: Firebird::MetaName name; bool silent; }; typedef RecreateNode RecreateTriggerNode; class CreateCollationNode : public DdlNode { public: CreateCollationNode(MemoryPool& p, const Firebird::MetaName& aName, const Firebird::MetaName& aForCharSet) : DdlNode(p), name(p, aName), forCharSet(p, aForCharSet), fromName(p), fromExternal(p), specificAttributes(p), attributesOn(0), attributesOff(0), forCharSetId(0), fromCollationId(0) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); void setAttribute(USHORT attribute) { if ((attributesOn | attributesOff) & attribute) { // msg: 222: "Invalid collation attributes" using namespace Firebird; ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) << Arg::PrivateDyn(222)); } attributesOn |= attribute; } void unsetAttribute(USHORT attribute) { if ((attributesOn | attributesOff) & attribute) { // msg: 222: "Invalid collation attributes" using namespace Firebird; ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) << Arg::PrivateDyn(222)); } attributesOff |= attribute; } protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_create_collation_failed) << name; } public: Firebird::MetaName name; Firebird::MetaName forCharSet; Firebird::MetaName fromName; Firebird::string fromExternal; Firebird::UCharBuffer specificAttributes; private: USHORT attributesOn; USHORT attributesOff; USHORT forCharSetId; USHORT fromCollationId; }; class DropCollationNode : public DdlNode { public: DropCollationNode(MemoryPool& p, const Firebird::MetaName& aName) : DdlNode(p), name(p, aName) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_drop_collation_failed) << name; } public: Firebird::MetaName name; }; class CreateDomainNode : public DdlNode { public: CreateDomainNode(MemoryPool& p, const ParameterClause& aNameType) : DdlNode(p), nameType(aNameType), notNull(false), check(NULL) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_create_domain_failed) << nameType.name; } public: ParameterClause nameType; bool notNull; ValueSourceClause* check; }; class AlterDomainNode : public DdlNode { public: AlterDomainNode(MemoryPool& p, const Firebird::MetaName& aName) : DdlNode(p), name(p, aName), dropConstraint(false), dropDefault(false), setConstraint(NULL), setDefault(NULL), renameTo(p) { } public: static void checkUpdate(const dyn_fld& origFld, const dyn_fld& newFld); static ULONG checkUpdateNumericType(const dyn_fld& origFld, const dyn_fld& newFld); static void getDomainType(thread_db* tdbb, jrd_tra* transaction, dyn_fld& dynFld); static void modifyLocalFieldIndex(thread_db* tdbb, jrd_tra* transaction, const Firebird::MetaName& relationName, const Firebird::MetaName& fieldName, const Firebird::MetaName& newFieldName); virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_alter_domain_failed) << name; } private: void rename(thread_db* tdbb, jrd_tra* transaction, SSHORT dimensions); public: Firebird::MetaName name; bool dropConstraint; bool dropDefault; ValueSourceClause* setConstraint; ValueSourceClause* setDefault; Firebird::MetaName renameTo; Firebird::AutoPtr type; Nullable notNullFlag; // true = NOT NULL / false = NULL }; class DropDomainNode : public DdlNode { public: DropDomainNode(MemoryPool& p, const Firebird::MetaName& aName) : DdlNode(p), name(p, aName) { } static bool deleteDimensionRecords(thread_db* tdbb, jrd_tra* transaction, const Firebird::MetaName& name); public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_drop_domain_failed) << name; } private: void check(thread_db* tdbb, jrd_tra* transaction); public: Firebird::MetaName name; }; class CreateAlterExceptionNode : public DdlNode { public: CreateAlterExceptionNode(MemoryPool& p, const Firebird::MetaName& aName, const Firebird::string& aMessage) : DdlNode(p), name(p, aName), message(p, aMessage), create(true), alter(false) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(createAlterCode(create, alter, isc_dsql_create_except_failed, isc_dsql_alter_except_failed, isc_dsql_create_alter_except_failed)) << name; } private: void executeCreate(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); bool executeAlter(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); public: Firebird::MetaName name; Firebird::string message; bool create; bool alter; }; class DropExceptionNode : public DdlNode { public: DropExceptionNode(MemoryPool& p, const Firebird::MetaName& aName) : DdlNode(p), name(p, aName), silent(false) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_drop_except_failed) << name; } public: Firebird::MetaName name; bool silent; }; typedef RecreateNode RecreateExceptionNode; class CreateSequenceNode : public DdlNode { public: CreateSequenceNode(MemoryPool& pool, const Firebird::MetaName& aName) : DdlNode(pool), name(pool, aName) { } static void store(thread_db* tdbb, jrd_tra* transaction, const Firebird::MetaName& name, fb_sysflag sysFlag); public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_create_sequence_failed) << name; } public: Firebird::MetaName name; }; class DropSequenceNode : public DdlNode { public: DropSequenceNode(MemoryPool& pool, const Firebird::MetaName& aName) : DdlNode(pool), name(pool, aName), silent(false) { } static void deleteIdentity(thread_db* tdbb, jrd_tra* transaction, const Firebird::MetaName& name); public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_drop_sequence_failed) << name; } public: Firebird::MetaName name; bool silent; }; typedef RecreateNode RecreateSequenceNode; class RelationNode : public DdlNode { public: class FieldDefinition { public: explicit FieldDefinition(MemoryPool& p) : name(p), relationName(p), fieldSource(p), identitySequence(p), defaultSource(p), baseField(p) { } void modify(thread_db* tdbb, jrd_tra* transaction); void store(thread_db* tdbb, jrd_tra* transaction); public: Firebird::MetaName name; Firebird::MetaName relationName; Firebird::MetaName fieldSource; Firebird::MetaName identitySequence; Nullable collationId; Nullable notNullFlag; // true = NOT NULL / false = NULL Nullable position; Firebird::string defaultSource; Firebird::ByteChunk defaultValue; Nullable viewContext; Firebird::MetaName baseField; }; struct IndexConstraintClause { IndexConstraintClause(MemoryPool& p) : name(p), descending(false) { } Firebird::MetaName name; bool descending; }; struct Constraint : public PermanentStorage { enum Type { TYPE_CHECK, TYPE_NOT_NULL, TYPE_PK, TYPE_UNIQUE, TYPE_FK }; // Specialized BlrWriter for constraints. class BlrWriter : public Jrd::BlrWriter { public: explicit BlrWriter(MemoryPool& p) : Jrd::BlrWriter(p), dsqlScratch(NULL) { } void init(DsqlCompilerScratch* aDsqlScratch) { dsqlScratch = aDsqlScratch; dsqlScratch->getBlrData().clear(); dsqlScratch->getDebugData().clear(); appendUChar(isVersion4() ? blr_version4 : blr_version5); } virtual bool isVersion4() { return dsqlScratch->isVersion4(); } protected: virtual bool isDdlDyn() { return false; } private: DsqlCompilerScratch* dsqlScratch; }; explicit Constraint(MemoryPool& p) : PermanentStorage(p), type(TYPE_CHECK), // Just something to initialize. Do not assume it. name(p), columns(p), index(NULL), refRelation(p), refColumns(p), refUpdateAction(RI_RESTRICT), refDeleteAction(RI_RESTRICT), triggers(p), blrWritersHolder(p) { } Constraint::Type type; Firebird::MetaName name; Firebird::ObjectsArray columns; IndexConstraintClause* index; Firebird::MetaName refRelation; Firebird::ObjectsArray refColumns; const char* refUpdateAction; const char* refDeleteAction; Firebird::ObjectsArray triggers; Firebird::ObjectsArray blrWritersHolder; }; struct Clause : public PermanentStorage { enum Type { TYPE_ADD_CONSTRAINT, TYPE_ADD_COLUMN, TYPE_ALTER_COL_NAME, TYPE_ALTER_COL_NULL, TYPE_ALTER_COL_POS, TYPE_ALTER_COL_TYPE, TYPE_DROP_COLUMN, TYPE_DROP_CONSTRAINT }; explicit Clause(MemoryPool& p, Type aType) : PermanentStorage(p), type(aType) { } const Type type; }; struct RefActionClause { static const unsigned ACTION_CASCADE = 1; static const unsigned ACTION_SET_DEFAULT = 2; static const unsigned ACTION_SET_NULL = 3; static const unsigned ACTION_NONE = 4; RefActionClause(MemoryPool& p, unsigned aUpdateAction, unsigned aDeleteAction) : updateAction(aUpdateAction), deleteAction(aDeleteAction) { } unsigned updateAction; unsigned deleteAction; }; struct AddConstraintClause : public Clause { enum ConstraintType { CTYPE_NOT_NULL, CTYPE_PK, CTYPE_FK, CTYPE_UNIQUE, CTYPE_CHECK }; AddConstraintClause(MemoryPool& p) : Clause(p, TYPE_ADD_CONSTRAINT), name(p), constraintType(CTYPE_NOT_NULL), columns(p), index(NULL), refRelation(p), refColumns(p), refAction(NULL), check(NULL) { } Firebird::MetaName name; ConstraintType constraintType; Firebird::ObjectsArray columns; IndexConstraintClause* index; Firebird::MetaName refRelation; Firebird::ObjectsArray refColumns; RefActionClause* refAction; ValueSourceClause* check; }; struct AddColumnClause : public Clause { explicit AddColumnClause(MemoryPool& p) : Clause(p, TYPE_ADD_COLUMN), field(NULL), defaultValue(NULL), constraints(p), collate(p), domain(p), computed(NULL), identity(false) { } dsql_fld* field; ValueSourceClause* defaultValue; Firebird::ObjectsArray constraints; Firebird::MetaName collate; Firebird::MetaName domain; ValueSourceClause* computed; bool identity; }; struct AlterColNameClause : public Clause { explicit AlterColNameClause(MemoryPool& p) : Clause(p, TYPE_ALTER_COL_NAME), fromName(p), toName(p) { } Firebird::MetaName fromName; Firebird::MetaName toName; }; struct AlterColNullClause : public Clause { explicit AlterColNullClause(MemoryPool& p) : Clause(p, TYPE_ALTER_COL_NULL), name(p), notNullFlag(false) { } Firebird::MetaName name; bool notNullFlag; }; struct AlterColPosClause : public Clause { explicit AlterColPosClause(MemoryPool& p) : Clause(p, TYPE_ALTER_COL_POS), name(p), newPos(0) { } Firebird::MetaName name; SSHORT newPos; }; struct AlterColTypeClause : public Clause { explicit AlterColTypeClause(MemoryPool& p) : Clause(p, TYPE_ALTER_COL_TYPE), field(NULL), domain(p), defaultValue(NULL), dropDefault(false), computed(NULL) { } dsql_fld* field; Firebird::MetaName domain; ValueSourceClause* defaultValue; bool dropDefault; ValueSourceClause* computed; }; struct DropColumnClause : public Clause { explicit DropColumnClause(MemoryPool& p) : Clause(p, TYPE_DROP_COLUMN), name(p), cascade(false) { } Firebird::MetaName name; bool cascade; }; struct DropConstraintClause : public Clause { explicit DropConstraintClause(MemoryPool& p) : Clause(p, TYPE_DROP_CONSTRAINT), name(p) { } Firebird::MetaName name; }; RelationNode(MemoryPool& p, dsql_nod* aDsqlNode); static void deleteLocalField(thread_db* tdbb, jrd_tra* transaction, const Firebird::MetaName& relationName, const Firebird::MetaName& fieldName); protected: void defineField(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction, const AddColumnClause* clause, SSHORT position, const Firebird::ObjectsArray* pkcols); bool defineDefault(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, dsql_fld* field, const ValueSourceClause* clause, Firebird::string& source, BlrWriter::BlrData& value); void makeConstraint(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction, const AddConstraintClause* clause, Firebird::ObjectsArray& constraints, bool* notNull = NULL); void defineConstraint(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction, Constraint& constraint); void defineCheckConstraint(DsqlCompilerScratch* dsqlScratch, Constraint& constraint, const ValueSourceClause* clause); void defineCheckConstraintTrigger(DsqlCompilerScratch* dsqlScratch, Constraint& constraint, const ValueSourceClause* clause, FB_UINT64 triggerType); void defineSetDefaultTrigger(DsqlCompilerScratch* dsqlScratch, Constraint& constraint, bool onUpdate); void defineSetNullTrigger(DsqlCompilerScratch* dsqlScratch, Constraint& constraint, bool onUpdate); void defineDeleteCascadeTrigger(DsqlCompilerScratch* dsqlScratch, Constraint& constraint); void defineUpdateCascadeTrigger(DsqlCompilerScratch* dsqlScratch, Constraint& constraint); void generateUnnamedTriggerBeginning(Constraint& constraint, bool onUpdate, BlrWriter& blrWriter); void stuffDefaultBlr(const Firebird::ByteChunk& defaultBlr, BlrWriter& blrWriter); void stuffMatchingBlr(Constraint& constraint, BlrWriter& blrWriter); void stuffTriggerFiringCondition(const Constraint& constraint, BlrWriter& blrWriter); public: dsql_nod* dsqlNode; Firebird::MetaName name; Firebird::Array clauses; }; class CreateRelationNode : public RelationNode { public: CreateRelationNode(MemoryPool& p, dsql_nod* aDsqlNode, const Firebird::PathName* aExternalFile = NULL) : RelationNode(p, aDsqlNode), externalFile(aExternalFile), relationType(rel_persistent) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_create_table_failed) << name; } private: const Firebird::ObjectsArray* findPkColumns(); public: const Firebird::PathName* externalFile; rel_t relationType; }; class AlterRelationNode : public RelationNode { public: AlterRelationNode(MemoryPool& p, dsql_nod* aDsqlNode) : RelationNode(p, aDsqlNode) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_alter_table_failed) << name; } private: void modifyField(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction, const AlterColTypeClause* clause); }; class DropRelationNode : public DdlNode { public: DropRelationNode(MemoryPool& p, const Firebird::MetaName& aName, bool aView = false) : DdlNode(p), name(p, aName), view(aView), silent(false) { } static void deleteGlobalField(thread_db* tdbb, jrd_tra* transaction, const Firebird::MetaName& globalName); public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_drop_table_failed) << name; } public: Firebird::MetaName name; bool view; bool silent; }; typedef RecreateNode RecreateTableNode; class CreateAlterViewNode : public RelationNode { public: CreateAlterViewNode(MemoryPool& p, dsql_nod* aDsqlNode, dsql_nod* aViewFields, dsql_nod* aSelectExpr) : RelationNode(p, aDsqlNode), create(true), alter(false), viewFields(aViewFields), selectExpr(aSelectExpr), source(p), withCheckOption(false) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(createAlterCode(create, alter, isc_dsql_create_view_failed, isc_dsql_alter_view_failed, isc_dsql_create_alter_view_failed)) << name; } private: void createCheckTriggers(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, dsql_nod* items); void createCheckTrigger(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, dsql_nod* rse, dsql_nod* items, CompoundStmtNode* actions, TriggerType triggerType); void defineUpdateAction(DsqlCompilerScratch* dsqlScratch, dsql_nod** baseAndNode, dsql_nod** baseRelation, dsql_nod* items); static dsql_nod* replaceFieldNames(dsql_nod* input, dsql_nod* searchFields, dsql_nod* replaceFields, bool nullThem, const char* contextName); public: bool create; bool alter; dsql_nod* viewFields; dsql_nod* selectExpr; Firebird::string source; bool withCheckOption; }; class RecreateViewNode : public RecreateNode { public: RecreateViewNode(MemoryPool& p, CreateAlterViewNode* aCreateNode) : RecreateNode( p, aCreateNode) { dropNode.view = true; } }; class CreateIndexNode : public DdlNode { public: struct Definition { Definition() : type(0) { expressionBlr.clear(); expressionSource.clear(); } Firebird::MetaName relation; Firebird::ObjectsArray columns; Nullable unique; Nullable descending; Nullable inactive; SSHORT type; bid expressionBlr; bid expressionSource; Firebird::MetaName refRelation; Firebird::ObjectsArray refColumns; }; public: CreateIndexNode(MemoryPool& p, const Firebird::MetaName& aName) : DdlNode(p), name(p, aName), unique(false), descending(false), legacyRelation(NULL), columns(NULL), computed(NULL) { } public: static void store(thread_db* tdbb, jrd_tra* transaction, Firebird::MetaName& name, const Definition& definition, Firebird::MetaName* referredIndexName = NULL); public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_create_index_failed) << name; } public: Firebird::MetaName name; bool unique; bool descending; dsql_nod* legacyRelation; dsql_nod* columns; ValueSourceClause* computed; }; class AlterIndexNode : public DdlNode { public: AlterIndexNode(MemoryPool& p, const Firebird::MetaName& aName, bool aActive) : DdlNode(p), name(p, aName), active(aActive) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_alter_index_failed) << name; } public: Firebird::MetaName name; bool active; }; class SetStatisticsNode : public DdlNode { public: SetStatisticsNode(MemoryPool& p, const Firebird::MetaName& aName) : DdlNode(p), name(p, aName) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { // ASF: using ALTER INDEX's code. statusVector << Firebird::Arg::Gds(isc_dsql_alter_index_failed) << name; } public: Firebird::MetaName name; }; class DropIndexNode : public DdlNode { public: DropIndexNode(MemoryPool& p, const Firebird::MetaName& aName) : DdlNode(p), name(p, aName) { } static bool deleteSegmentRecords(thread_db* tdbb, jrd_tra* transaction, const Firebird::MetaName& name); public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_drop_index_failed) << name; } public: Firebird::MetaName name; }; class CreateFilterNode : public DdlNode { public: struct NameNumber { NameNumber(MemoryPool& p, const Firebird::MetaName& aName) : name(p, aName), number(0) { } NameNumber(MemoryPool& p, SSHORT aNumber) : name(p), number(aNumber) { } Firebird::MetaName name; SSHORT number; }; public: CreateFilterNode(MemoryPool& p, const Firebird::MetaName& aName) : DdlNode(p), name(p, aName), inputFilter(NULL), outputFilter(NULL), entryPoint(p), moduleName(p) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_create_filter_failed) << name; } public: Firebird::MetaName name; NameNumber* inputFilter; NameNumber* outputFilter; Firebird::string entryPoint; Firebird::string moduleName; }; class DropFilterNode : public DdlNode { public: DropFilterNode(MemoryPool& p, const Firebird::MetaName& aName) : DdlNode(p), name(p, aName) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_drop_filter_failed) << name; } public: Firebird::MetaName name; }; class CreateShadowNode : public DdlNode { public: CreateShadowNode(MemoryPool& p, const SSHORT aNumber) : DdlNode(p), number(aNumber), manual(false), conditional(false), files(p) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_create_shadow_failed) << Firebird::Arg::Num(number); } public: SSHORT number; bool manual; bool conditional; Nullable firstLength; Firebird::Array files; }; class DropShadowNode : public DdlNode { public: DropShadowNode(MemoryPool& p, const SSHORT aNumber) : DdlNode(p), number(aNumber) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_drop_shadow_failed) << Firebird::Arg::Num(number); } public: SSHORT number; }; class CreateRoleNode : public DdlNode { public: CreateRoleNode(MemoryPool& p, const Firebird::MetaName& aName) : DdlNode(p), name(p, aName) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_create_role_failed) << name; } private: bool isItUserName(thread_db* tdbb, jrd_tra* transaction); public: Firebird::MetaName name; }; class AlterRoleNode : public DdlNode { public: AlterRoleNode(MemoryPool& p, const Firebird::MetaName& aName, bool aMap) : DdlNode(p), name(p, aName), map(aMap) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_alter_role_failed) << name; } public: Firebird::MetaName name; bool map; }; class DropRoleNode : public DdlNode { public: DropRoleNode(MemoryPool& p, const Firebird::MetaName& aName) : DdlNode(p), name(p, aName) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_drop_role_failed) << name; } public: Firebird::MetaName name; }; class CreateAlterUserNode : public DdlNode { public: CreateAlterUserNode(MemoryPool& p, bool creating, const Firebird::MetaName& aName) : DdlNode(p), isCreating(creating), name(p, aName) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isCreating ? isc_dsql_create_user_failed : isc_dsql_alter_user_failed) << name; } public: const bool isCreating; const Firebird::MetaName name; const Firebird::string* password; const Firebird::string* firstName; const Firebird::string* middleName; const Firebird::string* lastName; Nullable adminRole; }; class DropUserNode : public DdlNode { public: DropUserNode(MemoryPool& p, const Firebird::MetaName& aName) : DdlNode(p), name(p, aName) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_drop_user_failed) << name; } public: Firebird::MetaName name; }; class GrantRevokeNode : public DdlNode { public: GrantRevokeNode(MemoryPool& p, bool aIsGrant) : DdlNode(p), isGrant(aIsGrant), privileges(NULL), roles(NULL), table(NULL), users(NULL), grantAdminOption(NULL), grantor(NULL) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isGrant ? isc_dsql_grant_failed : isc_dsql_revoke_failed); } private: char modifyPrivileges(thread_db* tdbb, jrd_tra* transaction, SSHORT option, const dsql_nod* privs, const dsql_nod* user); void grantRevoke(thread_db* tdbb, jrd_tra* transaction, const dsql_nod* table, const dsql_nod* userNod, const dsql_nod* grantorNod, const char* privs, const dsql_str* fieldName, int options); static void checkGrantorCanGrant(thread_db* tdbb, jrd_tra* transaction, const char* grantor, const char* privilege, const Firebird::MetaName& relationName, const Firebird::MetaName& fieldName, bool topLevel); static void checkGrantorCanGrantRole(thread_db* tdbb, jrd_tra* transaction, const Firebird::MetaName& grantor, const Firebird::MetaName& roleName); static void storePrivilege(thread_db* tdbb, jrd_tra* transaction, const Firebird::MetaName& object, const Firebird::MetaName& user, const Firebird::MetaName& field, const TEXT* privilege, SSHORT userType, SSHORT objType, int option, const Firebird::MetaName& grantor); static void setFieldClassName(thread_db* tdbb, jrd_tra* transaction, const Firebird::MetaName& relation, const Firebird::MetaName& field); // Diagnostics print helper. static const char* privilegeName(char symbol) { switch (UPPER7(symbol)) { case 'A': return "All"; case 'I': return "Insert"; case 'U': return "Update"; case 'D': return "Delete"; case 'S': return "Select"; case 'X': return "Execute"; case 'M': return "Role"; case 'R': return "Reference"; } return ""; } public: bool isGrant; dsql_nod* privileges; dsql_nod* roles; dsql_nod* table; dsql_nod* users; dsql_nod* grantAdminOption; dsql_nod* grantor; }; class AlterDatabaseNode : public DdlNode { public: static const unsigned CLAUSE_BEGIN_BACKUP = 0x01; static const unsigned CLAUSE_END_BACKUP = 0x02; static const unsigned CLAUSE_DROP_DIFFERENCE = 0x04; public: AlterDatabaseNode(MemoryPool& p) : DdlNode(p), create(false), createLength(0), clauses(0), differenceFile(p), setDefaultCharSet(p), setDefaultCollation(p), files(p) { } public: virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch) { dsqlScratch->getStatement()->setType( create ? DsqlCompiledStatement::TYPE_CREATE_DB : DsqlCompiledStatement::TYPE_DDL); return this; } virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); protected: virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) { statusVector << Firebird::Arg::Gds(isc_dsql_alter_database_failed); } private: static void changeBackupMode(thread_db* tdbb, jrd_tra* transaction, unsigned clause); static void defineDifference(thread_db* tdbb, jrd_tra* transaction, const Firebird::PathName& file); public: bool create; // Is the node created with a CREATE DATABASE command? SLONG createLength; unsigned clauses; Firebird::PathName differenceFile; Firebird::MetaName setDefaultCharSet; Firebird::MetaName setDefaultCollation; Firebird::Array files; }; } // namespace #endif // DSQL_DDL_NODES_H