mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-02-02 10:00:38 +01:00
babd741daa
* Add AUTO RELEASE TEMP BLOBID transaction option It makes the transaction release temporary ID of user BLOB just after its materialization. It's useful for massive insertions of records with user-defined BLOBs because it eliminates the memory overhead caused by creating and keeping temporary IDs until the transaction ends. This option is used during the database restore. * Place tokens in the correct sections * Avoid repeated attempts to start a transaction with options that are not supported by the target server * Correct AUTO RELEASE TEMP BLOBID description * Check bad_tpb_form error for more reliable detection of unsupported transaction options * Do not use unsupported options for transactions of parallel workers performing RestoreRelationTask
2019 lines
57 KiB
C++
2019 lines
57 KiB
C++
/*
|
|
* 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 <adrianosf@uol.com.br>
|
|
* and all contributors signed below.
|
|
*
|
|
* All Rights Reserved.
|
|
* Contributor(s): ______________________________________.
|
|
*/
|
|
|
|
#ifndef DSQL_STMT_NODES_H
|
|
#define DSQL_STMT_NODES_H
|
|
|
|
#include <optional>
|
|
#include "../jrd/MetaName.h"
|
|
#include "firebird/impl/blr.h"
|
|
#include "../jrd/Function.h"
|
|
#include "../jrd/extds/ExtDS.h"
|
|
#include "../dsql/Nodes.h"
|
|
#include "../dsql/DdlNodes.h"
|
|
#include "../dsql/NodePrinter.h"
|
|
#include "../common/DecFloat.h"
|
|
#include "../common/classes/TriState.h"
|
|
|
|
namespace Jrd {
|
|
|
|
class CompoundStmtNode;
|
|
class ExecBlockNode;
|
|
class ForNode;
|
|
class PlanNode;
|
|
class RecordBuffer;
|
|
class RelationSourceNode;
|
|
class SelectNode;
|
|
class GeneratorItem;
|
|
|
|
|
|
class ExceptionItem : public Firebird::PermanentStorage, public Printable
|
|
{
|
|
public:
|
|
enum Type : UCHAR
|
|
{
|
|
SQL_CODE = 1,
|
|
SQL_STATE = 2,
|
|
GDS_CODE = 3,
|
|
XCP_CODE = 4,
|
|
XCP_DEFAULT = 5
|
|
};
|
|
|
|
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;
|
|
}
|
|
|
|
public:
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) const
|
|
{
|
|
NODE_PRINT(printer, type);
|
|
NODE_PRINT(printer, code);
|
|
NODE_PRINT(printer, name);
|
|
NODE_PRINT(printer, secName);
|
|
|
|
return "ExceptionItem";
|
|
}
|
|
|
|
public:
|
|
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;
|
|
MetaName secName;
|
|
};
|
|
|
|
typedef Firebird::ObjectsArray<ExceptionItem> ExceptionArray;
|
|
|
|
|
|
struct ValidateInfo
|
|
{
|
|
NestConst<BoolExprNode> boolean;
|
|
NestConst<ValueExprNode> value;
|
|
};
|
|
|
|
|
|
enum OverrideClause : UCHAR
|
|
{
|
|
USER_VALUE = blr_store_override_user,
|
|
SYSTEM_VALUE = blr_store_override_system
|
|
};
|
|
|
|
|
|
class AssignmentNode final : public TypedNode<StmtNode, StmtNode::TYPE_ASSIGNMENT>
|
|
{
|
|
public:
|
|
explicit AssignmentNode(MemoryPool& pool)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_ASSIGNMENT>(pool),
|
|
asgnFrom(NULL),
|
|
asgnTo(NULL),
|
|
missing(NULL),
|
|
missing2(NULL)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
static void validateTarget(CompilerScratch* csb, const ValueExprNode* target);
|
|
static void dsqlValidateTarget(const ValueExprNode* target);
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) 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, Request* request, ExeState* exeState) const;
|
|
|
|
public:
|
|
NestConst<ValueExprNode> asgnFrom;
|
|
NestConst<ValueExprNode> asgnTo;
|
|
NestConst<ValueExprNode> missing;
|
|
NestConst<ValueExprNode> missing2;
|
|
};
|
|
|
|
|
|
class BlockNode final : public TypedNode<StmtNode, StmtNode::TYPE_BLOCK>
|
|
{
|
|
public:
|
|
explicit BlockNode(MemoryPool& pool)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_BLOCK>(pool),
|
|
action(NULL),
|
|
handlers(NULL)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) 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, Request* request, ExeState* exeState) const;
|
|
|
|
private:
|
|
static bool testAndFixupError(thread_db* tdbb, Request* request, const ExceptionArray& conditions);
|
|
|
|
public:
|
|
NestConst<StmtNode> action;
|
|
NestConst<CompoundStmtNode> handlers;
|
|
};
|
|
|
|
|
|
class CompoundStmtNode : public TypedNode<StmtNode, StmtNode::TYPE_COMPOUND_STMT> // blr_begin
|
|
{
|
|
public:
|
|
explicit CompoundStmtNode(MemoryPool& pool)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_COMPOUND_STMT>(pool),
|
|
statements(pool),
|
|
onlyAssignments(false)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
virtual bool isProfileAware() const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) 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, Request* request, ExeState* exeState) const;
|
|
|
|
public:
|
|
Firebird::Array<NestConst<StmtNode> > statements;
|
|
bool onlyAssignments;
|
|
};
|
|
|
|
|
|
class ContinueLeaveNode final : public TypedNode<StmtNode, StmtNode::TYPE_CONTINUE_LEAVE>
|
|
{
|
|
public:
|
|
explicit ContinueLeaveNode(MemoryPool& pool, UCHAR aBlrOp)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_CONTINUE_LEAVE>(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, const UCHAR blrOp);
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) 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, Request* request, ExeState* exeState) const;
|
|
|
|
public:
|
|
UCHAR blrOp;
|
|
USHORT labelNumber;
|
|
MetaName* dsqlLabelName;
|
|
};
|
|
|
|
|
|
class CursorStmtNode final : public TypedNode<StmtNode, StmtNode::TYPE_CURSOR_STMT>
|
|
{
|
|
public:
|
|
explicit CursorStmtNode(MemoryPool& pool, UCHAR aCursorOp, const MetaName& aDsqlName = "",
|
|
ValueListNode* aDsqlIntoStmt = NULL)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_CURSOR_STMT>(pool),
|
|
dsqlName(pool, aDsqlName),
|
|
dsqlIntoStmt(aDsqlIntoStmt),
|
|
scrollExpr(NULL),
|
|
intoStmt(NULL),
|
|
cursorNumber(0),
|
|
cursorOp(aCursorOp),
|
|
scrollOp(0)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) 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, Request* request, ExeState* exeState) const;
|
|
|
|
public:
|
|
MetaName dsqlName;
|
|
ValueListNode* dsqlIntoStmt;
|
|
NestConst<ValueExprNode> scrollExpr;
|
|
NestConst<StmtNode> intoStmt;
|
|
USHORT cursorNumber;
|
|
UCHAR cursorOp;
|
|
UCHAR scrollOp;
|
|
};
|
|
|
|
|
|
class DeclareCursorNode final : public TypedNode<StmtNode, StmtNode::TYPE_DECLARE_CURSOR>
|
|
{
|
|
public:
|
|
static constexpr USHORT CUR_TYPE_NONE = 0;
|
|
static constexpr USHORT CUR_TYPE_EXPLICIT = 1;
|
|
static constexpr USHORT CUR_TYPE_FOR = 2;
|
|
static constexpr USHORT CUR_TYPE_ALL = CUR_TYPE_EXPLICIT | CUR_TYPE_FOR;
|
|
|
|
explicit DeclareCursorNode(MemoryPool& pool, const MetaName& aDsqlName = NULL,
|
|
USHORT aDsqlCursorType = CUR_TYPE_NONE)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_DECLARE_CURSOR>(pool),
|
|
dsqlName(aDsqlName),
|
|
dsqlSelect(NULL),
|
|
rse(NULL),
|
|
refs(NULL),
|
|
cursor(NULL),
|
|
dsqlCursorType(aDsqlCursorType),
|
|
cursorNumber(0),
|
|
dsqlScroll(false)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) 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, Request* request, ExeState* exeState) const;
|
|
|
|
public:
|
|
MetaName dsqlName;
|
|
NestConst<SelectNode> dsqlSelect;
|
|
NestConst<RseNode> rse;
|
|
NestConst<ValueListNode> refs;
|
|
NestConst<Cursor> cursor;
|
|
USHORT dsqlCursorType;
|
|
USHORT cursorNumber;
|
|
bool dsqlScroll;
|
|
};
|
|
|
|
|
|
class DeclareLocalTableNode final : public TypedNode<StmtNode, StmtNode::TYPE_DECLARE_LOCAL_TABLE>
|
|
{
|
|
public:
|
|
struct Impure
|
|
{
|
|
RecordBuffer* recordBuffer;
|
|
};
|
|
|
|
public:
|
|
explicit DeclareLocalTableNode(MemoryPool& pool)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_DECLARE_LOCAL_TABLE>(pool)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
Firebird::string internalPrint(NodePrinter& printer) const override;
|
|
DeclareLocalTableNode* dsqlPass(DsqlCompilerScratch* dsqlScratch) override;
|
|
void genBlr(DsqlCompilerScratch* dsqlScratch) override;
|
|
DeclareLocalTableNode* copy(thread_db* tdbb, NodeCopier& copier) const override;
|
|
|
|
DeclareLocalTableNode* pass1(thread_db* tdbb, CompilerScratch* csb) override
|
|
{
|
|
return this;
|
|
}
|
|
|
|
DeclareLocalTableNode* pass2(thread_db* tdbb, CompilerScratch* csb) override;
|
|
const StmtNode* execute(thread_db* tdbb, Request* request, ExeState* exeState) const override;
|
|
|
|
public:
|
|
Impure* getImpure(thread_db* tdbb, Request* request, bool createWhenDead = true) const;
|
|
|
|
public:
|
|
NestConst<Format> format;
|
|
USHORT tableNumber = 0;
|
|
};
|
|
|
|
|
|
class DeclareSubFuncNode final : public TypedNode<StmtNode, StmtNode::TYPE_DECLARE_SUBFUNC>
|
|
{
|
|
public:
|
|
explicit DeclareSubFuncNode(MemoryPool& pool, const MetaName& aName)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_DECLARE_SUBFUNC>(pool),
|
|
name(pool, aName),
|
|
dsqlSignature(pool, aName)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
virtual bool isProfileAware() const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) const;
|
|
virtual DeclareSubFuncNode* dsqlPass(DsqlCompilerScratch* dsqlScratch);
|
|
virtual void genBlr(DsqlCompilerScratch* dsqlScratch);
|
|
|
|
virtual DeclareSubFuncNode* pass1(thread_db* tdbb, CompilerScratch* csb)
|
|
{
|
|
return this;
|
|
}
|
|
|
|
virtual DeclareSubFuncNode* pass2(thread_db* tdbb, CompilerScratch* csb)
|
|
{
|
|
return this;
|
|
}
|
|
|
|
virtual const StmtNode* execute(thread_db* tdbb, Request* request, ExeState* exeState) const;
|
|
|
|
public:
|
|
bool isForwardDecl() const;
|
|
|
|
private:
|
|
static void parseParameters(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb,
|
|
Firebird::Array<NestConst<Parameter> >& paramArray, USHORT* defaultCount = NULL);
|
|
|
|
void genParameters(DsqlCompilerScratch* dsqlScratch,
|
|
Firebird::Array<NestConst<ParameterClause> >& paramArray);
|
|
|
|
public:
|
|
MetaName name;
|
|
Signature dsqlSignature;
|
|
NestConst<ExecBlockNode> dsqlBlock;
|
|
DsqlCompilerScratch* blockScratch = nullptr;
|
|
dsql_udf* dsqlFunction = nullptr;
|
|
const UCHAR* blrStart = nullptr;
|
|
CompilerScratch* subCsb = nullptr;
|
|
Function* routine = nullptr;
|
|
ULONG blrLength = 0;
|
|
bool dsqlDeterministic = false;
|
|
};
|
|
|
|
|
|
class DeclareSubProcNode final : public TypedNode<StmtNode, StmtNode::TYPE_DECLARE_SUBPROC>
|
|
{
|
|
public:
|
|
explicit DeclareSubProcNode(MemoryPool& pool, const MetaName& aName)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_DECLARE_SUBPROC>(pool),
|
|
name(pool, aName),
|
|
dsqlSignature(pool, aName)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
virtual bool isProfileAware() const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) const;
|
|
virtual DeclareSubProcNode* dsqlPass(DsqlCompilerScratch* dsqlScratch);
|
|
virtual void genBlr(DsqlCompilerScratch* dsqlScratch);
|
|
|
|
virtual DeclareSubProcNode* pass1(thread_db* tdbb, CompilerScratch* csb)
|
|
{
|
|
return this;
|
|
}
|
|
|
|
virtual DeclareSubProcNode* pass2(thread_db* tdbb, CompilerScratch* csb)
|
|
{
|
|
return this;
|
|
}
|
|
|
|
virtual const StmtNode* execute(thread_db* tdbb, Request* request, ExeState* exeState) const;
|
|
|
|
public:
|
|
bool isForwardDecl() const;
|
|
|
|
private:
|
|
static void parseParameters(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb,
|
|
Firebird::Array<NestConst<Parameter> >& paramArray, USHORT* defaultCount = NULL);
|
|
|
|
void genParameters(DsqlCompilerScratch* dsqlScratch,
|
|
Firebird::Array<NestConst<ParameterClause> >& paramArray);
|
|
|
|
public:
|
|
MetaName name;
|
|
Signature dsqlSignature;
|
|
NestConst<ExecBlockNode> dsqlBlock;
|
|
DsqlCompilerScratch* blockScratch = nullptr;
|
|
dsql_prc* dsqlProcedure = nullptr;
|
|
const UCHAR* blrStart = nullptr;
|
|
CompilerScratch* subCsb = nullptr;
|
|
jrd_prc* routine = nullptr;
|
|
ULONG blrLength = 0;
|
|
};
|
|
|
|
|
|
class DeclareVariableNode final : public TypedNode<StmtNode, StmtNode::TYPE_DECLARE_VARIABLE>
|
|
{
|
|
public:
|
|
explicit DeclareVariableNode(MemoryPool& pool)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_DECLARE_VARIABLE>(pool)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) 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, Request* request, ExeState* exeState) const;
|
|
|
|
public:
|
|
NestConst<ParameterClause> dsqlDef;
|
|
dsc varDesc;
|
|
USHORT varId = 0;
|
|
bool usedInSubRoutines = false;
|
|
};
|
|
|
|
|
|
class EraseNode final : public TypedNode<StmtNode, StmtNode::TYPE_ERASE>
|
|
{
|
|
public:
|
|
explicit EraseNode(MemoryPool& pool)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_ERASE>(pool),
|
|
dsqlCursorName(pool)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) 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, Request* request, ExeState* exeState) const;
|
|
|
|
private:
|
|
static void pass1Erase(thread_db* tdbb, CompilerScratch* csb, EraseNode* node);
|
|
const StmtNode* erase(thread_db* tdbb, Request* request, WhichTrigger whichTrig) const;
|
|
|
|
public:
|
|
NestConst<RelationSourceNode> dsqlRelation;
|
|
NestConst<BoolExprNode> dsqlBoolean;
|
|
NestConst<PlanNode> dsqlPlan;
|
|
NestConst<ValueListNode> dsqlOrder;
|
|
NestConst<RowsClause> dsqlRows;
|
|
MetaName dsqlCursorName;
|
|
NestConst<ReturningClause> dsqlReturning;
|
|
NestConst<RseNode> dsqlRse;
|
|
bool dsqlSkipLocked = false;
|
|
dsql_ctx* dsqlContext = nullptr;
|
|
NestConst<StmtNode> statement;
|
|
NestConst<StmtNode> subStatement;
|
|
NestConst<StmtNode> returningStatement;
|
|
NestConst<ForNode> forNode; // parent implicit cursor, if present
|
|
StreamType stream = 0;
|
|
unsigned marks = 0; // see StmtNode::IUD_MARK_xxx
|
|
};
|
|
|
|
|
|
class ErrorHandlerNode final : public TypedNode<StmtNode, StmtNode::TYPE_ERROR_HANDLER>
|
|
{
|
|
public:
|
|
explicit ErrorHandlerNode(MemoryPool& pool)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_ERROR_HANDLER>(pool),
|
|
action(NULL),
|
|
conditions(pool)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) 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, Request* request, ExeState* exeState) const;
|
|
|
|
public:
|
|
NestConst<StmtNode> action;
|
|
ExceptionArray conditions;
|
|
};
|
|
|
|
|
|
class ExecProcedureNode final : public TypedNode<StmtNode, StmtNode::TYPE_EXEC_PROCEDURE>
|
|
{
|
|
public:
|
|
explicit ExecProcedureNode(MemoryPool& pool,
|
|
const QualifiedName& aDsqlName = QualifiedName(),
|
|
ValueListNode* aInputs = nullptr, ValueListNode* aOutputs = nullptr,
|
|
Firebird::ObjectsArray<MetaName>* aDsqlInputArgNames = nullptr)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_EXEC_PROCEDURE>(pool),
|
|
dsqlName(pool, aDsqlName),
|
|
inputSources(aInputs),
|
|
outputTargets(aOutputs),
|
|
dsqlInputArgNames(aDsqlInputArgNames)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
public:
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) 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, Request* request, ExeState* exeState) const;
|
|
|
|
private:
|
|
ValueListNode* explodeOutputs(DsqlCompilerScratch* dsqlScratch, const dsql_prc* procedure);
|
|
void executeProcedure(thread_db* tdbb, Request* request) const;
|
|
|
|
public:
|
|
QualifiedName dsqlName;
|
|
dsql_prc* dsqlProcedure = nullptr;
|
|
NestConst<ValueListNode> inputSources;
|
|
NestConst<ValueListNode> inputTargets;
|
|
NestConst<MessageNode> inputMessage;
|
|
NestConst<ValueListNode> outputSources;
|
|
NestConst<ValueListNode> outputTargets;
|
|
NestConst<MessageNode> outputMessage;
|
|
NestConst<jrd_prc> procedure;
|
|
NestConst<Firebird::ObjectsArray<MetaName>> dsqlInputArgNames;
|
|
NestConst<Firebird::ObjectsArray<MetaName>> dsqlOutputArgNames;
|
|
bool dsqlCallSyntax = false;
|
|
};
|
|
|
|
|
|
class ExecStatementNode final : public TypedNode<StmtNode, StmtNode::TYPE_EXEC_STATEMENT>
|
|
{
|
|
public:
|
|
explicit ExecStatementNode(MemoryPool& pool)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_EXEC_STATEMENT>(pool),
|
|
dsqlLabelName(NULL),
|
|
sql(NULL),
|
|
dataSource(NULL),
|
|
userName(NULL),
|
|
password(NULL),
|
|
role(NULL),
|
|
innerStmt(NULL),
|
|
inputs(NULL),
|
|
outputs(NULL),
|
|
inputNames(NULL),
|
|
excessInputs(NULL),
|
|
dsqlLabelNumber(0),
|
|
useCallerPrivs(false),
|
|
traScope(EDS::traNotSet) // not defined
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) 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, Request* request, ExeState* exeState) const;
|
|
|
|
private:
|
|
static void genOptionalExpr(DsqlCompilerScratch* dsqlScratch, const UCHAR code, ValueExprNode* node);
|
|
|
|
void getString(thread_db* tdbb, Request* request, const ValueExprNode* node,
|
|
Firebird::string& str, bool useAttCS = false) const;
|
|
|
|
public:
|
|
MetaName* dsqlLabelName;
|
|
NestConst<ValueExprNode> sql;
|
|
NestConst<ValueExprNode> dataSource;
|
|
NestConst<ValueExprNode> userName;
|
|
NestConst<ValueExprNode> password;
|
|
NestConst<ValueExprNode> role;
|
|
NestConst<StmtNode> innerStmt;
|
|
NestConst<ValueListNode> inputs;
|
|
NestConst<ValueListNode> outputs;
|
|
EDS::ParamNames* inputNames;
|
|
EDS::ParamNumbers* excessInputs;
|
|
USHORT dsqlLabelNumber;
|
|
bool useCallerPrivs;
|
|
EDS::TraScope traScope;
|
|
};
|
|
|
|
|
|
class IfNode final : public TypedNode<StmtNode, StmtNode::TYPE_IF>
|
|
{
|
|
public:
|
|
explicit IfNode(MemoryPool& pool)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_IF>(pool),
|
|
condition(NULL),
|
|
trueAction(NULL),
|
|
falseAction(NULL)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) 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, Request* request, ExeState* exeState) const;
|
|
|
|
public:
|
|
NestConst<BoolExprNode> condition;
|
|
NestConst<StmtNode> trueAction;
|
|
NestConst<StmtNode> falseAction;
|
|
};
|
|
|
|
|
|
class InAutonomousTransactionNode final : public TypedNode<StmtNode, StmtNode::TYPE_IN_AUTO_TRANS>
|
|
{
|
|
struct Impure
|
|
{
|
|
TraNumber traNumber;
|
|
SavNumber savNumber;
|
|
};
|
|
|
|
public:
|
|
explicit InAutonomousTransactionNode(MemoryPool& pool)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_IN_AUTO_TRANS>(pool),
|
|
action(NULL)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) 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, Request* request, ExeState* exeState) const;
|
|
|
|
public:
|
|
NestConst<StmtNode> action;
|
|
};
|
|
|
|
|
|
class InitVariableNode final : public TypedNode<StmtNode, StmtNode::TYPE_INIT_VARIABLE>
|
|
{
|
|
public:
|
|
explicit InitVariableNode(MemoryPool& pool)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_INIT_VARIABLE>(pool),
|
|
varId(0),
|
|
varDecl(NULL),
|
|
varInfo(NULL)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) 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, Request* request, ExeState* exeState) const;
|
|
|
|
public:
|
|
USHORT varId;
|
|
NestConst<DeclareVariableNode> varDecl;
|
|
NestConst<ItemInfo> varInfo;
|
|
};
|
|
|
|
|
|
class ExecBlockNode final : public TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_EXEC_BLOCK>
|
|
{
|
|
public:
|
|
explicit ExecBlockNode(MemoryPool& pool)
|
|
: TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_EXEC_BLOCK>(pool),
|
|
parameters(pool),
|
|
returns(pool)
|
|
{
|
|
}
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) const;
|
|
virtual ExecBlockNode* dsqlPass(DsqlCompilerScratch* dsqlScratch);
|
|
virtual void genBlr(DsqlCompilerScratch* dsqlScratch);
|
|
|
|
private:
|
|
static void revertParametersOrder(Firebird::Array<dsql_par*>& parameters);
|
|
|
|
public:
|
|
Firebird::Array<NestConst<ParameterClause>> parameters;
|
|
Firebird::Array<NestConst<ParameterClause>> returns;
|
|
NestConst<LocalDeclarationsNode> localDeclList;
|
|
NestConst<StmtNode> body;
|
|
};
|
|
|
|
|
|
class ExceptionNode final : public TypedNode<StmtNode, StmtNode::TYPE_EXCEPTION>
|
|
{
|
|
public:
|
|
ExceptionNode(MemoryPool& pool, const MetaName& name,
|
|
ValueExprNode* aMessageExpr = NULL, ValueListNode* aParameters = NULL)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_EXCEPTION>(pool),
|
|
messageExpr(aMessageExpr),
|
|
parameters(aParameters)
|
|
{
|
|
exception = FB_NEW_POOL(pool) ExceptionItem(pool);
|
|
exception->type = ExceptionItem::XCP_CODE;
|
|
exception->name = name.c_str();
|
|
}
|
|
|
|
explicit ExceptionNode(MemoryPool& pool)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_EXCEPTION>(pool),
|
|
messageExpr(NULL),
|
|
parameters(NULL),
|
|
exception(NULL)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) 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, Request* request, ExeState* exeState) const;
|
|
|
|
private:
|
|
void setError(thread_db* tdbb) const;
|
|
|
|
public:
|
|
NestConst<ValueExprNode> messageExpr;
|
|
NestConst<ValueListNode> parameters;
|
|
NestConst<ExceptionItem> exception;
|
|
};
|
|
|
|
|
|
class ExitNode final : public TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_EXIT>
|
|
{
|
|
public:
|
|
explicit ExitNode(MemoryPool& pool)
|
|
: TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_EXIT>(pool)
|
|
{
|
|
}
|
|
|
|
public:
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) const;
|
|
virtual void genBlr(DsqlCompilerScratch* dsqlScratch);
|
|
};
|
|
|
|
|
|
class ForNode final : public TypedNode<StmtNode, StmtNode::TYPE_FOR>
|
|
{
|
|
public:
|
|
explicit ForNode(MemoryPool& pool)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_FOR>(pool),
|
|
dsqlSelect(NULL),
|
|
dsqlInto(NULL),
|
|
dsqlCursor(NULL),
|
|
dsqlLabelName(NULL),
|
|
stall(NULL),
|
|
rse(NULL),
|
|
statement(NULL),
|
|
cursor(NULL),
|
|
parBlrBeginCnt(0),
|
|
marks(0),
|
|
dsqlLabelNumber(0),
|
|
dsqlForceSingular(false),
|
|
withLock(false)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) 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, Request* request, ExeState* exeState) const;
|
|
|
|
bool isWriteLockMode(Request* request) const;
|
|
void setWriteLockMode(Request* request) const;
|
|
|
|
// Used by UPDATE and DELETE sub-statements of MERGE
|
|
void checkRecordUpdated(thread_db* tdbb, Request* request, record_param* rpb) const;
|
|
void setRecordUpdated(thread_db* tdbb, Request* request, record_param* rpb) const;
|
|
|
|
public:
|
|
struct Impure
|
|
{
|
|
SavNumber savepoint;
|
|
bool writeLockMode; // true - driven statement (UPDATE\DELETE\SELECT WITH LOCK) works in "write lock" mode, false - normal mode
|
|
};
|
|
|
|
struct ImpureMerge : Impure
|
|
{
|
|
RecordBitmap* recUpdated; // updated and deleted records by MERGE statement
|
|
};
|
|
|
|
NestConst<SelectNode> dsqlSelect;
|
|
NestConst<ValueListNode> dsqlInto;
|
|
DeclareCursorNode* dsqlCursor;
|
|
MetaName* dsqlLabelName;
|
|
NestConst<StmtNode> stall;
|
|
NestConst<RseNode> rse;
|
|
NestConst<StmtNode> statement;
|
|
NestConst<Cursor> cursor;
|
|
int parBlrBeginCnt;
|
|
unsigned marks;
|
|
USHORT dsqlLabelNumber;
|
|
bool dsqlForceSingular;
|
|
bool withLock; // part of SELECT ... WITH LOCK statement
|
|
};
|
|
|
|
|
|
class HandlerNode final : public TypedNode<StmtNode, StmtNode::TYPE_HANDLER>
|
|
{
|
|
public:
|
|
explicit HandlerNode(MemoryPool& pool)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_HANDLER>(pool),
|
|
statement(NULL)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) 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, Request* request, ExeState* exeState) const;
|
|
|
|
public:
|
|
NestConst<StmtNode> statement;
|
|
};
|
|
|
|
|
|
class LabelNode final : public TypedNode<StmtNode, StmtNode::TYPE_LABEL>
|
|
{
|
|
public:
|
|
explicit LabelNode(MemoryPool& pool)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_LABEL>(pool),
|
|
statement(NULL),
|
|
labelNumber(0)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) 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, Request* request, ExeState* exeState) const;
|
|
|
|
public:
|
|
NestConst<StmtNode> statement;
|
|
USHORT labelNumber;
|
|
};
|
|
|
|
|
|
class LineColumnNode final : public TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_LINE_COLUMN>
|
|
{
|
|
public:
|
|
explicit LineColumnNode(MemoryPool& pool, ULONG aLine, ULONG aColumn, StmtNode* aStatement)
|
|
: TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_LINE_COLUMN>(pool),
|
|
statement(aStatement)
|
|
{
|
|
line = aLine;
|
|
column = aColumn;
|
|
}
|
|
|
|
public:
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) const;
|
|
virtual LineColumnNode* dsqlPass(DsqlCompilerScratch* dsqlScratch);
|
|
virtual void genBlr(DsqlCompilerScratch* dsqlScratch);
|
|
|
|
private:
|
|
NestConst<StmtNode> statement;
|
|
};
|
|
|
|
|
|
class LocalDeclarationsNode final : public TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_LOCAL_DECLARATIONS>
|
|
{
|
|
public:
|
|
explicit LocalDeclarationsNode(MemoryPool& pool)
|
|
: TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_LOCAL_DECLARATIONS>(pool),
|
|
statements(pool)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static void checkUniqueFieldsNames(const LocalDeclarationsNode* node,
|
|
const Firebird::Array<NestConst<ParameterClause>>* inputParameters,
|
|
const Firebird::Array<NestConst<ParameterClause>>* outputParameters);
|
|
|
|
public:
|
|
void genBlr(DsqlCompilerScratch* dsqlScratch) override;
|
|
|
|
public:
|
|
Firebird::Array<NestConst<StmtNode>> statements;
|
|
};
|
|
|
|
|
|
class LoopNode final : public TypedNode<StmtNode, StmtNode::TYPE_LOOP>
|
|
{
|
|
public:
|
|
explicit LoopNode(MemoryPool& pool)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_LOOP>(pool),
|
|
dsqlLabelName(NULL),
|
|
dsqlExpr(NULL),
|
|
statement(NULL),
|
|
dsqlLabelNumber(0)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) 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, Request* request, ExeState* exeState) const;
|
|
|
|
public:
|
|
MetaName* dsqlLabelName;
|
|
NestConst<BoolExprNode> dsqlExpr;
|
|
NestConst<StmtNode> statement;
|
|
USHORT dsqlLabelNumber;
|
|
};
|
|
|
|
|
|
class MergeNode final : public TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_MERGE>
|
|
{
|
|
public:
|
|
struct Matched
|
|
{
|
|
explicit Matched(MemoryPool& pool)
|
|
: processedFields(pool),
|
|
processedValues(pool)
|
|
{
|
|
}
|
|
|
|
NestConst<CompoundStmtNode> assignments;
|
|
NestConst<BoolExprNode> condition;
|
|
|
|
NestConst<Jrd::RecordSourceNode> modifyRelation;
|
|
NestValueArray processedFields;
|
|
NestValueArray processedValues;
|
|
NestConst<ReturningClause> processedReturning;
|
|
};
|
|
|
|
struct NotMatched
|
|
{
|
|
explicit NotMatched(MemoryPool& pool)
|
|
: fields(pool),
|
|
processedFields(pool)
|
|
{
|
|
}
|
|
|
|
Firebird::Array<NestConst<FieldNode>> fields;
|
|
NestConst<ValueListNode> values;
|
|
NestConst<BoolExprNode> condition;
|
|
std::optional<OverrideClause> overrideClause;
|
|
|
|
NestConst<Jrd::RecordSourceNode> storeRelation;
|
|
NestValueArray processedFields;
|
|
NestConst<ReturningClause> processedReturning;
|
|
};
|
|
|
|
explicit MergeNode(MemoryPool& pool)
|
|
: TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_MERGE>(pool),
|
|
whenMatched(pool),
|
|
whenNotMatchedByTarget(pool),
|
|
whenNotMatchedBySource(pool),
|
|
usingContexts(pool)
|
|
{
|
|
}
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) const;
|
|
virtual StmtNode* dsqlPass(DsqlCompilerScratch* dsqlScratch);
|
|
virtual void genBlr(DsqlCompilerScratch* dsqlScratch);
|
|
|
|
public:
|
|
NestConst<RelationSourceNode> relation;
|
|
NestConst<RecordSourceNode> usingClause;
|
|
NestConst<BoolExprNode> condition;
|
|
Firebird::ObjectsArray<Matched> whenMatched;
|
|
Firebird::ObjectsArray<NotMatched> whenNotMatchedByTarget;
|
|
Firebird::ObjectsArray<Matched> whenNotMatchedBySource;
|
|
NestConst<PlanNode> plan;
|
|
NestConst<ValueListNode> order;
|
|
NestConst<ReturningClause> returning;
|
|
|
|
NestConst<RseNode> rse;
|
|
dsql_ctx* oldContext = nullptr;
|
|
Firebird::SortedArray<USHORT> usingContexts;
|
|
};
|
|
|
|
|
|
class MessageNode : public TypedNode<StmtNode, StmtNode::TYPE_MESSAGE>
|
|
{
|
|
public:
|
|
explicit MessageNode(MemoryPool& pool)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_MESSAGE>(pool),
|
|
itemsUsedInSubroutines(pool)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const 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 Firebird::string internalPrint(NodePrinter& printer) 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, Request* request, ExeState* exeState) const;
|
|
|
|
public:
|
|
Firebird::SortedArray<USHORT> itemsUsedInSubroutines;
|
|
NestConst<Format> format;
|
|
ULONG impureFlags = 0;
|
|
USHORT messageNumber = 0;
|
|
};
|
|
|
|
|
|
class ModifyNode final : public TypedNode<StmtNode, StmtNode::TYPE_MODIFY>
|
|
{
|
|
public:
|
|
explicit ModifyNode(MemoryPool& pool)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_MODIFY>(pool),
|
|
dsqlCursorName(pool),
|
|
validations(pool)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) 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, Request* request, ExeState* exeState) const;
|
|
|
|
private:
|
|
static void pass1Modify(thread_db* tdbb, CompilerScratch* csb, ModifyNode* node);
|
|
const StmtNode* modify(thread_db* tdbb, Request* request, WhichTrigger whichTrig) const;
|
|
|
|
public:
|
|
NestConst<RecordSourceNode> dsqlRelation;
|
|
NestConst<BoolExprNode> dsqlBoolean;
|
|
NestConst<PlanNode> dsqlPlan;
|
|
NestConst<ValueListNode> dsqlOrder;
|
|
NestConst<RowsClause> dsqlRows;
|
|
MetaName dsqlCursorName;
|
|
NestConst<ReturningClause> dsqlReturning;
|
|
NestConst<RecordSourceNode> dsqlRse;
|
|
dsql_ctx* dsqlContext = nullptr;
|
|
bool dsqlSkipLocked = false;
|
|
NestConst<StmtNode> statement;
|
|
NestConst<StmtNode> statement2;
|
|
NestConst<StmtNode> subMod;
|
|
Firebird::Array<ValidateInfo> validations;
|
|
NestConst<StmtNode> mapView;
|
|
NestConst<ForNode> forNode; // parent implicit cursor, if present
|
|
StreamType orgStream = 0;
|
|
StreamType newStream = 0;
|
|
unsigned marks = 0; // see StmtNode::IUD_MARK_xxx
|
|
USHORT dsqlRseFlags = 0;
|
|
std::optional<USHORT> dsqlReturningLocalTableNumber;
|
|
};
|
|
|
|
|
|
class OuterMapNode final : public TypedNode<StmtNode, StmtNode::TYPE_OUTER_MAP>
|
|
{
|
|
public:
|
|
explicit OuterMapNode(MemoryPool& pool)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_OUTER_MAP>(pool)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
Firebird::string internalPrint(NodePrinter& /*printer*/) const override
|
|
{
|
|
return "OuterMapNode";
|
|
}
|
|
|
|
void genBlr(DsqlCompilerScratch* /*dsqlScratch*/) override
|
|
{
|
|
}
|
|
|
|
OuterMapNode* pass1(thread_db* /*tdbb*/, CompilerScratch* /*csb*/) override;
|
|
|
|
OuterMapNode* pass2(thread_db* /*tdbb*/, CompilerScratch* /*csb*/) override
|
|
{
|
|
return this;
|
|
}
|
|
|
|
const StmtNode* execute(thread_db* tdbb, Request* request, ExeState* exeState) const override;
|
|
};
|
|
|
|
|
|
class PostEventNode final : public TypedNode<StmtNode, StmtNode::TYPE_POST_EVENT>
|
|
{
|
|
public:
|
|
explicit PostEventNode(MemoryPool& pool)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_POST_EVENT>(pool),
|
|
event(NULL),
|
|
argument(NULL)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) 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, Request* request, ExeState* exeState) const;
|
|
|
|
public:
|
|
NestConst<ValueExprNode> event;
|
|
NestConst<ValueExprNode> argument;
|
|
};
|
|
|
|
|
|
class ReceiveNode final : public TypedNode<StmtNode, StmtNode::TYPE_RECEIVE>
|
|
{
|
|
public:
|
|
explicit ReceiveNode(MemoryPool& pool)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_RECEIVE>(pool),
|
|
statement(NULL),
|
|
message(NULL),
|
|
batchFlag(false)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) 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, Request* request, ExeState* exeState) const;
|
|
|
|
public:
|
|
NestConst<StmtNode> statement;
|
|
NestConst<MessageNode> message;
|
|
bool batchFlag;
|
|
};
|
|
|
|
|
|
class StoreNode final : public TypedNode<StmtNode, StmtNode::TYPE_STORE>
|
|
{
|
|
public:
|
|
explicit StoreNode(MemoryPool& pool)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_STORE>(pool),
|
|
dsqlFields(pool),
|
|
validations(pool),
|
|
marks(0)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) const;
|
|
StmtNode* internalDsqlPass(DsqlCompilerScratch* dsqlScratch, bool updateOrInsert, bool& needSavePoint);
|
|
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, Request* 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, Request* request, WhichTrigger whichTrig) const;
|
|
|
|
public:
|
|
NestConst<RecordSourceNode> target;
|
|
Firebird::Array<NestConst<FieldNode>> dsqlFields;
|
|
NestConst<ValueListNode> dsqlValues;
|
|
NestConst<ReturningClause> dsqlReturning;
|
|
NestConst<RecordSourceNode> dsqlRse;
|
|
NestConst<StmtNode> statement;
|
|
NestConst<StmtNode> statement2;
|
|
NestConst<StmtNode> subStore;
|
|
Firebird::Array<ValidateInfo> validations;
|
|
unsigned marks;
|
|
std::optional<USHORT> dsqlReturningLocalTableNumber;
|
|
std::optional<OverrideClause> overrideClause;
|
|
};
|
|
|
|
|
|
class SelectNode final : public TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_SELECT>
|
|
{
|
|
public:
|
|
explicit SelectNode(MemoryPool& pool)
|
|
: TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_SELECT>(pool)
|
|
{
|
|
}
|
|
|
|
public:
|
|
RseNode* dsqlProcess(DsqlCompilerScratch* dsqlScratch);
|
|
|
|
Firebird::string internalPrint(NodePrinter& printer) const override;
|
|
SelectNode* dsqlPass(DsqlCompilerScratch* dsqlScratch) override;
|
|
void genBlr(DsqlCompilerScratch* dsqlScratch) override;
|
|
|
|
public:
|
|
NestConst<SelectExprNode> selectExpr;
|
|
NestConst<RseNode> rse;
|
|
Firebird::TriState optimizeForFirstRows;
|
|
bool forUpdate = false;
|
|
bool withLock = false;
|
|
bool skipLocked = false;
|
|
};
|
|
|
|
|
|
class SelectMessageNode final : public TypedNode<StmtNode, StmtNode::TYPE_SELECT_MESSAGE>
|
|
{
|
|
public:
|
|
explicit SelectMessageNode(MemoryPool& pool)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_SELECT_MESSAGE>(pool),
|
|
statements(pool)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
Firebird::string internalPrint(NodePrinter& printer) const override;
|
|
|
|
SelectMessageNode* dsqlPass(DsqlCompilerScratch* dsqlScratch) override
|
|
{
|
|
fb_assert(false);
|
|
return nullptr;
|
|
}
|
|
|
|
void genBlr(DsqlCompilerScratch* dsqlScratch) override
|
|
{
|
|
fb_assert(false);
|
|
}
|
|
|
|
SelectMessageNode* pass1(thread_db* tdbb, CompilerScratch* csb) override;
|
|
SelectMessageNode* pass2(thread_db* tdbb, CompilerScratch* csb) override;
|
|
const StmtNode* execute(thread_db* tdbb, Request* request, ExeState* exeState) const override;
|
|
|
|
public:
|
|
Firebird::Array<NestConst<StmtNode>> statements;
|
|
};
|
|
|
|
|
|
// This is only for GPRE's cmp_set_generator().
|
|
class SetGeneratorNode final : public TypedNode<StmtNode, StmtNode::TYPE_SET_GENERATOR>
|
|
{
|
|
public:
|
|
SetGeneratorNode(MemoryPool& pool, const MetaName& name, ValueExprNode* aValue = NULL)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_SET_GENERATOR>(pool),
|
|
generator(pool, name), value(aValue)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) 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, Request* request, ExeState* exeState) const;
|
|
|
|
public:
|
|
GeneratorItem generator;
|
|
NestConst<ValueExprNode> value;
|
|
};
|
|
|
|
|
|
class StallNode final : public TypedNode<StmtNode, StmtNode::TYPE_STALL>
|
|
{
|
|
public:
|
|
explicit StallNode(MemoryPool& pool)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_STALL>(pool)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) 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, Request* request, ExeState* exeState) const;
|
|
};
|
|
|
|
|
|
class SuspendNode : public TypedNode<StmtNode, StmtNode::TYPE_SUSPEND>
|
|
{
|
|
public:
|
|
explicit SuspendNode(MemoryPool& pool)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_SUSPEND>(pool),
|
|
message(NULL),
|
|
statement(NULL)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) 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, Request* request, ExeState* exeState) const;
|
|
|
|
public:
|
|
NestConst<MessageNode> message;
|
|
NestConst<StmtNode> statement;
|
|
};
|
|
|
|
|
|
class ReturnNode final : public TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_RETURN>
|
|
{
|
|
public:
|
|
explicit ReturnNode(MemoryPool& pool, ValueExprNode* val = NULL)
|
|
: TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_RETURN>(pool),
|
|
value(val)
|
|
{
|
|
}
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) const;
|
|
virtual ReturnNode* dsqlPass(DsqlCompilerScratch* dsqlScratch);
|
|
virtual void genBlr(DsqlCompilerScratch* dsqlScratch);
|
|
|
|
public:
|
|
NestConst<ValueExprNode> value;
|
|
};
|
|
|
|
|
|
class SavepointEncloseNode final : public TypedNode<StmtNode, StmtNode::TYPE_SAVEPOINT>
|
|
{
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
static StmtNode* make(MemoryPool& pool, DsqlCompilerScratch* dsqlScratch, StmtNode* node, bool force = false);
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) const;
|
|
virtual SavepointEncloseNode* dsqlPass(DsqlCompilerScratch* dsqlScratch);
|
|
virtual void genBlr(DsqlCompilerScratch* dsqlScratch);
|
|
|
|
virtual SavepointEncloseNode* pass1(thread_db* tdbb, CompilerScratch* csb);
|
|
virtual SavepointEncloseNode* pass2(thread_db* tdbb, CompilerScratch* csb);
|
|
|
|
virtual const StmtNode* execute(thread_db* tdbb, Request* request, ExeState* exeState) const;
|
|
|
|
private:
|
|
explicit SavepointEncloseNode(MemoryPool& pool, StmtNode* stmt)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_SAVEPOINT>(pool),
|
|
statement(stmt)
|
|
{
|
|
}
|
|
|
|
NestConst<StmtNode> statement;
|
|
};
|
|
|
|
|
|
class SessionManagementWrapperNode final : public TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_SESSION_MANAGEMENT_WRAPPER>
|
|
{
|
|
public:
|
|
explicit SessionManagementWrapperNode(MemoryPool& pool, SessionManagementNode* aWrapped,
|
|
const Firebird::string& aText)
|
|
: TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_SESSION_MANAGEMENT_WRAPPER>(pool),
|
|
wrapped(aWrapped),
|
|
text(pool, aText)
|
|
{
|
|
}
|
|
|
|
public:
|
|
virtual SessionManagementWrapperNode* dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
|
{
|
|
Node::dsqlPass(dsqlScratch);
|
|
|
|
// Save and reset the statement type, as SessionManagementNode sets it to TYPE_SESSION_MANAGEMENT but
|
|
// we are a DML statement.
|
|
DsqlStatement::Type statementType = dsqlScratch->getDsqlStatement()->getType();
|
|
wrapped->dsqlPass(dsqlScratch);
|
|
dsqlScratch->getDsqlStatement()->setType(statementType);
|
|
|
|
return this;
|
|
}
|
|
|
|
public:
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) const
|
|
{
|
|
DsqlOnlyStmtNode::internalPrint(printer);
|
|
|
|
NODE_PRINT(printer, wrapped);
|
|
NODE_PRINT(printer, text);
|
|
|
|
return "SessionManagementWrapperNode";
|
|
}
|
|
|
|
virtual void genBlr(DsqlCompilerScratch* dsqlScratch)
|
|
{
|
|
dsqlScratch->appendUChar(blr_exec_sql);
|
|
dsqlScratch->appendUChar(blr_literal);
|
|
dsqlScratch->appendUChar(blr_text2);
|
|
dsqlScratch->appendUShort(CS_METADATA);
|
|
dsqlScratch->appendUShort((USHORT) text.length());
|
|
dsqlScratch->appendBytes((const UCHAR*) text.c_str(), text.length());
|
|
}
|
|
|
|
public:
|
|
SessionManagementNode* wrapped;
|
|
const Firebird::string text;
|
|
};
|
|
|
|
|
|
class SetTransactionNode : public TransactionNode
|
|
{
|
|
public:
|
|
struct RestrictionOption : Firebird::PermanentStorage
|
|
{
|
|
RestrictionOption(MemoryPool& p, Firebird::ObjectsArray<MetaName>* aTables,
|
|
unsigned aLockMode)
|
|
: PermanentStorage(p),
|
|
tables(aTables),
|
|
lockMode(aLockMode)
|
|
{
|
|
}
|
|
|
|
Firebird::ObjectsArray<MetaName>* tables;
|
|
unsigned lockMode;
|
|
};
|
|
|
|
enum
|
|
{
|
|
ISO_LEVEL_CONCURRENCY,
|
|
ISO_LEVEL_CONSISTENCY,
|
|
ISO_LEVEL_READ_COMMITTED_REC_VERSION,
|
|
ISO_LEVEL_READ_COMMITTED_NO_REC_VERSION,
|
|
ISO_LEVEL_READ_COMMITTED_READ_CONSISTENCY
|
|
};
|
|
|
|
static constexpr unsigned LOCK_MODE_SHARED = 0x1;
|
|
static constexpr unsigned LOCK_MODE_PROTECTED = 0x2;
|
|
static constexpr unsigned LOCK_MODE_READ = 0x4;
|
|
static constexpr unsigned LOCK_MODE_WRITE = 0x8;
|
|
|
|
public:
|
|
explicit SetTransactionNode(MemoryPool& pool)
|
|
: TransactionNode(pool),
|
|
reserveList(pool),
|
|
tpb(pool)
|
|
{
|
|
}
|
|
|
|
public:
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) const
|
|
{
|
|
TransactionNode::internalPrint(printer);
|
|
|
|
NODE_PRINT(printer, readOnly);
|
|
NODE_PRINT(printer, wait);
|
|
NODE_PRINT(printer, isoLevel);
|
|
NODE_PRINT(printer, noAutoUndo);
|
|
NODE_PRINT(printer, ignoreLimbo);
|
|
NODE_PRINT(printer, restartRequests);
|
|
NODE_PRINT(printer, autoCommit);
|
|
NODE_PRINT(printer, autoReleaseTempBlobID);
|
|
NODE_PRINT(printer, lockTimeout);
|
|
//// FIXME-PRINT: NODE_PRINT(printer, reserveList);
|
|
NODE_PRINT(printer, tpb);
|
|
|
|
return "SetTransactionNode";
|
|
}
|
|
|
|
virtual SetTransactionNode* dsqlPass(DsqlCompilerScratch* dsqlScratch);
|
|
virtual void execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** transaction) const;
|
|
|
|
private:
|
|
void genTableLock(DsqlCompilerScratch* dsqlScratch, const RestrictionOption& tblLock,
|
|
USHORT lockLevel);
|
|
|
|
public:
|
|
Firebird::Array<RestrictionOption*> reserveList;
|
|
Firebird::UCharBuffer tpb;
|
|
std::optional<CommitNumber> atSnapshotNumber;
|
|
std::optional<unsigned> isoLevel;
|
|
std::optional<USHORT> lockTimeout;
|
|
Firebird::TriState readOnly;
|
|
Firebird::TriState wait;
|
|
Firebird::TriState noAutoUndo;
|
|
Firebird::TriState ignoreLimbo;
|
|
Firebird::TriState restartRequests;
|
|
Firebird::TriState autoCommit;
|
|
Firebird::TriState autoReleaseTempBlobID;
|
|
};
|
|
|
|
|
|
class CommitRollbackNode : public TransactionNode
|
|
{
|
|
public:
|
|
enum Command : UCHAR
|
|
{
|
|
CMD_COMMIT,
|
|
CMD_ROLLBACK
|
|
};
|
|
|
|
public:
|
|
explicit CommitRollbackNode(MemoryPool& pool, Command aCommand, bool aRetain)
|
|
: TransactionNode(pool),
|
|
command(aCommand),
|
|
retain(aRetain)
|
|
{
|
|
}
|
|
|
|
public:
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) const;
|
|
virtual CommitRollbackNode* dsqlPass(DsqlCompilerScratch* dsqlScratch);
|
|
virtual void execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** transaction) const;
|
|
|
|
private:
|
|
const Command command;
|
|
const bool retain;
|
|
};
|
|
|
|
|
|
class UserSavepointNode : public TransactionNode
|
|
{
|
|
public:
|
|
enum Command : UCHAR
|
|
{
|
|
CMD_SET,
|
|
CMD_RELEASE,
|
|
CMD_RELEASE_ONLY,
|
|
CMD_ROLLBACK
|
|
};
|
|
|
|
public:
|
|
explicit UserSavepointNode(MemoryPool& pool, Command aCommand, const MetaName& aName)
|
|
: TransactionNode(pool),
|
|
command(aCommand),
|
|
name(pool, aName)
|
|
{
|
|
}
|
|
|
|
public:
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) const;
|
|
virtual UserSavepointNode* dsqlPass(DsqlCompilerScratch* dsqlScratch);
|
|
virtual void execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** transaction) const;
|
|
|
|
public:
|
|
const Command command;
|
|
const MetaName name;
|
|
};
|
|
|
|
|
|
class SessionResetNode : public SessionManagementNode
|
|
{
|
|
public:
|
|
explicit SessionResetNode(MemoryPool& pool)
|
|
: SessionManagementNode(pool)
|
|
{
|
|
}
|
|
|
|
public:
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) const
|
|
{
|
|
SessionManagementNode::internalPrint(printer);
|
|
|
|
return "SessionResetNode";
|
|
}
|
|
|
|
virtual void execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** traHandle) const;
|
|
};
|
|
|
|
|
|
class SetRoleNode : public SessionManagementNode
|
|
{
|
|
public:
|
|
explicit SetRoleNode(MemoryPool& pool)
|
|
: SessionManagementNode(pool),
|
|
trusted(true),
|
|
roleName(pool)
|
|
{
|
|
}
|
|
|
|
SetRoleNode(MemoryPool& pool, MetaName* name)
|
|
: SessionManagementNode(pool),
|
|
trusted(false),
|
|
roleName(pool, *name)
|
|
{
|
|
}
|
|
|
|
public:
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) const
|
|
{
|
|
SessionManagementNode::internalPrint(printer);
|
|
|
|
NODE_PRINT(printer, trusted);
|
|
NODE_PRINT(printer, roleName);
|
|
|
|
return "SetRoleNode";
|
|
}
|
|
|
|
virtual void execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** traHandle) const;
|
|
|
|
public:
|
|
bool trusted;
|
|
MetaName roleName;
|
|
};
|
|
|
|
|
|
class SetSessionNode : public SessionManagementNode
|
|
{
|
|
public:
|
|
enum Type : UCHAR
|
|
{
|
|
TYPE_IDLE_TIMEOUT,
|
|
TYPE_STMT_TIMEOUT
|
|
};
|
|
|
|
SetSessionNode(MemoryPool& pool, Type aType, ULONG aVal, UCHAR blr_timepart);
|
|
|
|
public:
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) const;
|
|
virtual void execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** traHandle) const;
|
|
|
|
private:
|
|
Type m_type;
|
|
ULONG m_value;
|
|
};
|
|
|
|
|
|
class SetDebugOptionNode : public SessionManagementNode
|
|
{
|
|
public:
|
|
SetDebugOptionNode(MemoryPool& pool, MetaName* aName, ExprNode* aValue);
|
|
|
|
public:
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) const
|
|
{
|
|
SessionManagementNode::internalPrint(printer);
|
|
|
|
NODE_PRINT(printer, name);
|
|
NODE_PRINT(printer, value);
|
|
|
|
return "SetDebugOptionNode";
|
|
}
|
|
|
|
virtual void execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** traHandle) const;
|
|
|
|
private:
|
|
MetaName name;
|
|
ExprNode* value;
|
|
};
|
|
|
|
|
|
class SetDecFloatRoundNode : public SessionManagementNode
|
|
{
|
|
public:
|
|
SetDecFloatRoundNode(MemoryPool& pool, MetaName* name);
|
|
|
|
public:
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) const
|
|
{
|
|
SessionManagementNode::internalPrint(printer);
|
|
|
|
NODE_PRINT(printer, rndMode);
|
|
|
|
return "SetDecFloatRoundNode";
|
|
}
|
|
|
|
virtual void execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** traHandle) const;
|
|
|
|
public:
|
|
USHORT rndMode;
|
|
};
|
|
|
|
|
|
class SetDecFloatTrapsNode : public SessionManagementNode
|
|
{
|
|
public:
|
|
SetDecFloatTrapsNode(MemoryPool& pool)
|
|
: SessionManagementNode(pool),
|
|
traps(0u)
|
|
{
|
|
}
|
|
|
|
public:
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) const
|
|
{
|
|
SessionManagementNode::internalPrint(printer);
|
|
|
|
NODE_PRINT(printer, traps);
|
|
|
|
return "SetDecFloatTrapsNode";
|
|
}
|
|
|
|
virtual void execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** traHandle) const;
|
|
|
|
void trap(MetaName* name);
|
|
|
|
public:
|
|
USHORT traps;
|
|
};
|
|
|
|
|
|
class SetBindNode : public SessionManagementNode
|
|
{
|
|
public:
|
|
SetBindNode(MemoryPool& pool)
|
|
: SessionManagementNode(pool),
|
|
from(nullptr),
|
|
to(nullptr)
|
|
{
|
|
}
|
|
|
|
public:
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) const
|
|
{
|
|
SessionManagementNode::internalPrint(printer);
|
|
|
|
NODE_PRINT(printer, from);
|
|
NODE_PRINT(printer, to);
|
|
|
|
return "SetBindNode";
|
|
}
|
|
|
|
virtual SessionManagementNode* dsqlPass(DsqlCompilerScratch* dsqlScratch);
|
|
virtual void execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** traHandle) const;
|
|
|
|
public:
|
|
dsql_fld* from;
|
|
dsql_fld* to;
|
|
};
|
|
|
|
|
|
class SetOptimizeNode : public SessionManagementNode
|
|
{
|
|
public:
|
|
explicit SetOptimizeNode(MemoryPool& pool)
|
|
: SessionManagementNode(pool)
|
|
{
|
|
}
|
|
|
|
SetOptimizeNode(MemoryPool& pool, bool mode)
|
|
: SessionManagementNode(pool),
|
|
optimizeMode(mode)
|
|
{
|
|
}
|
|
|
|
public:
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) const
|
|
{
|
|
SessionManagementNode::internalPrint(printer);
|
|
|
|
NODE_PRINT(printer, optimizeMode);
|
|
|
|
return "SetOptimizeNode";
|
|
}
|
|
|
|
virtual void execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** traHandle) const;
|
|
|
|
public:
|
|
Firebird::TriState optimizeMode;
|
|
};
|
|
|
|
|
|
class SetTimeZoneNode : public SessionManagementNode
|
|
{
|
|
public:
|
|
explicit SetTimeZoneNode(MemoryPool& pool, const Firebird::string& aStr)
|
|
: SessionManagementNode(pool),
|
|
str(pool, aStr),
|
|
local(false)
|
|
{
|
|
}
|
|
|
|
explicit SetTimeZoneNode(MemoryPool& pool)
|
|
: SessionManagementNode(pool),
|
|
str(pool),
|
|
local(true)
|
|
{
|
|
}
|
|
|
|
public:
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) const
|
|
{
|
|
SessionManagementNode::internalPrint(printer);
|
|
|
|
NODE_PRINT(printer, str);
|
|
NODE_PRINT(printer, local);
|
|
|
|
return "SetTimeZoneNode";
|
|
}
|
|
|
|
virtual void execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** traHandle) const;
|
|
|
|
public:
|
|
Firebird::string str;
|
|
bool local;
|
|
};
|
|
|
|
|
|
class TruncateLocalTableNode final : public TypedNode<StmtNode, StmtNode::TYPE_TRUNCATE_LOCAL_TABLE>
|
|
{
|
|
public:
|
|
explicit TruncateLocalTableNode(MemoryPool& pool)
|
|
: TypedNode<StmtNode, StmtNode::TYPE_TRUNCATE_LOCAL_TABLE>(pool)
|
|
{
|
|
}
|
|
|
|
public:
|
|
static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp);
|
|
|
|
Firebird::string internalPrint(NodePrinter& printer) const override;
|
|
|
|
TruncateLocalTableNode* dsqlPass(DsqlCompilerScratch* dsqlScratch) override
|
|
{
|
|
return this;
|
|
}
|
|
|
|
void genBlr(DsqlCompilerScratch* dsqlScratch) override;
|
|
TruncateLocalTableNode* copy(thread_db* tdbb, NodeCopier& copier) const override;
|
|
|
|
TruncateLocalTableNode* pass1(thread_db* tdbb, CompilerScratch* csb) override
|
|
{
|
|
return this;
|
|
}
|
|
|
|
TruncateLocalTableNode* pass2(thread_db* tdbb, CompilerScratch* csb) override
|
|
{
|
|
return this;
|
|
}
|
|
|
|
const StmtNode* execute(thread_db* tdbb, Request* request, ExeState* exeState) const override;
|
|
|
|
public:
|
|
USHORT tableNumber = 0;
|
|
};
|
|
|
|
|
|
class UpdateOrInsertNode final : public TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_UPDATE_OR_INSERT>
|
|
{
|
|
public:
|
|
explicit UpdateOrInsertNode(MemoryPool& pool)
|
|
: TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_UPDATE_OR_INSERT>(pool),
|
|
fields(pool),
|
|
matching(pool),
|
|
varAssignments(pool)
|
|
{
|
|
}
|
|
|
|
virtual Firebird::string internalPrint(NodePrinter& printer) const;
|
|
virtual StmtNode* dsqlPass(DsqlCompilerScratch* dsqlScratch);
|
|
virtual void genBlr(DsqlCompilerScratch* dsqlScratch);
|
|
|
|
public:
|
|
NestConst<RelationSourceNode> relation;
|
|
Firebird::Array<NestConst<FieldNode>> fields;
|
|
NestConst<ValueListNode> values;
|
|
Firebird::Array<NestConst<FieldNode>> matching;
|
|
NestConst<PlanNode> plan;
|
|
NestConst<ValueListNode> order;
|
|
NestConst<RowsClause> rows;
|
|
NestConst<ReturningClause> returning;
|
|
std::optional<OverrideClause> overrideClause;
|
|
NestConst<StoreNode> storeNode;
|
|
NestConst<ModifyNode> modifyNode;
|
|
Firebird::Array<NestConst<AssignmentNode>> varAssignments;
|
|
};
|
|
|
|
|
|
} // namespace
|
|
|
|
#endif // DSQL_STMT_NODES_H
|