/* * 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_STMT_NODES_H #define DSQL_STMT_NODES_H #include "../common/classes/MetaName.h" #include "../jrd/blr.h" #include "../jrd/Function.h" #include "../jrd/extds/ExtDS.h" #include "../dsql/Nodes.h" #include "../dsql/DdlNodes.h" namespace Jrd { class CompoundStmtNode; class ExecBlockNode; class PlanNode; class RelationSourceNode; class SelectNode; class GeneratorItem; typedef Firebird::Pair< Firebird::NonPooled, NestConst > > ReturningClause; class ExceptionItem : public Firebird::PermanentStorage { public: enum Type { SQL_CODE = 1, GDS_CODE = 2, XCP_CODE = 3, XCP_DEFAULT = 4 }; ExceptionItem(MemoryPool& pool, const ExceptionItem& o) : PermanentStorage(pool), type(o.type), code(o.code), name(pool, o.name), secName(pool, o.secName) { } explicit ExceptionItem(MemoryPool& pool) : PermanentStorage(pool), code(0), name(pool), secName(pool) { } ExceptionItem& operator =(const ExceptionItem& o) { code = o.code; name = o.name; secName = o.secName; return *this; } Type type; SLONG code; // ASF: There are some inconsistencies in the type of 'name'. Metanames have maximum of 31 chars, // while there are system exceptions with 32 chars. The parser always expects metanames, but // I'm following the legacy code and making this a string. Firebird::string name; Firebird::MetaName secName; }; typedef Firebird::ObjectsArray ExceptionArray; struct ValidateInfo { NestConst boolean; NestConst value; }; class AssignmentNode : public TypedNode { public: explicit AssignmentNode(MemoryPool& pool) : TypedNode(pool), asgnFrom(NULL), asgnTo(NULL), missing(NULL), missing2(NULL) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual AssignmentNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual AssignmentNode* copy(thread_db* tdbb, NodeCopier& copier) const; virtual AssignmentNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual AssignmentNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; public: NestConst asgnFrom; NestConst asgnTo; NestConst missing; NestConst missing2; }; class BlockNode : public TypedNode { public: explicit BlockNode(MemoryPool& pool) : TypedNode(pool), action(NULL), handlers(NULL) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual StmtNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual BlockNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual BlockNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; private: static bool testAndFixupError(thread_db* tdbb, jrd_req* request, const ExceptionArray& conditions); public: NestConst action; NestConst handlers; }; class CommitRollbackNode : public TransactionNode { public: enum Command { CMD_COMMIT, CMD_ROLLBACK }; public: explicit CommitRollbackNode(MemoryPool& pool, Command aCommand, bool aRetain) : TransactionNode(pool), command(aCommand), retain(aRetain) { } public: virtual void print(Firebird::string& text) const { text = "CommitRollbackNode"; } virtual CommitRollbackNode* dsqlPass(DsqlCompilerScratch* dsqlScratch) { switch (command) { case CMD_COMMIT: dsqlScratch->getStatement()->setType(retain ? DsqlCompiledStatement::TYPE_COMMIT_RETAIN : DsqlCompiledStatement::TYPE_COMMIT); break; case CMD_ROLLBACK: dsqlScratch->getStatement()->setType(retain ? DsqlCompiledStatement::TYPE_ROLLBACK_RETAIN : DsqlCompiledStatement::TYPE_ROLLBACK); break; } return this; } virtual void execute(thread_db* tdbb, dsql_req* request, jrd_tra** transaction) const { if (retain) { switch (command) { case CMD_COMMIT: JRD_commit_retaining(tdbb, request->req_transaction); break; case CMD_ROLLBACK: JRD_rollback_retaining(tdbb, request->req_transaction); break; } } else { switch (command) { case CMD_COMMIT: JRD_commit_transaction(tdbb, request->req_transaction); break; case CMD_ROLLBACK: JRD_rollback_transaction(tdbb, request->req_transaction); break; } *transaction = NULL; } } private: Command command; bool retain; }; class CompoundStmtNode : public TypedNode // blr_begin { public: explicit CompoundStmtNode(MemoryPool& pool) : TypedNode(pool), statements(pool), onlyAssignments(false) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual CompoundStmtNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual CompoundStmtNode* copy(thread_db* tdbb, NodeCopier& copier) const; virtual CompoundStmtNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual CompoundStmtNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; public: Firebird::Array > statements; bool onlyAssignments; }; class ContinueLeaveNode : public TypedNode { public: explicit ContinueLeaveNode(MemoryPool& pool, UCHAR aBlrOp) : TypedNode(pool), blrOp(aBlrOp), labelNumber(0), dsqlLabelName(NULL) { fb_assert(blrOp == blr_continue_loop || blrOp == blr_leave); } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual ContinueLeaveNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual ContinueLeaveNode* pass1(thread_db* /*tdbb*/, CompilerScratch* /*csb*/) { return this; } virtual ContinueLeaveNode* pass2(thread_db* /*tdbb*/, CompilerScratch* /*csb*/) { return this; } virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; public: UCHAR blrOp; USHORT labelNumber; Firebird::MetaName* dsqlLabelName; }; class CursorStmtNode : public TypedNode { public: explicit CursorStmtNode(MemoryPool& pool, UCHAR aCursorOp, const Firebird::MetaName& aDsqlName = "", ValueListNode* aDsqlIntoStmt = NULL) : TypedNode(pool), dsqlName(pool, aDsqlName), dsqlIntoStmt(aDsqlIntoStmt), cursorOp(aCursorOp), cursorNumber(0), scrollOp(0), scrollExpr(NULL), intoStmt(NULL) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual CursorStmtNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual CursorStmtNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual CursorStmtNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; public: Firebird::MetaName dsqlName; ValueListNode* dsqlIntoStmt; UCHAR cursorOp; USHORT cursorNumber; UCHAR scrollOp; NestConst scrollExpr; NestConst intoStmt; }; class DeclareCursorNode : public TypedNode { public: static const USHORT CUR_TYPE_NONE = 0; static const USHORT CUR_TYPE_EXPLICIT = 1; static const USHORT CUR_TYPE_FOR = 2; static const USHORT CUR_TYPE_ALL = (CUR_TYPE_EXPLICIT | CUR_TYPE_FOR); explicit DeclareCursorNode(MemoryPool& pool, const Firebird::MetaName& aDsqlName = NULL, USHORT aDsqlCursorType = CUR_TYPE_NONE) : TypedNode(pool), dsqlCursorType(aDsqlCursorType), dsqlScroll(false), dsqlName(aDsqlName), dsqlSelect(NULL), rse(NULL), refs(NULL), cursorNumber(0), cursor(NULL) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual DeclareCursorNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual DeclareCursorNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual DeclareCursorNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; public: USHORT dsqlCursorType; bool dsqlScroll; Firebird::MetaName dsqlName; NestConst dsqlSelect; NestConst rse; NestConst refs; USHORT cursorNumber; NestConst cursor; }; class DeclareSubFuncNode : public TypedNode { public: explicit DeclareSubFuncNode(MemoryPool& pool, const Firebird::MetaName& aName) : TypedNode(pool), name(pool, aName), dsqlDeterministic(false), dsqlBlock(NULL), blockScratch(NULL), dsqlFunction(NULL), blrStart(NULL), blrLength(0), subCsb(NULL), routine(NULL) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual DeclareSubFuncNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual DeclareSubFuncNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual DeclareSubFuncNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; private: static void parseParameters(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, Firebird::Array >& paramArray, USHORT* defaultCount = NULL); void genParameters(DsqlCompilerScratch* dsqlScratch, Firebird::Array >& paramArray); public: Firebird::MetaName name; bool dsqlDeterministic; NestConst dsqlBlock; DsqlCompilerScratch* blockScratch; dsql_udf* dsqlFunction; const UCHAR* blrStart; ULONG blrLength; CompilerScratch* subCsb; Function* routine; }; class DeclareSubProcNode : public TypedNode { public: explicit DeclareSubProcNode(MemoryPool& pool, const Firebird::MetaName& aName) : TypedNode(pool), name(pool, aName), dsqlBlock(NULL), blockScratch(NULL), dsqlProcedure(NULL), blrStart(NULL), blrLength(0), subCsb(NULL), routine(NULL) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual DeclareSubProcNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual DeclareSubProcNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual DeclareSubProcNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; private: static void parseParameters(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, Firebird::Array >& paramArray, USHORT* defaultCount = NULL); void genParameters(DsqlCompilerScratch* dsqlScratch, Firebird::Array >& paramArray); public: Firebird::MetaName name; NestConst dsqlBlock; DsqlCompilerScratch* blockScratch; dsql_prc* dsqlProcedure; const UCHAR* blrStart; ULONG blrLength; CompilerScratch* subCsb; jrd_prc* routine; }; class DeclareVariableNode : public TypedNode { public: explicit DeclareVariableNode(MemoryPool& pool) : TypedNode(pool), dsqlDef(NULL), varId(0) { varDesc.clear(); } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual DeclareVariableNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual DeclareVariableNode* copy(thread_db* tdbb, NodeCopier& copier) const; virtual DeclareVariableNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual DeclareVariableNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; public: NestConst dsqlDef; USHORT varId; dsc varDesc; }; class EraseNode : public TypedNode { public: explicit EraseNode(MemoryPool& pool) : TypedNode(pool), dsqlRelation(NULL), dsqlBoolean(NULL), dsqlPlan(NULL), dsqlOrder(NULL), dsqlRows(NULL), dsqlCursorName(pool), dsqlReturning(NULL), dsqlRse(NULL), dsqlContext(NULL), statement(NULL), subStatement(NULL), stream(0) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual StmtNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual EraseNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual EraseNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; private: static void pass1Erase(thread_db* tdbb, CompilerScratch* csb, EraseNode* node); const StmtNode* erase(thread_db* tdbb, jrd_req* request, WhichTrigger whichTrig) const; public: NestConst dsqlRelation; NestConst dsqlBoolean; NestConst dsqlPlan; NestConst dsqlOrder; NestConst dsqlRows; Firebird::MetaName dsqlCursorName; NestConst dsqlReturning; NestConst dsqlRse; dsql_ctx* dsqlContext; NestConst statement; NestConst subStatement; StreamType stream; }; class ErrorHandlerNode : public TypedNode { public: explicit ErrorHandlerNode(MemoryPool& pool) : TypedNode(pool), action(NULL), conditions(pool) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual ErrorHandlerNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual ErrorHandlerNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual ErrorHandlerNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; public: NestConst action; ExceptionArray conditions; }; class ExecProcedureNode : public TypedNode { public: explicit ExecProcedureNode(MemoryPool& pool, const Firebird::QualifiedName& aDsqlName = Firebird::QualifiedName(), ValueListNode* aInputs = NULL, ValueListNode* aOutputs = NULL) : TypedNode(pool), dsqlName(pool, aDsqlName), dsqlProcedure(NULL), inputSources(aInputs), inputTargets(NULL), inputMessage(NULL), outputSources(aOutputs), outputTargets(NULL), outputMessage(NULL), procedure(NULL) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual ExecProcedureNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual ExecProcedureNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual ExecProcedureNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; private: ValueListNode* explodeOutputs(DsqlCompilerScratch* dsqlScratch, const dsql_prc* procedure); void executeProcedure(thread_db* tdbb, jrd_req* request) const; public: Firebird::QualifiedName dsqlName; dsql_prc* dsqlProcedure; NestConst inputSources; NestConst inputTargets; NestConst inputMessage; NestConst outputSources; NestConst outputTargets; NestConst outputMessage; NestConst procedure; }; class ExecStatementNode : public TypedNode { public: explicit ExecStatementNode(MemoryPool& pool) : TypedNode(pool), dsqlLabelName(NULL), dsqlLabelNumber(0), sql(NULL), dataSource(NULL), userName(NULL), password(NULL), role(NULL), innerStmt(NULL), inputs(NULL), outputs(NULL), useCallerPrivs(false), traScope(EDS::TraScope(0)), // not defined inputNames(NULL) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual StmtNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual ExecStatementNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual ExecStatementNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; private: static void genOptionalExpr(DsqlCompilerScratch* dsqlScratch, const UCHAR code, ValueExprNode* node); void getString(thread_db* tdbb, jrd_req* request, const ValueExprNode* node, Firebird::string& str, bool useAttCS = false) const; public: Firebird::MetaName* dsqlLabelName; USHORT dsqlLabelNumber; NestConst sql; NestConst dataSource; NestConst userName; NestConst password; NestConst role; NestConst innerStmt; NestConst inputs; NestConst outputs; bool useCallerPrivs; EDS::TraScope traScope; EDS::ParamNames* inputNames; }; class IfNode : public TypedNode { public: explicit IfNode(MemoryPool& pool) : TypedNode(pool), condition(NULL), trueAction(NULL), falseAction(NULL) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual IfNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual IfNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual IfNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; public: NestConst condition; NestConst trueAction; NestConst falseAction; }; class InAutonomousTransactionNode : public TypedNode { struct Impure { TraNumber traNumber; SLONG savNumber; }; public: explicit InAutonomousTransactionNode(MemoryPool& pool) : TypedNode(pool), action(NULL), impureOffset(0) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual InAutonomousTransactionNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual InAutonomousTransactionNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual InAutonomousTransactionNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; public: NestConst action; SLONG impureOffset; }; class InitVariableNode : public TypedNode { public: explicit InitVariableNode(MemoryPool& pool) : TypedNode(pool), varId(0), varDecl(NULL), varInfo(NULL) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual InitVariableNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual InitVariableNode* copy(thread_db* tdbb, NodeCopier& copier) const; virtual InitVariableNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual InitVariableNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; public: USHORT varId; NestConst varDecl; NestConst varInfo; }; class ExecBlockNode : public TypedNode { public: explicit ExecBlockNode(MemoryPool& pool) : TypedNode(pool), parameters(pool), returns(pool), localDeclList(NULL), body(NULL) { } virtual void print(Firebird::string& text) const; virtual ExecBlockNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); private: static void revertParametersOrder(Firebird::Array& parameters); public: Firebird::Array > parameters; Firebird::Array > returns; NestConst localDeclList; NestConst body; }; class ExceptionNode : public TypedNode { public: ExceptionNode(MemoryPool& pool, const Firebird::MetaName& name, ValueExprNode* aMessageExpr = NULL, ValueListNode* aParameters = NULL) : TypedNode(pool), messageExpr(aMessageExpr), parameters(aParameters) { exception = FB_NEW(pool) ExceptionItem(pool); exception->type = ExceptionItem::XCP_CODE; exception->name = name.c_str(); } explicit ExceptionNode(MemoryPool& pool) : TypedNode(pool), messageExpr(NULL), parameters(NULL), exception(NULL) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual StmtNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual ExceptionNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual ExceptionNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; private: void setError(thread_db* tdbb) const; public: NestConst messageExpr; NestConst parameters; NestConst exception; }; class ExitNode : public TypedNode { public: explicit ExitNode(MemoryPool& pool) : TypedNode(pool) { } public: virtual void print(Firebird::string& text) const; virtual void genBlr(DsqlCompilerScratch* dsqlScratch); }; class ForNode : public TypedNode { public: explicit ForNode(MemoryPool& pool) : TypedNode(pool), dsqlSelect(NULL), dsqlInto(NULL), dsqlCursor(NULL), dsqlLabelName(NULL), dsqlLabelNumber(0), dsqlForceSingular(false), stall(NULL), rse(NULL), statement(NULL), cursor(NULL), parBlrBeginCnt(0) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual ForNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual StmtNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual StmtNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; public: NestConst dsqlSelect; NestConst dsqlInto; DeclareCursorNode* dsqlCursor; Firebird::MetaName* dsqlLabelName; USHORT dsqlLabelNumber; bool dsqlForceSingular; NestConst stall; NestConst rse; NestConst statement; NestConst cursor; int parBlrBeginCnt; }; class HandlerNode : public TypedNode { public: explicit HandlerNode(MemoryPool& pool) : TypedNode(pool), statement(NULL) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual HandlerNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual HandlerNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual HandlerNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; public: NestConst statement; }; class LabelNode : public TypedNode { public: explicit LabelNode(MemoryPool& pool) : TypedNode(pool), statement(NULL), labelNumber(0) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual LabelNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual LabelNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual LabelNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; public: NestConst statement; USHORT labelNumber; }; class LineColumnNode : public TypedNode { public: explicit LineColumnNode(MemoryPool& pool, ULONG aLine, ULONG aColumn, StmtNode* aStatement) : TypedNode(pool), statement(aStatement) { line = aLine; column = aColumn; } public: virtual void print(Firebird::string& text) const; virtual LineColumnNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); private: NestConst statement; }; class LoopNode : public TypedNode { public: explicit LoopNode(MemoryPool& pool) : TypedNode(pool), dsqlLabelName(NULL), dsqlLabelNumber(0), dsqlExpr(NULL), statement(NULL) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual LoopNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual LoopNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual LoopNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; public: Firebird::MetaName* dsqlLabelName; USHORT dsqlLabelNumber; NestConst dsqlExpr; NestConst statement; }; class MergeNode : public TypedNode { public: struct Matched { explicit Matched(MemoryPool& pool) : assignments(NULL), condition(NULL) { } NestConst assignments; NestConst condition; }; struct NotMatched { explicit NotMatched(MemoryPool& pool) : fields(pool), values(NULL), condition(NULL) { } Firebird::Array > fields; NestConst values; NestConst condition; }; explicit MergeNode(MemoryPool& pool) : TypedNode(pool), relation(NULL), usingClause(NULL), condition(NULL), whenMatched(pool), whenNotMatched(pool), returning(NULL) { } virtual void print(Firebird::string& text) const; virtual StmtNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); public: NestConst relation; NestConst usingClause; NestConst condition; Firebird::ObjectsArray whenMatched; Firebird::ObjectsArray whenNotMatched; NestConst returning; }; class MessageNode : public TypedNode { public: explicit MessageNode(MemoryPool& pool) : TypedNode(pool), messageNumber(0), format(NULL), impureFlags(0) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); void setup(thread_db* tdbb, CompilerScratch* csb, USHORT message, USHORT count); virtual USHORT setupDesc(thread_db* tdbb, CompilerScratch* csb, USHORT index, dsc* desc, ItemInfo* itemInfo); virtual void print(Firebird::string& text) const; virtual MessageNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual MessageNode* copy(thread_db* tdbb, NodeCopier& copier) const; virtual MessageNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual MessageNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; public: USHORT messageNumber; NestConst format; ULONG impureFlags; }; class ModifyNode : public TypedNode { public: explicit ModifyNode(MemoryPool& pool) : TypedNode(pool), dsqlRelation(NULL), dsqlBoolean(NULL), dsqlPlan(NULL), dsqlOrder(NULL), dsqlRows(NULL), dsqlCursorName(pool), dsqlReturning(NULL), dsqlRseFlags(0), dsqlRse(NULL), dsqlContext(NULL), statement(NULL), statement2(NULL), subMod(NULL), validations(pool), mapView(NULL), orgStream(0), newStream(0) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; StmtNode* internalDsqlPass(DsqlCompilerScratch* dsqlScratch, bool updateOrInsert); virtual StmtNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual ModifyNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual ModifyNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; private: static void pass1Modify(thread_db* tdbb, CompilerScratch* csb, ModifyNode* node); const StmtNode* modify(thread_db* tdbb, jrd_req* request, WhichTrigger whichTrig) const; public: NestConst dsqlRelation; NestConst dsqlBoolean; NestConst dsqlPlan; NestConst dsqlOrder; NestConst dsqlRows; Firebird::MetaName dsqlCursorName; NestConst dsqlReturning; USHORT dsqlRseFlags; NestConst dsqlRse; dsql_ctx* dsqlContext; NestConst statement; NestConst statement2; NestConst subMod; Firebird::Array validations; NestConst mapView; StreamType orgStream; StreamType newStream; }; class PostEventNode : public TypedNode { public: explicit PostEventNode(MemoryPool& pool) : TypedNode(pool), event(NULL), argument(NULL) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual PostEventNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual PostEventNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual PostEventNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; public: NestConst event; NestConst argument; }; class ReceiveNode : public TypedNode { public: explicit ReceiveNode(MemoryPool& pool) : TypedNode(pool), statement(NULL), message(NULL) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual ReceiveNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual ReceiveNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual ReceiveNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; public: NestConst statement; NestConst message; }; class StoreNode : public TypedNode { public: explicit StoreNode(MemoryPool& pool) : TypedNode(pool), dsqlRelation(NULL), dsqlFields(pool), dsqlValues(NULL), dsqlReturning(NULL), dsqlRse(NULL), statement(NULL), statement2(NULL), subStore(NULL), validations(pool), relationSource(NULL) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; StmtNode* internalDsqlPass(DsqlCompilerScratch* dsqlScratch, bool updateOrInsert); virtual StmtNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual StoreNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual StoreNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; private: static bool pass1Store(thread_db* tdbb, CompilerScratch* csb, StoreNode* node); void makeDefaults(thread_db* tdbb, CompilerScratch* csb); const StmtNode* store(thread_db* tdbb, jrd_req* request, WhichTrigger whichTrig) const; public: NestConst dsqlRelation; Firebird::Array > dsqlFields; NestConst dsqlValues; NestConst dsqlReturning; NestConst dsqlRse; NestConst statement; NestConst statement2; NestConst subStore; Firebird::Array validations; NestConst relationSource; }; class UserSavepointNode : public TypedNode { public: enum Command { CMD_NOTHING = -1, CMD_SET = blr_savepoint_set, CMD_RELEASE = blr_savepoint_release, CMD_RELEASE_ONLY = blr_savepoint_release_single, CMD_ROLLBACK = blr_savepoint_undo }; public: explicit UserSavepointNode(MemoryPool& pool) : TypedNode(pool), command(CMD_NOTHING), name(pool) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual UserSavepointNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual UserSavepointNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual UserSavepointNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; public: Command command; Firebird::MetaName name; }; class SelectNode : public TypedNode { public: explicit SelectNode(MemoryPool& pool) : TypedNode(pool), dsqlExpr(NULL), dsqlForUpdate(false), dsqlWithLock(false), dsqlRse(NULL), statements(pool) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual SelectNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual SelectNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual SelectNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; public: NestConst dsqlExpr; bool dsqlForUpdate; bool dsqlWithLock; NestConst dsqlRse; Firebird::Array > statements; }; class SetGeneratorNode : public TypedNode { public: SetGeneratorNode(MemoryPool& pool, const Firebird::MetaName& name, ValueExprNode* aValue = NULL) : TypedNode(pool), generator(pool, name), value(aValue) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; // DSQL support is implemented in CreateAlterSequenceNode. virtual void genBlr(DsqlCompilerScratch* dsqlScratch) { fb_assert(false); } virtual SetGeneratorNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual SetGeneratorNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; public: GeneratorItem generator; NestConst value; }; class StallNode : public TypedNode { public: explicit StallNode(MemoryPool& pool) : TypedNode(pool) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual StallNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual StallNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual StallNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; }; class SuspendNode : public TypedNode { public: explicit SuspendNode(MemoryPool& pool) : TypedNode(pool), message(NULL), statement(NULL) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual SuspendNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual SuspendNode* pass1(thread_db* tdbb, CompilerScratch* csb); virtual SuspendNode* pass2(thread_db* tdbb, CompilerScratch* csb); virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; public: NestConst message; NestConst statement; }; class ReturnNode : public TypedNode { public: explicit ReturnNode(MemoryPool& pool, ValueExprNode* val = NULL) : TypedNode(pool), value(val) { } virtual void print(Firebird::string& text) const; virtual ReturnNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); public: NestConst value; }; class SavePointNode : public TypedNode { public: explicit SavePointNode(MemoryPool& pool, UCHAR aBlrOp) : TypedNode(pool), blrOp(aBlrOp) { fb_assert(blrOp == blr_start_savepoint || blrOp == blr_end_savepoint); } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text) const; virtual SavePointNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); virtual SavePointNode* pass1(thread_db* /*tdbb*/, CompilerScratch* /*csb*/) { return this; } virtual SavePointNode* pass2(thread_db* /*tdbb*/, CompilerScratch* /*csb*/) { return this; } virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; public: UCHAR blrOp; }; class SetTransactionNode : public TransactionNode { public: struct RestrictionOption : Firebird::PermanentStorage { RestrictionOption(MemoryPool& p, Firebird::ObjectsArray* aTables, unsigned aLockMode) : PermanentStorage(p), tables(aTables), lockMode(aLockMode) { } Firebird::ObjectsArray* tables; unsigned lockMode; }; enum { ISO_LEVEL_CONCURRENCY, ISO_LEVEL_CONSISTENCY, ISO_LEVEL_READ_COMMITTED_REC_VERSION, ISO_LEVEL_READ_COMMITTED_NO_REC_VERSION }; static const unsigned LOCK_MODE_SHARED = 0x1; static const unsigned LOCK_MODE_PROTECTED = 0x2; static const unsigned LOCK_MODE_READ = 0x4; static const unsigned LOCK_MODE_WRITE = 0x8; public: explicit SetTransactionNode(MemoryPool& pool) : TransactionNode(pool), reserveList(pool), tpb(pool) { } public: virtual void print(Firebird::string& text) const { text = "SetTransactionNode"; } virtual SetTransactionNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void execute(thread_db* tdbb, dsql_req* request, jrd_tra** transaction) const; private: void genTableLock(DsqlCompilerScratch* dsqlScratch, const RestrictionOption& tblLock, USHORT lockLevel); public: Nullable readOnly; Nullable wait; Nullable isoLevel; Nullable noAutoUndo; Nullable ignoreLimbo; Nullable restartRequests; Nullable lockTimeout; Firebird::Array reserveList; Firebird::UCharBuffer tpb; }; class UpdateOrInsertNode : public TypedNode { public: explicit UpdateOrInsertNode(MemoryPool& pool) : TypedNode(pool), relation(NULL), fields(pool), values(NULL), matching(pool), returning(NULL) { } virtual void print(Firebird::string& text) const; virtual StmtNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); public: NestConst relation; Firebird::Array > fields; NestConst values; Firebird::Array > matching; NestConst returning; }; } // namespace #endif // DSQL_STMT_NODES_H