mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 12:43:03 +01:00
1) Make a new kind of Node (TransactionNode).
2) Make main parser statement return requests instead of nodes. 3) Some related cleanup (ddlData, ddlScratch). 4) Added dsqlPass to dsql_req and children, to get rid of ugly logic in prepareStatement.
This commit is contained in:
parent
1198014fcf
commit
8f46d9300e
@ -46,17 +46,19 @@ class VariableNode;
|
||||
class DsqlCompilerScratch : public BlrWriter
|
||||
{
|
||||
public:
|
||||
static const unsigned FLAG_IN_AUTO_TRANS_BLOCK = 0x001;
|
||||
static const unsigned FLAG_RETURNING_INTO = 0x002;
|
||||
static const unsigned FLAG_METADATA_SAVED = 0x004;
|
||||
static const unsigned FLAG_PROCEDURE = 0x008;
|
||||
static const unsigned FLAG_TRIGGER = 0x010;
|
||||
static const unsigned FLAG_BLOCK = 0x020;
|
||||
static const unsigned FLAG_RECURSIVE_CTE = 0x040;
|
||||
static const unsigned FLAG_UPDATE_OR_INSERT = 0x080;
|
||||
static const unsigned FLAG_MERGE = 0x100;
|
||||
static const unsigned FLAG_FUNCTION = 0x200;
|
||||
static const unsigned FLAG_SUB_ROUTINE = 0x400;
|
||||
static const unsigned FLAG_IN_AUTO_TRANS_BLOCK = 0x0001;
|
||||
static const unsigned FLAG_RETURNING_INTO = 0x0002;
|
||||
static const unsigned FLAG_METADATA_SAVED = 0x0004;
|
||||
static const unsigned FLAG_PROCEDURE = 0x0008;
|
||||
static const unsigned FLAG_TRIGGER = 0x0010;
|
||||
static const unsigned FLAG_BLOCK = 0x0020;
|
||||
static const unsigned FLAG_RECURSIVE_CTE = 0x0040;
|
||||
static const unsigned FLAG_UPDATE_OR_INSERT = 0x0080;
|
||||
static const unsigned FLAG_MERGE = 0x0100;
|
||||
static const unsigned FLAG_FUNCTION = 0x0200;
|
||||
static const unsigned FLAG_SUB_ROUTINE = 0x0400;
|
||||
static const unsigned FLAG_INTERNAL_REQUEST = 0x0800;
|
||||
static const unsigned FLAG_AMBIGUOUS_STMT = 0x1000;
|
||||
|
||||
public:
|
||||
DsqlCompilerScratch(MemoryPool& p, dsql_dbb* aDbb, jrd_tra* aTransaction,
|
||||
|
@ -225,6 +225,25 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class TransactionNode : public Node
|
||||
{
|
||||
public:
|
||||
explicit TransactionNode(MemoryPool& pool)
|
||||
: Node(pool)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual TransactionNode* dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
||||
{
|
||||
Node::dsqlPass(dsqlScratch);
|
||||
return this;
|
||||
}
|
||||
|
||||
virtual void execute(thread_db* tdbb, dsql_req* request, jrd_tra** transaction) const = 0;
|
||||
};
|
||||
|
||||
|
||||
class DmlNode : public Node
|
||||
{
|
||||
public:
|
||||
@ -239,7 +258,7 @@ public:
|
||||
|
||||
explicit DmlNode(MemoryPool& pool, Kind aKind)
|
||||
: Node(pool),
|
||||
kind(aKind)
|
||||
kind(aKind)
|
||||
{
|
||||
}
|
||||
|
||||
@ -851,7 +870,6 @@ public:
|
||||
{
|
||||
TYPE_ASSIGNMENT,
|
||||
TYPE_BLOCK,
|
||||
TYPE_COMMIT_ROLLBACK,
|
||||
TYPE_COMPOUND_STMT,
|
||||
TYPE_CONTINUE_LEAVE,
|
||||
TYPE_CURSOR_STMT,
|
||||
@ -885,7 +903,6 @@ public:
|
||||
TYPE_SAVEPOINT_ENCLOSE,
|
||||
TYPE_SELECT,
|
||||
TYPE_SET_GENERATOR,
|
||||
TYPE_SET_TRANSACTION,
|
||||
TYPE_STALL,
|
||||
TYPE_STORE,
|
||||
TYPE_SUSPEND,
|
||||
|
@ -91,10 +91,13 @@ Parser::~Parser()
|
||||
}
|
||||
|
||||
|
||||
Node* Parser::parse()
|
||||
dsql_req* Parser::parse()
|
||||
{
|
||||
if (parseAux() != 0)
|
||||
{
|
||||
fb_assert(false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
transformString(lex.start, lex.end - lex.start, transformedString);
|
||||
|
||||
|
@ -128,7 +128,7 @@ public:
|
||||
~Parser();
|
||||
|
||||
public:
|
||||
Node* parse();
|
||||
dsql_req* parse();
|
||||
|
||||
const Firebird::string& getTransformedString() const
|
||||
{
|
||||
@ -283,7 +283,7 @@ private:
|
||||
Firebird::string transformedString;
|
||||
Firebird::GenericMap<Firebird::NonPooled<dsql_str*, StrMark> > strMarks;
|
||||
bool stmt_ambiguous;
|
||||
Node* DSQL_parse;
|
||||
dsql_req* DSQL_parse;
|
||||
|
||||
// These value/posn are taken from the lexer
|
||||
YYSTYPE yylval;
|
||||
|
@ -6776,42 +6776,8 @@ DmlNode* UserSavepointNode::parse(thread_db* /*tdbb*/, MemoryPool& pool, Compile
|
||||
|
||||
UserSavepointNode* UserSavepointNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
||||
{
|
||||
DsqlCompiledStatement* statement = dsqlScratch->getStatement();
|
||||
|
||||
// ASF: It should never enter in this IF, because the grammar does not allow it.
|
||||
if (dsqlScratch->flags & DsqlCompilerScratch::FLAG_BLOCK) // blocks, procedures and triggers
|
||||
{
|
||||
const char* cmd = NULL;
|
||||
|
||||
switch (command)
|
||||
{
|
||||
//case CMD_NOTHING:
|
||||
case CMD_SET:
|
||||
cmd = "SAVEPOINT";
|
||||
break;
|
||||
case CMD_RELEASE:
|
||||
cmd = "RELEASE";
|
||||
break;
|
||||
case CMD_RELEASE_ONLY:
|
||||
cmd = "RELEASE ONLY";
|
||||
break;
|
||||
case CMD_ROLLBACK:
|
||||
cmd = "ROLLBACK";
|
||||
break;
|
||||
default:
|
||||
cmd = "UNKNOWN";
|
||||
fb_assert(false);
|
||||
}
|
||||
|
||||
ERRD_post(
|
||||
Arg::Gds(isc_sqlerr) << Arg::Num(-104) <<
|
||||
// Token unknown
|
||||
Arg::Gds(isc_token_err) <<
|
||||
Arg::Gds(isc_random) << Arg::Str(cmd));
|
||||
}
|
||||
|
||||
statement->setType(DsqlCompiledStatement::TYPE_SAVEPOINT);
|
||||
|
||||
fb_assert(!(dsqlScratch->flags & DsqlCompilerScratch::FLAG_BLOCK));
|
||||
dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_SAVEPOINT);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -7616,14 +7582,18 @@ SetTransactionNode* SetTransactionNode::dsqlPass(DsqlCompilerScratch* dsqlScratc
|
||||
}
|
||||
|
||||
if (dsqlScratch->getBlrData().getCount() > 1) // 1 -> isc_tpb_version1
|
||||
{
|
||||
// Store DYN data in the statement.
|
||||
dsqlScratch->getStatement()->setDdlData(dsqlScratch->getBlrData());
|
||||
}
|
||||
tpb.add(dsqlScratch->getBlrData().begin(), dsqlScratch->getBlrData().getCount());
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
void SetTransactionNode::execute(thread_db* tdbb, dsql_req* request, jrd_tra** transaction) const
|
||||
{
|
||||
JRD_start_transaction(tdbb, &request->req_transaction, request->req_dbb->dbb_attachment,
|
||||
tpb.getCount(), tpb.begin());
|
||||
*transaction = request->req_transaction;
|
||||
}
|
||||
|
||||
// Generate tpb for table lock.
|
||||
// If lock level is specified, it overrrides the transaction lock level.
|
||||
void SetTransactionNode::genTableLock(DsqlCompilerScratch* dsqlScratch, const dsql_nod* tblLock,
|
||||
|
@ -159,7 +159,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class CommitRollbackNode : public TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_COMMIT_ROLLBACK>
|
||||
class CommitRollbackNode : public TransactionNode
|
||||
{
|
||||
public:
|
||||
enum Command
|
||||
@ -170,7 +170,7 @@ public:
|
||||
|
||||
public:
|
||||
explicit CommitRollbackNode(MemoryPool& pool, Command aCommand, bool aRetain)
|
||||
: TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_COMMIT_ROLLBACK>(pool),
|
||||
: TransactionNode(pool),
|
||||
command(aCommand),
|
||||
retain(aRetain)
|
||||
{
|
||||
@ -200,8 +200,36 @@ public:
|
||||
return this;
|
||||
}
|
||||
|
||||
virtual void genBlr(DsqlCompilerScratch* dsqlScratch)
|
||||
virtual void execute(thread_db* tdbb, dsql_req* request, jrd_tra** transaction) const
|
||||
{
|
||||
if (retain)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case CMD_COMMIT:
|
||||
JRD_commit_retaining(tdbb, request->req_transaction);
|
||||
break;
|
||||
|
||||
case CMD_ROLLBACK:
|
||||
JRD_rollback_retaining(tdbb, request->req_transaction);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case CMD_COMMIT:
|
||||
JRD_commit_transaction(tdbb, request->req_transaction);
|
||||
break;
|
||||
|
||||
case CMD_ROLLBACK:
|
||||
JRD_rollback_transaction(tdbb, request->req_transaction);
|
||||
break;
|
||||
}
|
||||
|
||||
*transaction = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
@ -1432,7 +1460,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class SetTransactionNode : public TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_SET_TRANSACTION>
|
||||
class SetTransactionNode : public TransactionNode
|
||||
{
|
||||
public:
|
||||
enum
|
||||
@ -1445,7 +1473,8 @@ public:
|
||||
|
||||
public:
|
||||
explicit SetTransactionNode(MemoryPool& pool)
|
||||
: TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_SET_TRANSACTION>(pool)
|
||||
: TransactionNode(pool),
|
||||
tpb(pool)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1457,9 +1486,7 @@ public:
|
||||
|
||||
virtual SetTransactionNode* dsqlPass(DsqlCompilerScratch* dsqlScratch);
|
||||
|
||||
virtual void genBlr(DsqlCompilerScratch* dsqlScratch)
|
||||
{
|
||||
}
|
||||
virtual void execute(thread_db* tdbb, dsql_req* request, jrd_tra** transaction) const;
|
||||
|
||||
private:
|
||||
void genTableLock(DsqlCompilerScratch* dsqlScratch, const dsql_nod* tblLock, USHORT lockLevel);
|
||||
@ -1473,6 +1500,7 @@ public:
|
||||
Nullable<bool> restartRequests;
|
||||
Nullable<USHORT> lockTimeout;
|
||||
Nullable<dsql_nod*> reserveList;
|
||||
Firebird::UCharBuffer tpb;
|
||||
};
|
||||
|
||||
|
||||
|
@ -115,57 +115,6 @@ namespace
|
||||
isc_info_req_update_count, isc_info_req_delete_count,
|
||||
isc_info_req_select_count, isc_info_req_insert_count
|
||||
};
|
||||
|
||||
class DsqlDmlRequest : public dsql_req
|
||||
{
|
||||
public:
|
||||
explicit DsqlDmlRequest(DsqlCompilerScratch* scratch)
|
||||
: dsql_req(scratch)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void execute(thread_db* tdbb, jrd_tra** traHandle,
|
||||
ULONG inBlrLength, const UCHAR* inBlr, ULONG inMsgLength, const UCHAR* inMsg,
|
||||
ULONG outBlrLength, const UCHAR* const outBlr, ULONG outMsgLength, UCHAR* outMsg,
|
||||
bool singleton);
|
||||
|
||||
virtual void setCursor(thread_db* tdbb, const TEXT* name);
|
||||
|
||||
virtual ISC_STATUS fetch(thread_db* tdbb, ULONG blrLength, const UCHAR* blr,
|
||||
ULONG msgLength, UCHAR* msgBuffer);
|
||||
};
|
||||
|
||||
class DsqlDdlRequest : public dsql_req
|
||||
{
|
||||
public:
|
||||
explicit DsqlDdlRequest(DsqlCompilerScratch* scratch, DdlNode* aNode)
|
||||
: dsql_req(scratch),
|
||||
node(aNode)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void execute(thread_db* tdbb, jrd_tra** traHandle,
|
||||
ULONG inBlrLength, const UCHAR* inBlr, ULONG inMsgLength, const UCHAR* inMsg,
|
||||
ULONG outBlrLength, const UCHAR* const outBlr, ULONG outMsgLength, UCHAR* outMsg,
|
||||
bool singleton);
|
||||
|
||||
private:
|
||||
DdlNode* node;
|
||||
};
|
||||
|
||||
class DsqlTransactionRequest : public dsql_req
|
||||
{
|
||||
public:
|
||||
explicit DsqlTransactionRequest(DsqlCompilerScratch* scratch)
|
||||
: dsql_req(scratch)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void execute(thread_db* tdbb, jrd_tra** traHandle,
|
||||
ULONG inBlrLength, const UCHAR* inBlr, ULONG inMsgLength, const UCHAR* inMsg,
|
||||
ULONG outBlrLength, const UCHAR* const outBlr, ULONG outMsgLength, UCHAR* outMsg,
|
||||
bool singleton);
|
||||
};
|
||||
} // namespace
|
||||
|
||||
|
||||
@ -204,8 +153,10 @@ dsql_req* DSQL_allocate_statement(thread_db* tdbb, Jrd::Attachment* attachment)
|
||||
DsqlCompilerScratch* scratch = FB_NEW(pool) DsqlCompilerScratch(pool, database,
|
||||
NULL, statement);
|
||||
|
||||
dsql_req* const request = FB_NEW(pool) DsqlDmlRequest(scratch);
|
||||
dsql_req* const request = FB_NEW(pool) DsqlDmlRequest(pool, NULL);
|
||||
request->req_dbb = database;
|
||||
request->req_transaction = scratch->getTransaction();
|
||||
request->statement = scratch->getStatement();
|
||||
|
||||
return request;
|
||||
}
|
||||
@ -754,14 +705,108 @@ void DSQL_execute_immediate(thread_db* tdbb, Jrd::Attachment* attachment, jrd_tr
|
||||
}
|
||||
|
||||
|
||||
void DsqlDmlRequest::dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch,
|
||||
ntrace_result_t* traceResult)
|
||||
{
|
||||
node = Node::doDsqlPass(scratch, node);
|
||||
|
||||
if (scratch->clientDialect > SQL_DIALECT_V5)
|
||||
scratch->getStatement()->addFlags(DsqlCompiledStatement::FLAG_BLR_VERSION5);
|
||||
else
|
||||
scratch->getStatement()->addFlags(DsqlCompiledStatement::FLAG_BLR_VERSION4);
|
||||
|
||||
GEN_request(scratch, node);
|
||||
|
||||
// Create the messages buffers
|
||||
for (size_t i = 0; i < scratch->ports.getCount(); ++i)
|
||||
{
|
||||
dsql_msg* message = scratch->ports[i];
|
||||
|
||||
// Allocate buffer for message
|
||||
const ULONG newLen = message->msg_length + FB_DOUBLE_ALIGN - 1;
|
||||
|
||||
message->msg_buffer_number = req_msg_buffers.getCount();
|
||||
req_msg_buffers.grow(message->msg_buffer_number + 1);
|
||||
|
||||
UCHAR*& msgBuffer = req_msg_buffers[message->msg_buffer_number];
|
||||
fb_assert(!msgBuffer);
|
||||
|
||||
msgBuffer = FB_NEW(*tdbb->getDefaultPool()) UCHAR[newLen];
|
||||
msgBuffer = (UCHAR*) FB_ALIGN((U_IPTR) msgBuffer, FB_DOUBLE_ALIGN);
|
||||
}
|
||||
|
||||
// have the access method compile the statement
|
||||
|
||||
#ifdef DSQL_DEBUG
|
||||
if (DSQL_debug & 64)
|
||||
{
|
||||
dsql_trace("Resulting BLR code for DSQL:");
|
||||
gds__trace_raw("Statement:\n");
|
||||
gds__trace_raw(statement->getSqlText()->c_str(), statement->getSqlText()->length());
|
||||
gds__trace_raw("\nBLR:\n");
|
||||
fb_print_blr(scratch->getBlrData().begin(),
|
||||
(ULONG) scratch->getBlrData().getCount(),
|
||||
gds__trace_printer, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
ISC_STATUS_ARRAY localStatus;
|
||||
MOVE_CLEAR(localStatus, sizeof(localStatus));
|
||||
|
||||
// check for warnings
|
||||
if (tdbb->tdbb_status_vector[2] == isc_arg_warning)
|
||||
{
|
||||
// save a status vector
|
||||
memcpy(localStatus, tdbb->tdbb_status_vector, sizeof(ISC_STATUS_ARRAY));
|
||||
}
|
||||
|
||||
ISC_STATUS status = FB_SUCCESS;
|
||||
|
||||
try
|
||||
{
|
||||
JRD_compile(tdbb, scratch->getAttachment()->dbb_attachment, &req_request,
|
||||
scratch->getBlrData().getCount(), scratch->getBlrData().begin(),
|
||||
statement->getSqlText(),
|
||||
scratch->getDebugData().getCount(), scratch->getDebugData().begin(),
|
||||
(scratch->flags & DsqlCompilerScratch::FLAG_INTERNAL_REQUEST));
|
||||
}
|
||||
catch (const Exception&)
|
||||
{
|
||||
status = tdbb->tdbb_status_vector[1];
|
||||
*traceResult = (status == isc_no_priv ? res_unauthorized : res_failed);
|
||||
}
|
||||
|
||||
// restore warnings (if there are any)
|
||||
if (localStatus[2] == isc_arg_warning)
|
||||
{
|
||||
size_t indx, len, warning;
|
||||
|
||||
// find end of a status vector
|
||||
PARSE_STATUS(tdbb->tdbb_status_vector, indx, warning);
|
||||
if (indx)
|
||||
--indx;
|
||||
|
||||
// calculate length of saved warnings
|
||||
PARSE_STATUS(localStatus, len, warning);
|
||||
len -= 2;
|
||||
|
||||
if ((len + indx - 1) < ISC_STATUS_LENGTH)
|
||||
memcpy(&tdbb->tdbb_status_vector[indx], &localStatus[2], sizeof(ISC_STATUS) * len);
|
||||
}
|
||||
|
||||
// free blr memory
|
||||
scratch->getBlrData().free();
|
||||
|
||||
if (status)
|
||||
status_exception::raise(tdbb->tdbb_status_vector);
|
||||
}
|
||||
|
||||
// Execute a dynamic SQL statement.
|
||||
void DsqlDmlRequest::execute(thread_db* tdbb, jrd_tra** traHandle,
|
||||
ULONG inBlrLength, const UCHAR* inBlr, ULONG inMsgLength, const UCHAR* inMsg,
|
||||
ULONG outBlrLength, const UCHAR* const outBlr, ULONG outMsgLength, UCHAR* outMsg,
|
||||
bool singleton)
|
||||
{
|
||||
const DsqlCompiledStatement* statement = getStatement();
|
||||
|
||||
// If there is no data required, just start the request
|
||||
|
||||
const dsql_msg* message = statement->getSendMsg();
|
||||
@ -894,6 +939,30 @@ void DsqlDmlRequest::execute(thread_db* tdbb, jrd_tra** traHandle,
|
||||
trace.finish(have_cursor, res_successful);
|
||||
}
|
||||
|
||||
void DsqlDdlRequest::dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch,
|
||||
ntrace_result_t* traceResult)
|
||||
{
|
||||
this->scratch = scratch;
|
||||
|
||||
node = Node::doDsqlPass(scratch, node);
|
||||
|
||||
if (scratch->getAttachment()->dbb_read_only)
|
||||
ERRD_post(Arg::Gds(isc_read_only_database));
|
||||
|
||||
if ((scratch->flags & DsqlCompilerScratch::FLAG_AMBIGUOUS_STMT) &&
|
||||
scratch->getAttachment()->dbb_db_SQL_dialect != scratch->clientDialect)
|
||||
{
|
||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-817) <<
|
||||
Arg::Gds(isc_ddl_not_allowed_by_db_sql_dial) <<
|
||||
Arg::Num(scratch->getAttachment()->dbb_db_SQL_dialect));
|
||||
}
|
||||
|
||||
if (scratch->clientDialect > SQL_DIALECT_V5)
|
||||
scratch->getStatement()->addFlags(DsqlCompiledStatement::FLAG_BLR_VERSION5);
|
||||
else
|
||||
scratch->getStatement()->addFlags(DsqlCompiledStatement::FLAG_BLR_VERSION4);
|
||||
}
|
||||
|
||||
// Execute a dynamic SQL statement.
|
||||
void DsqlDdlRequest::execute(thread_db* tdbb, jrd_tra** traHandle,
|
||||
ULONG inBlrLength, const UCHAR* inBlr, ULONG inMsgLength, const UCHAR* inMsg,
|
||||
@ -902,14 +971,12 @@ void DsqlDdlRequest::execute(thread_db* tdbb, jrd_tra** traHandle,
|
||||
{
|
||||
TraceDSQLExecute trace(req_dbb->dbb_attachment, this);
|
||||
|
||||
const DsqlCompiledStatement* statement = getStatement();
|
||||
|
||||
fb_utils::init_status(tdbb->tdbb_status_vector);
|
||||
|
||||
// run all statements under savepoint control
|
||||
{ // scope
|
||||
AutoSavePoint savePoint(tdbb, req_transaction);
|
||||
node->executeDdl(tdbb, statement->getDdlScratch(), req_transaction);
|
||||
node->executeDdl(tdbb, scratch, req_transaction);
|
||||
savePoint.release(); // everything is ok
|
||||
}
|
||||
|
||||
@ -918,43 +985,20 @@ void DsqlDdlRequest::execute(thread_db* tdbb, jrd_tra** traHandle,
|
||||
trace.finish(false, res_successful);
|
||||
}
|
||||
|
||||
|
||||
void DsqlTransactionRequest::dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch,
|
||||
ntrace_result_t* /*traceResult*/)
|
||||
{
|
||||
node = Node::doDsqlPass(scratch, node);
|
||||
}
|
||||
|
||||
// Execute a dynamic SQL statement.
|
||||
void DsqlTransactionRequest::execute(thread_db* tdbb, jrd_tra** traHandle,
|
||||
ULONG inBlrLength, const UCHAR* inBlr, ULONG inMsgLength, const UCHAR* inMsg,
|
||||
ULONG outBlrLength, const UCHAR* const outBlr, ULONG outMsgLength, UCHAR* outMsg,
|
||||
bool singleton)
|
||||
{
|
||||
const DsqlCompiledStatement* statement = getStatement();
|
||||
|
||||
switch (statement->getType())
|
||||
{
|
||||
case DsqlCompiledStatement::TYPE_START_TRANS:
|
||||
JRD_start_transaction(tdbb, &req_transaction, req_dbb->dbb_attachment,
|
||||
statement->getDdlData().getCount(), statement->getDdlData().begin());
|
||||
*traHandle = req_transaction;
|
||||
break;
|
||||
|
||||
case DsqlCompiledStatement::TYPE_COMMIT:
|
||||
JRD_commit_transaction(tdbb, req_transaction);
|
||||
*traHandle = NULL;
|
||||
break;
|
||||
|
||||
case DsqlCompiledStatement::TYPE_COMMIT_RETAIN:
|
||||
JRD_commit_retaining(tdbb, req_transaction);
|
||||
break;
|
||||
|
||||
case DsqlCompiledStatement::TYPE_ROLLBACK:
|
||||
JRD_rollback_transaction(tdbb, req_transaction);
|
||||
*traHandle = NULL;
|
||||
break;
|
||||
|
||||
case DsqlCompiledStatement::TYPE_ROLLBACK_RETAIN:
|
||||
JRD_rollback_retaining(tdbb, req_transaction);
|
||||
break;
|
||||
|
||||
default:
|
||||
fb_assert(false);
|
||||
}
|
||||
node->execute(tdbb, this, traHandle);
|
||||
}
|
||||
|
||||
|
||||
@ -1535,6 +1579,9 @@ static dsql_req* prepareStatement(thread_db* tdbb, dsql_dbb* database, jrd_tra*
|
||||
transaction, statement);
|
||||
scratch->clientDialect = clientDialect;
|
||||
|
||||
if (isInternalRequest)
|
||||
scratch->flags |= DsqlCompilerScratch::FLAG_INTERNAL_REQUEST;
|
||||
|
||||
dsql_req* request = NULL;
|
||||
|
||||
try
|
||||
@ -1545,17 +1592,10 @@ static dsql_req* prepareStatement(thread_db* tdbb, dsql_dbb* database, jrd_tra*
|
||||
scratch->getAttachment()->dbb_db_SQL_dialect, parserVersion, text, textLength,
|
||||
tdbb->getAttachment()->att_charset);
|
||||
|
||||
Node* node = parser.parse();
|
||||
request = parser.parse();
|
||||
|
||||
if (!node)
|
||||
{
|
||||
// CVC: Apparently, Parser::parse won't return if the command is incomplete,
|
||||
// because yyerror() will call ERRD_post().
|
||||
// This may be a special case, but we don't know about positions here.
|
||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) <<
|
||||
// Unexpected end of command
|
||||
Arg::Gds(isc_command_end_err));
|
||||
}
|
||||
if (parser.isStmtAmbiguous())
|
||||
scratch->flags |= DsqlCompilerScratch::FLAG_AMBIGUOUS_STMT;
|
||||
|
||||
string transformedText = parser.getTransformedString();
|
||||
SSHORT charSetId = database->dbb_attachment->att_charset;
|
||||
@ -1602,161 +1642,24 @@ static dsql_req* prepareStatement(thread_db* tdbb, dsql_dbb* database, jrd_tra*
|
||||
|
||||
statement->setType(DsqlCompiledStatement::TYPE_SELECT);
|
||||
|
||||
node = Node::doDsqlPass(scratch, node);
|
||||
fb_assert(node);
|
||||
|
||||
const DsqlCompiledStatement::Type statementType = statement->getType();
|
||||
|
||||
switch (statementType)
|
||||
{
|
||||
case DsqlCompiledStatement::TYPE_COMMIT:
|
||||
case DsqlCompiledStatement::TYPE_COMMIT_RETAIN:
|
||||
case DsqlCompiledStatement::TYPE_ROLLBACK:
|
||||
case DsqlCompiledStatement::TYPE_ROLLBACK_RETAIN:
|
||||
case DsqlCompiledStatement::TYPE_START_TRANS:
|
||||
request = FB_NEW(statement->getPool()) DsqlTransactionRequest(scratch);
|
||||
request->req_traced = false;
|
||||
trace.setStatement(request);
|
||||
return request; // Stop here for statements not requiring code generation.
|
||||
|
||||
case DsqlCompiledStatement::TYPE_CREATE_DB:
|
||||
case DsqlCompiledStatement::TYPE_DDL:
|
||||
if (scratch->getAttachment()->dbb_read_only)
|
||||
ERRD_post(Arg::Gds(isc_read_only_database));
|
||||
|
||||
request = FB_NEW(statement->getPool()) DsqlDdlRequest(scratch,
|
||||
static_cast<DdlNode*>(node));
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
request = FB_NEW(statement->getPool()) DsqlDmlRequest(scratch);
|
||||
break;
|
||||
}
|
||||
|
||||
request->req_traced = true;
|
||||
trace.setStatement(request);
|
||||
|
||||
if (statementType == DsqlCompiledStatement::TYPE_DDL)
|
||||
{
|
||||
if (parser.isStmtAmbiguous() &&
|
||||
scratch->getAttachment()->dbb_db_SQL_dialect != clientDialect)
|
||||
{
|
||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-817) <<
|
||||
Arg::Gds(isc_ddl_not_allowed_by_db_sql_dial) <<
|
||||
Arg::Num(scratch->getAttachment()->dbb_db_SQL_dialect));
|
||||
}
|
||||
|
||||
statement->setDdlScratch(scratch);
|
||||
}
|
||||
|
||||
if (clientDialect > SQL_DIALECT_V5)
|
||||
statement->addFlags(DsqlCompiledStatement::FLAG_BLR_VERSION5);
|
||||
else
|
||||
statement->addFlags(DsqlCompiledStatement::FLAG_BLR_VERSION4);
|
||||
|
||||
if (!statement->isDdl())
|
||||
GEN_request(scratch, static_cast<DmlNode*>(node));
|
||||
|
||||
// Create the messages buffers
|
||||
for (size_t i = 0; i < scratch->ports.getCount(); ++i)
|
||||
{
|
||||
dsql_msg* message = scratch->ports[i];
|
||||
|
||||
// Allocate buffer for message
|
||||
const ULONG newLen = message->msg_length + FB_DOUBLE_ALIGN - 1;
|
||||
|
||||
message->msg_buffer_number = request->req_msg_buffers.getCount();
|
||||
request->req_msg_buffers.grow(message->msg_buffer_number + 1);
|
||||
|
||||
UCHAR*& msgBuffer = request->req_msg_buffers[message->msg_buffer_number];
|
||||
fb_assert(!msgBuffer);
|
||||
|
||||
msgBuffer = FB_NEW(*tdbb->getDefaultPool()) UCHAR[newLen];
|
||||
msgBuffer = (UCHAR*) FB_ALIGN((U_IPTR) msgBuffer, FB_DOUBLE_ALIGN);
|
||||
}
|
||||
|
||||
// stop here for ddl statements
|
||||
|
||||
if (statementType == DsqlCompiledStatement::TYPE_CREATE_DB ||
|
||||
statementType == DsqlCompiledStatement::TYPE_DDL)
|
||||
{
|
||||
// Notify Trace API manager about new DDL request cooked.
|
||||
trace.prepare(res_successful);
|
||||
return request;
|
||||
}
|
||||
|
||||
// have the access method compile the statement
|
||||
|
||||
#ifdef DSQL_DEBUG
|
||||
if (DSQL_debug & 64)
|
||||
{
|
||||
dsql_trace("Resulting BLR code for DSQL:");
|
||||
gds__trace_raw("Statement:\n");
|
||||
gds__trace_raw(text, textLength);
|
||||
gds__trace_raw("\nBLR:\n");
|
||||
fb_print_blr(scratch->getBlrData().begin(),
|
||||
(ULONG) scratch->getBlrData().getCount(),
|
||||
gds__trace_printer, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
ISC_STATUS_ARRAY localStatus;
|
||||
MOVE_CLEAR(localStatus, sizeof(localStatus));
|
||||
|
||||
// check for warnings
|
||||
if (tdbb->tdbb_status_vector[2] == isc_arg_warning)
|
||||
{
|
||||
// save a status vector
|
||||
memcpy(localStatus, tdbb->tdbb_status_vector, sizeof(ISC_STATUS_ARRAY));
|
||||
}
|
||||
|
||||
ISC_STATUS status = FB_SUCCESS;
|
||||
if (request->req_traced)
|
||||
trace.setStatement(request);
|
||||
|
||||
ntrace_result_t traceResult = res_successful;
|
||||
try
|
||||
{
|
||||
JRD_compile(tdbb,
|
||||
scratch->getAttachment()->dbb_attachment,
|
||||
&request->req_request,
|
||||
scratch->getBlrData().getCount(),
|
||||
scratch->getBlrData().begin(),
|
||||
statement->getSqlText(),
|
||||
scratch->getDebugData().getCount(),
|
||||
scratch->getDebugData().begin(),
|
||||
isInternalRequest);
|
||||
request->req_dbb = scratch->getAttachment();
|
||||
request->req_transaction = scratch->getTransaction();
|
||||
request->statement = scratch->getStatement();
|
||||
|
||||
request->dsqlPass(tdbb, scratch, &traceResult);
|
||||
}
|
||||
catch (const Firebird::Exception&)
|
||||
catch (const Exception&)
|
||||
{
|
||||
status = tdbb->tdbb_status_vector[1];
|
||||
trace.prepare(status == isc_no_priv ? res_unauthorized : res_failed);
|
||||
trace.prepare(traceResult);
|
||||
throw;
|
||||
}
|
||||
|
||||
// restore warnings (if there are any)
|
||||
if (localStatus[2] == isc_arg_warning)
|
||||
{
|
||||
size_t indx, len, warning;
|
||||
|
||||
// find end of a status vector
|
||||
PARSE_STATUS(tdbb->tdbb_status_vector, indx, warning);
|
||||
if (indx)
|
||||
--indx;
|
||||
|
||||
// calculate length of saved warnings
|
||||
PARSE_STATUS(localStatus, len, warning);
|
||||
len -= 2;
|
||||
|
||||
if ((len + indx - 1) < ISC_STATUS_LENGTH)
|
||||
memcpy(&tdbb->tdbb_status_vector[indx], &localStatus[2], sizeof(ISC_STATUS) * len);
|
||||
}
|
||||
|
||||
// free blr memory
|
||||
scratch->getBlrData().free();
|
||||
|
||||
if (status)
|
||||
Firebird::status_exception::raise(tdbb->tdbb_status_vector);
|
||||
|
||||
// Notify Trace API manager about new request cooked.
|
||||
trace.prepare(res_successful);
|
||||
trace.prepare(traceResult);
|
||||
|
||||
return request;
|
||||
}
|
||||
@ -1830,16 +1733,15 @@ static void release_statement(DsqlCompiledStatement* statement)
|
||||
}
|
||||
|
||||
statement->setSqlText(NULL);
|
||||
statement->getDdlData().free(); // free blr memory
|
||||
}
|
||||
|
||||
|
||||
dsql_req::dsql_req(DsqlCompilerScratch* scratch)
|
||||
: req_pool(scratch->getStatement()->getPool()),
|
||||
statement(scratch->getStatement()),
|
||||
dsql_req::dsql_req(MemoryPool& pool)
|
||||
: req_pool(pool),
|
||||
statement(NULL),
|
||||
cursors(req_pool),
|
||||
req_dbb(scratch->getAttachment()),
|
||||
req_transaction(scratch->getTransaction()),
|
||||
req_dbb(NULL),
|
||||
req_transaction(NULL),
|
||||
req_msg_buffers(req_pool),
|
||||
req_cursor(req_pool),
|
||||
req_user_descs(req_pool),
|
||||
|
@ -71,6 +71,9 @@ namespace Jrd
|
||||
class Attachment;
|
||||
class Database;
|
||||
class DsqlCompilerScratch;
|
||||
class DdlNode;
|
||||
class StmtNode;
|
||||
class TransactionNode;
|
||||
class jrd_tra;
|
||||
class jrd_req;
|
||||
class blb;
|
||||
@ -427,7 +430,6 @@ public:
|
||||
: PermanentStorage(p),
|
||||
type(TYPE_SELECT),
|
||||
flags(0),
|
||||
ddlData(p),
|
||||
sendMsg(NULL),
|
||||
receiveMsg(NULL),
|
||||
eof(NULL),
|
||||
@ -435,8 +437,7 @@ public:
|
||||
recVersion(NULL),
|
||||
parentRecVersion(NULL),
|
||||
parentDbKey(NULL),
|
||||
parentRequest(NULL),
|
||||
ddlScratch(NULL)
|
||||
parentRequest(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
@ -454,10 +455,6 @@ public:
|
||||
const Firebird::RefStrPtr& getSqlText() const { return sqlText; }
|
||||
void setSqlText(Firebird::RefString* value) { sqlText = value; }
|
||||
|
||||
Firebird::HalfStaticArray<UCHAR, 1024>& getDdlData() { return ddlData; }
|
||||
const Firebird::HalfStaticArray<UCHAR, 1024>& getDdlData() const { return ddlData; }
|
||||
void setDdlData(Firebird::HalfStaticArray<UCHAR, 1024>& value) { ddlData = value; }
|
||||
|
||||
bool isDdl() const
|
||||
{
|
||||
return type == TYPE_DDL || type == TYPE_CREATE_DB;
|
||||
@ -494,14 +491,10 @@ public:
|
||||
dsql_req* getParentRequest() const { return parentRequest; }
|
||||
void setParentRequest(dsql_req* value) { parentRequest = value; }
|
||||
|
||||
DsqlCompilerScratch* getDdlScratch() const { return ddlScratch; }
|
||||
void setDdlScratch(DsqlCompilerScratch* value) { ddlScratch = value; }
|
||||
|
||||
private:
|
||||
Type type; // Type of statement
|
||||
ULONG flags; // generic flag
|
||||
Firebird::RefStrPtr sqlText;
|
||||
Firebird::HalfStaticArray<UCHAR, 1024> ddlData;
|
||||
dsql_msg* sendMsg; // Message to be sent to start request
|
||||
dsql_msg* receiveMsg; // Per record message to be received
|
||||
dsql_par* eof; // End of file parameter
|
||||
@ -510,7 +503,6 @@ private:
|
||||
dsql_par* parentRecVersion; // parent record version
|
||||
dsql_par* parentDbKey; // Parent database key for current of
|
||||
dsql_req* parentRequest; // Source request, if cursor update
|
||||
DsqlCompilerScratch* ddlScratch; // DSQL scratch for DDL statements
|
||||
};
|
||||
|
||||
class dsql_req : public pool_alloc<dsql_type_req>
|
||||
@ -520,7 +512,7 @@ public:
|
||||
static const unsigned FLAG_EMBEDDED = 0x02;
|
||||
|
||||
public:
|
||||
explicit dsql_req(DsqlCompilerScratch* scratch);
|
||||
explicit dsql_req(MemoryPool& pool);
|
||||
|
||||
public:
|
||||
MemoryPool& getPool()
|
||||
@ -538,6 +530,9 @@ public:
|
||||
return statement;
|
||||
}
|
||||
|
||||
virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch,
|
||||
ntrace_result_t* traceResult) = 0;
|
||||
|
||||
virtual void execute(thread_db* tdbb, jrd_tra** traHandle,
|
||||
ULONG inBlrLength, const UCHAR* inBlr, ULONG inMsgLength, const UCHAR* inMsg,
|
||||
ULONG outBlrLength, const UCHAR* const outBlr, ULONG outMsgLength, UCHAR* outMsg,
|
||||
@ -552,9 +547,9 @@ public:
|
||||
|
||||
private:
|
||||
MemoryPool& req_pool;
|
||||
const DsqlCompiledStatement* statement;
|
||||
|
||||
public:
|
||||
const DsqlCompiledStatement* statement;
|
||||
Firebird::Array<DsqlCompiledStatement*> cursors; // Cursor update statements
|
||||
|
||||
dsql_dbb* req_dbb; // DSQL attachment
|
||||
@ -584,6 +579,79 @@ protected:
|
||||
friend class Firebird::MemoryPool;
|
||||
};
|
||||
|
||||
class DsqlDmlRequest : public dsql_req
|
||||
{
|
||||
public:
|
||||
explicit DsqlDmlRequest(MemoryPool& pool, StmtNode* aNode)
|
||||
: dsql_req(pool),
|
||||
node(aNode)
|
||||
{
|
||||
req_traced = true;
|
||||
}
|
||||
|
||||
virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch,
|
||||
ntrace_result_t* traceResult);
|
||||
|
||||
virtual void execute(thread_db* tdbb, jrd_tra** traHandle,
|
||||
ULONG inBlrLength, const UCHAR* inBlr, ULONG inMsgLength, const UCHAR* inMsg,
|
||||
ULONG outBlrLength, const UCHAR* const outBlr, ULONG outMsgLength, UCHAR* outMsg,
|
||||
bool singleton);
|
||||
|
||||
virtual void setCursor(thread_db* tdbb, const TEXT* name);
|
||||
|
||||
virtual ISC_STATUS fetch(thread_db* tdbb, ULONG blrLength, const UCHAR* blr,
|
||||
ULONG msgLength, UCHAR* msgBuffer);
|
||||
|
||||
private:
|
||||
StmtNode* node;
|
||||
};
|
||||
|
||||
class DsqlDdlRequest : public dsql_req
|
||||
{
|
||||
public:
|
||||
explicit DsqlDdlRequest(MemoryPool& pool, DdlNode* aNode)
|
||||
: dsql_req(pool),
|
||||
node(aNode),
|
||||
scratch(NULL)
|
||||
{
|
||||
req_traced = true;
|
||||
}
|
||||
|
||||
virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch,
|
||||
ntrace_result_t* traceResult);
|
||||
|
||||
virtual void execute(thread_db* tdbb, jrd_tra** traHandle,
|
||||
ULONG inBlrLength, const UCHAR* inBlr, ULONG inMsgLength, const UCHAR* inMsg,
|
||||
ULONG outBlrLength, const UCHAR* const outBlr, ULONG outMsgLength, UCHAR* outMsg,
|
||||
bool singleton);
|
||||
|
||||
private:
|
||||
DdlNode* node;
|
||||
DsqlCompilerScratch* scratch;
|
||||
};
|
||||
|
||||
class DsqlTransactionRequest : public dsql_req
|
||||
{
|
||||
public:
|
||||
explicit DsqlTransactionRequest(MemoryPool& pool, TransactionNode* aNode)
|
||||
: dsql_req(pool),
|
||||
node(aNode)
|
||||
{
|
||||
req_traced = false;
|
||||
}
|
||||
|
||||
virtual void dsqlPass(thread_db* tdbb, DsqlCompilerScratch* scratch,
|
||||
ntrace_result_t* traceResult);
|
||||
|
||||
virtual void execute(thread_db* tdbb, jrd_tra** traHandle,
|
||||
ULONG inBlrLength, const UCHAR* inBlr, ULONG inMsgLength, const UCHAR* inMsg,
|
||||
ULONG outBlrLength, const UCHAR* const outBlr, ULONG outMsgLength, UCHAR* outMsg,
|
||||
bool singleton);
|
||||
|
||||
private:
|
||||
TransactionNode* node;
|
||||
};
|
||||
|
||||
//! Implicit (NATURAL and USING) joins
|
||||
class ImplicitJoin : public pool_alloc<dsql_type_imp_join>
|
||||
{
|
||||
|
@ -645,6 +645,7 @@ inline void check_copy_incr(char*& to, const char ch, const char* const string)
|
||||
Jrd::BoolExprNode* boolExprNode;
|
||||
Jrd::StmtNode* stmtNode;
|
||||
Jrd::DdlNode* ddlNode;
|
||||
Jrd::TransactionNode* traNode;
|
||||
Jrd::CreateCollationNode* createCollationNode;
|
||||
Jrd::CreateDomainNode* createDomainNode;
|
||||
Jrd::AlterDomainNode* alterDomainNode;
|
||||
@ -676,6 +677,7 @@ inline void check_copy_incr(char*& to, const char ch, const char* const string)
|
||||
Jrd::SetTransactionNode* setTransactionNode;
|
||||
Jrd::DeclareSubProcNode* declareSubProcNode;
|
||||
Jrd::DeclareSubFuncNode* declareSubFuncNode;
|
||||
Jrd::dsql_req* dsqlReq;
|
||||
}
|
||||
|
||||
%type <legacyNode> access_type alias_list
|
||||
@ -712,10 +714,10 @@ inline void check_copy_incr(char*& to, const char ch, const char* const string)
|
||||
%type <legacyNode> column_constraint column_constraint_clause
|
||||
%type <legacyNode> column_constraint_def column_constraint_list column_def
|
||||
%type <boolVal> check_opt
|
||||
|
||||
%type <legacyNode> column_list column_name column_parens column_parens_opt column_select
|
||||
%type <legacyNode> column_singleton
|
||||
%type <stmtNode> commit complex_proc_statement
|
||||
%type <traNode> commit
|
||||
%type <stmtNode> complex_proc_statement
|
||||
%type <legacyNode> computed_by computed_clause constant constraint_index_opt
|
||||
%type <boolVal> conditional
|
||||
%type <legacyNode> constraint_name_opt correlation_name
|
||||
@ -744,6 +746,8 @@ inline void check_copy_incr(char*& to, const char ch, const char* const string)
|
||||
%type <ddlNode> declare declare_clause drop drop_clause
|
||||
%type <legacyStr> db_name ddl_desc
|
||||
%type db_alter_clause(<alterDatabaseNode>)
|
||||
%type <ddlNode> ddl_statement
|
||||
%type <stmtNode> dml_statement
|
||||
|
||||
%type <legacyNode> event_argument_opt
|
||||
%type <ddlNode> exception_clause
|
||||
@ -851,7 +855,7 @@ inline void check_copy_incr(char*& to, const char ch, const char* const string)
|
||||
%type <ddlNode> revoke rexception_clause
|
||||
%type <legacyNode> role_admin_option role_grantee role_grantee_list
|
||||
%type <legacyNode> role_name role_name_list rows_clause
|
||||
%type <stmtNode> rollback
|
||||
%type <traNode> rollback
|
||||
%type <ddlNode> role_clause rtable_clause
|
||||
%type <ddlNode> rview_clause
|
||||
%type <nullableIntVal> revoke_admin
|
||||
@ -871,7 +875,7 @@ inline void check_copy_incr(char*& to, const char ch, const char* const string)
|
||||
%type <ddlNode> set_statistics
|
||||
%type <legacyNode> simple_type simple_when_clause skip_clause
|
||||
%type <uintVal> snap_shot
|
||||
%type <node> statement
|
||||
%type <dsqlReq> statement
|
||||
%type <legacyNode> string_length_opt
|
||||
%type <legacyNode> symbol_UDF_call_name symbol_UDF_name symbol_blob_subtype_name symbol_character_set_name
|
||||
%type <legacyNode> symbol_collation_name symbol_column_name symbol_constraint_name symbol_cursor_name
|
||||
@ -897,6 +901,7 @@ inline void check_copy_incr(char*& to, const char ch, const char* const string)
|
||||
%type tran_option(<setTransactionNode>) tran_option_list(<setTransactionNode>)
|
||||
%type tran_option_list_opt(<setTransactionNode>)
|
||||
%type <uintVal> time_precision_opt timestamp_precision_opt
|
||||
%type <traNode> tra_statement
|
||||
|
||||
%type <legacyNode> u_constant u_numeric_constant udf_data_type
|
||||
%type <createAlterFunctionNode> udf_decl_clause
|
||||
@ -998,40 +1003,50 @@ inline void check_copy_incr(char*& to, const char ch, const char* const string)
|
||||
// list of possible statements
|
||||
|
||||
top
|
||||
: statement
|
||||
{ DSQL_parse = $1; }
|
||||
| statement ';'
|
||||
{ DSQL_parse = $1; }
|
||||
: statement { DSQL_parse = $1; }
|
||||
| statement ';' { DSQL_parse = $1; }
|
||||
;
|
||||
|
||||
statement
|
||||
: alter { $$ = $1; }
|
||||
: dml_statement { $$ = newNode<DsqlDmlRequest>($1); }
|
||||
| ddl_statement { $$ = newNode<DsqlDdlRequest>($1); }
|
||||
| tra_statement { $$ = newNode<DsqlTransactionRequest>($1); }
|
||||
;
|
||||
|
||||
dml_statement
|
||||
// ASF: ALTER SEQUENCE is defined here cause it's treated as DML.
|
||||
| ALTER SEQUENCE alter_sequence_clause { $$ = $3; }
|
||||
| comment { $$ = $1; }
|
||||
| commit { $$ = $1; }
|
||||
| create { $$ = $1; }
|
||||
| create_or_alter { $$ = $1; }
|
||||
| declare { $$ = $1; }
|
||||
: ALTER SEQUENCE alter_sequence_clause { $$ = $3; }
|
||||
| delete { $$ = $1; }
|
||||
| drop { $$ = $1; }
|
||||
| grant { $$ = $1; }
|
||||
| insert { $$ = $1; }
|
||||
| merge { $$ = $1; }
|
||||
| exec_procedure { $$ = $1; }
|
||||
| exec_block { $$ = $1; }
|
||||
| recreate { $$ = $1; }
|
||||
| revoke { $$ = $1; }
|
||||
| rollback { $$ = $1; }
|
||||
| savepoint { $$ = $1; }
|
||||
| select { $$ = $1; }
|
||||
| set_transaction { $$ = $1; }
|
||||
| set_generator { $$ = $1; }
|
||||
| set_statistics { $$ = $1; }
|
||||
| update { $$ = $1; }
|
||||
| update_or_insert { $$ = $1; }
|
||||
;
|
||||
|
||||
ddl_statement
|
||||
: alter { $$ = $1; }
|
||||
| comment { $$ = $1; }
|
||||
| create { $$ = $1; }
|
||||
| create_or_alter { $$ = $1; }
|
||||
| declare { $$ = $1; }
|
||||
| drop { $$ = $1; }
|
||||
| grant { $$ = $1; }
|
||||
| recreate { $$ = $1; }
|
||||
| revoke { $$ = $1; }
|
||||
| set_statistics { $$ = $1; }
|
||||
;
|
||||
|
||||
tra_statement
|
||||
: set_transaction { $$ = $1; }
|
||||
| commit { $$ = $1; }
|
||||
| rollback { $$ = $1; }
|
||||
;
|
||||
|
||||
|
||||
// GRANT statement
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user