/* * 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/common.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 RelationSourceNode; class SelectNode; typedef Firebird::Pair*> > 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) { } explicit ExceptionItem(MemoryPool& pool) : PermanentStorage(pool), type(Type(0)), code(0), name(pool) { } ExceptionItem& operator =(const ExceptionItem& o) { type = o.type; code = o.code; name = o.name; 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; }; typedef Firebird::ObjectsArray ExceptionArray; struct ValidateInfo { NestConst stmt; NestConst boolean; NestConst value; }; class AssignmentNode : public TypedNode { public: explicit AssignmentNode(MemoryPool& pool) : TypedNode(pool), dsqlAsgnFrom(NULL), dsqlAsgnTo(NULL), 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, Firebird::Array& nodes) 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: dsql_nod* dsqlAsgnFrom; dsql_nod* dsqlAsgnTo; 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, Firebird::Array& nodes) 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 TypedNode { public: enum Command { CMD_COMMIT, CMD_ROLLBACK }; public: explicit CommitRollbackNode(MemoryPool& pool, Command aCommand, bool aRetain) : TypedNode(pool), command(aCommand), retain(aRetain) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) 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 genBlr(DsqlCompilerScratch* dsqlScratch) { } 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, Firebird::Array& nodes) 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), dsqlLabel(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, Firebird::Array& nodes) 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; dsql_nod* dsqlLabel; }; class CursorStmtNode : public TypedNode { public: explicit CursorStmtNode(MemoryPool& pool, UCHAR aCursorOp, const Firebird::MetaName& aDsqlName = "", Firebird::Array* aDsqlIntoStmt = NULL) : TypedNode(pool), dsqlName(pool, aDsqlName), dsqlIntoStmt(aDsqlIntoStmt), dsqlScrollExpr(NULL), 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, Firebird::Array& nodes) 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; Firebird::Array* dsqlIntoStmt; dsql_nod* dsqlScrollExpr; 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), dsqlRse(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, Firebird::Array& nodes) 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; SelectNode* dsqlSelect; dsql_nod* dsqlRse; 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, Firebird::Array& nodes) 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, const Firebird::Array& paramArray); public: Firebird::MetaName name; bool dsqlDeterministic; ExecBlockNode* 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, Firebird::Array& nodes) 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, const Firebird::Array& paramArray); public: Firebird::MetaName name; ExecBlockNode* 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, Firebird::Array& nodes) 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), dsqlSort(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, Firebird::Array& nodes) 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: dsql_nod* dsqlRelation; dsql_nod* dsqlBoolean; dsql_nod* dsqlPlan; dsql_nod* dsqlSort; dsql_nod* dsqlRows; Firebird::MetaName dsqlCursorName; ReturningClause* dsqlReturning; dsql_nod* dsqlRse; dsql_ctx* dsqlContext; NestConst statement; NestConst subStatement; USHORT 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, Firebird::Array& nodes) 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(), dsql_nod* aDsqlInputs = NULL, Firebird::Array* aDsqlOutputs = NULL) : TypedNode(pool), dsqlName(pool, aDsqlName), dsqlInputs(aDsqlInputs), dsqlOutputs(aDsqlOutputs), dsqlProcedure(NULL), inputSources(NULL), inputTargets(NULL), inputMessage(NULL), outputSources(NULL), 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, Firebird::Array& nodes) 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: Firebird::Array* explodeOutputs(DsqlCompilerScratch* dsqlScratch, const dsql_prc* procedure); void executeProcedure(thread_db* tdbb, jrd_req* request) const; public: Firebird::QualifiedName dsqlName; dsql_nod* dsqlInputs; Firebird::Array* dsqlOutputs; 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), dsqlSql(NULL), dsqlDataSource(NULL), dsqlUserName(NULL), dsqlPassword(NULL), dsqlRole(NULL), dsqlInputs(NULL), dsqlOutputs(NULL), dsqlLabel(NULL), 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, Firebird::Array& nodes) 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, dsql_nod* node); void getString(thread_db* tdbb, jrd_req* request, const ValueExprNode* node, Firebird::string& str, bool useAttCS = false) const; public: dsql_nod* dsqlSql; dsql_nod* dsqlDataSource; dsql_nod* dsqlUserName; dsql_nod* dsqlPassword; dsql_nod* dsqlRole; dsql_nod* dsqlInputs; Firebird::Array* dsqlOutputs; dsql_nod* dsqlLabel; 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), dsqlCondition(NULL), 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, Firebird::Array& nodes) 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: dsql_nod* dsqlCondition; NestConst condition; NestConst trueAction; NestConst falseAction; }; class InAutonomousTransactionNode : public TypedNode { public: explicit InAutonomousTransactionNode(MemoryPool& pool) : TypedNode(pool), action(NULL), savNumberOffset(0) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text, Firebird::Array& nodes) 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 savNumberOffset; }; 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, Firebird::Array& nodes) 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, Firebird::Array& nodes) 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, dsql_nod* aDsqlMessageExpr = NULL, dsql_nod* aDsqlParameters = NULL) : TypedNode(pool), dsqlMessageExpr(aDsqlMessageExpr), dsqlParameters(aDsqlParameters), messageExpr(NULL), parameters(NULL) { exception = FB_NEW(pool) ExceptionItem(pool); exception->type = ExceptionItem::XCP_CODE; exception->name = name.c_str(); } explicit ExceptionNode(MemoryPool& pool) : TypedNode(pool), dsqlMessageExpr(NULL), dsqlParameters(NULL), 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, Firebird::Array& nodes) 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: dsql_nod* dsqlMessageExpr; dsql_nod* dsqlParameters; NestConst messageExpr; NestConst parameters; NestConst exception; }; class ExitNode : public TypedNode { public: explicit ExitNode(MemoryPool& pool) : TypedNode(pool) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual void genBlr(DsqlCompilerScratch* dsqlScratch); }; class ForNode : public TypedNode { public: explicit ForNode(MemoryPool& pool) : TypedNode(pool), dsqlSelect(NULL), dsqlInto(NULL), dsqlCursor(NULL), dsqlLabel(NULL), dsqlForceSingular(false), stall(NULL), rse(NULL), statement(NULL), cursor(NULL) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text, Firebird::Array& nodes) 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: SelectNode* dsqlSelect; Firebird::Array* dsqlInto; DeclareCursorNode* dsqlCursor; dsql_nod* dsqlLabel; bool dsqlForceSingular; NestConst stall; NestConst rse; NestConst statement; NestConst cursor; }; 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, Firebird::Array& nodes) 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, Firebird::Array& nodes) 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, USHORT aLine, USHORT aColumn, StmtNode* aStatement) : TypedNode(pool), statement(aStatement) { line = aLine; column = aColumn; } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) 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), dsqlLabel(NULL), dsqlExpr(NULL), statement(NULL) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text, Firebird::Array& nodes) 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: dsql_nod* dsqlLabel; dsql_nod* dsqlExpr; NestConst statement; }; class MergeNode : public TypedNode { public: struct Matched { Matched() : assignments(NULL), condition(NULL) { } CompoundStmtNode* assignments; dsql_nod* condition; }; struct NotMatched { NotMatched() : fields(NULL), values(NULL), condition(NULL) { } dsql_nod* fields; dsql_nod* values; dsql_nod* condition; }; explicit MergeNode(MemoryPool& pool) : TypedNode(pool), dsqlRelation(NULL), dsqlUsing(NULL), dsqlCondition(NULL), dsqlWhenMatched(pool), dsqlWhenNotMatched(pool), dsqlReturning(NULL) { } virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual StmtNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); public: dsql_nod* dsqlRelation; dsql_nod* dsqlUsing; dsql_nod* dsqlCondition; Firebird::Array dsqlWhenMatched; Firebird::Array dsqlWhenNotMatched; ReturningClause* dsqlReturning; }; 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); virtual void print(Firebird::string& text, Firebird::Array& nodes) 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), dsqlSort(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, Firebird::Array& nodes) 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: dsql_nod* dsqlRelation; dsql_nod* dsqlBoolean; dsql_nod* dsqlPlan; dsql_nod* dsqlSort; dsql_nod* dsqlRows; Firebird::MetaName dsqlCursorName; ReturningClause* dsqlReturning; USHORT dsqlRseFlags; dsql_nod* dsqlRse; dsql_ctx* dsqlContext; NestConst statement; NestConst statement2; NestConst subMod; Firebird::Array validations; NestConst mapView; USHORT orgStream; USHORT newStream; }; class PostEventNode : public TypedNode { public: explicit PostEventNode(MemoryPool& pool) : TypedNode(pool), dsqlEvent(NULL), dsqlArgument(NULL), event(NULL), argument(NULL) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text, Firebird::Array& nodes) 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: dsql_nod* dsqlEvent; dsql_nod* dsqlArgument; 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, Firebird::Array& nodes) 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(NULL), 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, Firebird::Array& nodes) 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: dsql_nod* dsqlRelation; dsql_nod* dsqlFields; dsql_nod* dsqlValues; ReturningClause* dsqlReturning; dsql_nod* 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, Firebird::Array& nodes) 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, Firebird::Array& nodes) 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: dsql_nod* dsqlExpr; bool dsqlForUpdate; bool dsqlWithLock; dsql_nod* dsqlRse; Firebird::Array > statements; }; class SetGeneratorNode : public TypedNode { public: SetGeneratorNode(MemoryPool& pool, const Firebird::MetaName& aName, dsql_nod* aDsqlValue = NULL) : TypedNode(pool), name(aName), dsqlValue(aDsqlValue), value(NULL), genId(0) { } public: static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual SetGeneratorNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); 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: Firebird::MetaName name; dsql_nod* dsqlValue; NestConst value; USHORT genId; }; 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, Firebird::Array& nodes) 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, Firebird::Array& nodes) 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, dsql_nod* val = NULL) : TypedNode(pool), value(val) { } virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual ReturnNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); public: dsql_nod* 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, Firebird::Array& nodes) 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 TypedNode { public: enum { ISO_LEVEL_CONCURRENCY, ISO_LEVEL_CONSISTENCY, ISO_LEVEL_READ_COMMITTED_REC_VERSION, ISO_LEVEL_READ_COMMITTED_NO_REC_VERSION }; public: explicit SetTransactionNode(MemoryPool& pool) : TypedNode(pool) { } public: virtual void print(Firebird::string& text, Firebird::Array& nodes) const { text = "SetTransactionNode"; } virtual SetTransactionNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch) { } private: void genTableLock(DsqlCompilerScratch* dsqlScratch, const dsql_nod* tblLock, USHORT lockLevel); public: Nullable readOnly; Nullable wait; Nullable isoLevel; Nullable noAutoUndo; Nullable ignoreLimbo; Nullable restartRequests; Nullable lockTimeout; Nullable reserveList; }; class UpdateOrInsertNode : public TypedNode { public: explicit UpdateOrInsertNode(MemoryPool& pool) : TypedNode(pool), dsqlRelation(NULL), dsqlFields(NULL), dsqlValues(NULL), dsqlMatching(NULL), dsqlReturning(NULL) { } virtual void print(Firebird::string& text, Firebird::Array& nodes) const; virtual StmtNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); virtual void genBlr(DsqlCompilerScratch* dsqlScratch); public: dsql_nod* dsqlRelation; dsql_nod* dsqlFields; dsql_nod* dsqlValues; dsql_nod* dsqlMatching; ReturningClause* dsqlReturning; }; } // namespace #endif // DSQL_STMT_NODES_H