StmtNodes.cpp (Firebird-3.0.2.32703-0.tar.bz2) | : | StmtNodes.cpp (Firebird-3.0.4.33054-0.tar.bz2) | ||
---|---|---|---|---|
skipping to change at line 1207 | skipping to change at line 1207 | |||
} | } | |||
fb_assert(false); | fb_assert(false); | |||
return NULL; | return NULL; | |||
} | } | |||
//-------------------- | //-------------------- | |||
static RegisterNode<DeclareCursorNode> regDeclareCursorNode(blr_dcl_cursor); | static RegisterNode<DeclareCursorNode> regDeclareCursorNode(blr_dcl_cursor); | |||
DmlNode* DeclareCursorNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScr atch* csb, const UCHAR /*blrOp*/) | DmlNode* DeclareCursorNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScr atch* csb, const UCHAR blrOp) | |||
{ | { | |||
DeclareCursorNode* node = FB_NEW_POOL(pool) DeclareCursorNode(pool); | DeclareCursorNode* node = FB_NEW_POOL(pool) DeclareCursorNode(pool); | |||
fb_assert(blrOp == blr_dcl_cursor); | ||||
if (blrOp == blr_dcl_cursor) | ||||
node->dsqlCursorType = CUR_TYPE_EXPLICIT; | ||||
node->cursorNumber = csb->csb_blr_reader.getWord(); | node->cursorNumber = csb->csb_blr_reader.getWord(); | |||
node->rse = PAR_rse(tdbb, csb); | node->rse = PAR_rse(tdbb, csb); | |||
USHORT count = csb->csb_blr_reader.getWord(); | USHORT count = csb->csb_blr_reader.getWord(); | |||
node->refs = PAR_args(tdbb, csb, count, count); | node->refs = PAR_args(tdbb, csb, count, count); | |||
return node; | return node; | |||
} | } | |||
DeclareCursorNode* DeclareCursorNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) | DeclareCursorNode* DeclareCursorNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) | |||
skipping to change at line 1315 | skipping to change at line 1319 | |||
if (cursorNumber >= csb->csb_cursors.getCount()) | if (cursorNumber >= csb->csb_cursors.getCount()) | |||
csb->csb_cursors.grow(cursorNumber + 1); | csb->csb_cursors.grow(cursorNumber + 1); | |||
csb->csb_cursors[cursorNumber] = cursor; | csb->csb_cursors[cursorNumber] = cursor; | |||
StreamList cursorStreams; | StreamList cursorStreams; | |||
cursor->getAccessPath()->findUsedStreams(cursorStreams); | cursor->getAccessPath()->findUsedStreams(cursorStreams); | |||
// Activate cursor streams to allow index usage for <cursor>.<field> refe rences, see CORE-4675. | // Activate cursor streams to allow index usage for <cursor>.<field> refe rences, see CORE-4675. | |||
// It's also useful for correlated sub-queries in the select list, see CO RE-4379. | // It's also useful for correlated sub-queries in the select list, see CO RE-4379. | |||
// Mark cursor streams as unstable, see CORE-5773. | ||||
for (StreamList::const_iterator i = cursorStreams.begin(); i != cursorStr eams.end(); ++i) | for (StreamList::const_iterator i = cursorStreams.begin(); i != cursorStr eams.end(); ++i) | |||
{ | { | |||
csb->csb_rpt[*i].csb_cursor_number = cursorNumber; | csb->csb_rpt[*i].csb_cursor_number = cursorNumber; | |||
csb->csb_rpt[*i].activate(); | csb->csb_rpt[*i].activate(); | |||
if (dsqlCursorType == CUR_TYPE_EXPLICIT) | ||||
csb->csb_rpt[*i].csb_flags |= csb_unstable; | ||||
} | } | |||
return this; | return this; | |||
} | } | |||
const StmtNode* DeclareCursorNode::execute(thread_db* /*tdbb*/, jrd_req* request , ExeState* /*exeState*/) const | const StmtNode* DeclareCursorNode::execute(thread_db* /*tdbb*/, jrd_req* request , ExeState* /*exeState*/) const | |||
{ | { | |||
if (request->req_operation == jrd_req::req_evaluate) | if (request->req_operation == jrd_req::req_evaluate) | |||
{ | { | |||
// Set up the cursors array... | // Set up the cursors array... | |||
skipping to change at line 1515 | skipping to change at line 1522 | |||
dsqlFunction = FB_NEW_POOL(pool) dsql_udf(pool); | dsqlFunction = FB_NEW_POOL(pool) dsql_udf(pool); | |||
dsqlFunction->udf_flags = UDF_subfunc; | dsqlFunction->udf_flags = UDF_subfunc; | |||
dsqlFunction->udf_name.identifier = name; | dsqlFunction->udf_name.identifier = name; | |||
fb_assert(dsqlBlock->returns.getCount() == 1); | fb_assert(dsqlBlock->returns.getCount() == 1); | |||
const TypeClause* returnType = dsqlBlock->returns[0]->type; | const TypeClause* returnType = dsqlBlock->returns[0]->type; | |||
dsqlFunction->udf_dtype = returnType->dtype; | dsqlFunction->udf_dtype = returnType->dtype; | |||
dsqlFunction->udf_scale = returnType->scale; | dsqlFunction->udf_scale = returnType->scale; | |||
dsqlFunction->udf_sub_type = returnType->subType; | dsqlFunction->udf_sub_type = returnType->subType; | |||
dsqlFunction->udf_length = returnType->length; | dsqlFunction->udf_length = returnType->length; | |||
dsqlFunction->udf_character_set_id = returnType->charSetId; | dsqlFunction->udf_character_set_id = returnType->charSetId.value; | |||
const Array<NestConst<ParameterClause> >& paramArray = dsqlBlock->paramet ers; | const Array<NestConst<ParameterClause> >& paramArray = dsqlBlock->paramet ers; | |||
bool defaultFound = false; | bool defaultFound = false; | |||
for (const NestConst<ParameterClause>* i = paramArray.begin(); i != param Array.end(); ++i) | for (const NestConst<ParameterClause>* i = paramArray.begin(); i != param Array.end(); ++i) | |||
{ | { | |||
// ASF: dsqlFunction->udf_arguments is only checked for its count for now. | // ASF: dsqlFunction->udf_arguments is only checked for its count for now. | |||
dsqlFunction->udf_arguments.add(dsc()); | dsqlFunction->udf_arguments.add(dsc()); | |||
dsqlFunction->udf_fld_system_arguments.add(false); | dsqlFunction->udf_fld_system_arguments.add(false); | |||
skipping to change at line 1976 | skipping to change at line 1983 | |||
impureOffset = CMP_impure(csb, sizeof(impure_value)); | impureOffset = CMP_impure(csb, sizeof(impure_value)); | |||
return this; | return this; | |||
} | } | |||
const StmtNode* DeclareVariableNode::execute(thread_db* tdbb, jrd_req* request, ExeState* /*exeState*/) const | const StmtNode* DeclareVariableNode::execute(thread_db* tdbb, jrd_req* request, ExeState* /*exeState*/) const | |||
{ | { | |||
if (request->req_operation == jrd_req::req_evaluate) | if (request->req_operation == jrd_req::req_evaluate) | |||
{ | { | |||
impure_value* variable = request->getImpure<impure_value>(impureO ffset); | impure_value* variable = request->getImpure<impure_value>(impureO ffset); | |||
variable->vlu_desc = varDesc; | variable->vlu_desc = varDesc; | |||
variable->vlu_desc.dsc_flags = 0; | variable->vlu_desc.clearFlags(); | |||
if (variable->vlu_desc.dsc_dtype <= dtype_varying) | if (variable->vlu_desc.dsc_dtype <= dtype_varying) | |||
{ | { | |||
if (!variable->vlu_string) | if (!variable->vlu_string) | |||
{ | { | |||
const USHORT len = variable->vlu_desc.dsc_length; | const USHORT len = variable->vlu_desc.dsc_length; | |||
variable->vlu_string = FB_NEW_RPT(*tdbb->getDefau ltPool(), len) VaryingString(); | variable->vlu_string = FB_NEW_RPT(*tdbb->getDefau ltPool(), len) VaryingString(); | |||
variable->vlu_string->str_length = len; | variable->vlu_string->str_length = len; | |||
} | } | |||
skipping to change at line 3217 | skipping to change at line 3224 | |||
void ExecStatementNode::genBlr(DsqlCompilerScratch* dsqlScratch) | void ExecStatementNode::genBlr(DsqlCompilerScratch* dsqlScratch) | |||
{ | { | |||
if (innerStmt) | if (innerStmt) | |||
{ | { | |||
dsqlScratch->appendUChar(blr_label); | dsqlScratch->appendUChar(blr_label); | |||
dsqlScratch->appendUChar(dsqlLabelNumber); | dsqlScratch->appendUChar(dsqlLabelNumber); | |||
} | } | |||
// If no new features of EXECUTE STATEMENT are used, lets generate old BL R. | // If no new features of EXECUTE STATEMENT are used, lets generate old BL R. | |||
if (!dataSource && !userName && !password && !role && !useCallerPrivs && | if (!dataSource && !userName && !password && !role && !useCallerPrivs && | |||
!inputs && !traScope) | !inputs && | |||
traScope == EDS::traNotSet) | ||||
{ | { | |||
if (outputs) | if (outputs) | |||
{ | { | |||
dsqlScratch->appendUChar(blr_exec_into); | dsqlScratch->appendUChar(blr_exec_into); | |||
dsqlScratch->appendUShort(outputs->items.getCount()); | dsqlScratch->appendUShort(outputs->items.getCount()); | |||
GEN_expr(dsqlScratch, sql); | GEN_expr(dsqlScratch, sql); | |||
if (innerStmt) | if (innerStmt) | |||
{ | { | |||
skipping to change at line 3278 | skipping to change at line 3286 | |||
innerStmt->genBlr(dsqlScratch); | innerStmt->genBlr(dsqlScratch); | |||
} | } | |||
// External data source, user, password and role. | // External data source, user, password and role. | |||
genOptionalExpr(dsqlScratch, blr_exec_stmt_data_src, dataSource); | genOptionalExpr(dsqlScratch, blr_exec_stmt_data_src, dataSource); | |||
genOptionalExpr(dsqlScratch, blr_exec_stmt_user, userName); | genOptionalExpr(dsqlScratch, blr_exec_stmt_user, userName); | |||
genOptionalExpr(dsqlScratch, blr_exec_stmt_pwd, password); | genOptionalExpr(dsqlScratch, blr_exec_stmt_pwd, password); | |||
genOptionalExpr(dsqlScratch, blr_exec_stmt_role, role); | genOptionalExpr(dsqlScratch, blr_exec_stmt_role, role); | |||
// dsqlScratch's transaction behavior. | // dsqlScratch's transaction behavior. | |||
if (traScope) | if (traScope != EDS::traNotSet) | |||
{ | { | |||
// Transaction parameters equal to current transaction. | // Transaction parameters equal to current transaction. | |||
dsqlScratch->appendUChar(blr_exec_stmt_tran_clone); | dsqlScratch->appendUChar(blr_exec_stmt_tran_clone); | |||
dsqlScratch->appendUChar(UCHAR(traScope)); | dsqlScratch->appendUChar(UCHAR(traScope)); | |||
} | } | |||
// Inherit caller's privileges? | // Inherit caller's privileges? | |||
if (useCallerPrivs) | if (useCallerPrivs) | |||
dsqlScratch->appendUChar(blr_exec_stmt_privs); | dsqlScratch->appendUChar(blr_exec_stmt_privs); | |||
skipping to change at line 3642 | skipping to change at line 3650 | |||
jrd_tra* const org_transaction = request->req_transaction; | jrd_tra* const org_transaction = request->req_transaction; | |||
fb_assert(tdbb->getTransaction() == org_transaction); | fb_assert(tdbb->getTransaction() == org_transaction); | |||
jrd_tra* const transaction = TRA_start(tdbb, org_transaction->tra _flags, | jrd_tra* const transaction = TRA_start(tdbb, org_transaction->tra _flags, | |||
org_transaction->tra_lock_timeout, | org_transaction->tra_lock_timeout, | |||
org_transaction); | org_transaction); | |||
TRA_attach_request(transaction, request); | TRA_attach_request(transaction, request); | |||
tdbb->setTransaction(transaction); | tdbb->setTransaction(transaction); | |||
try | ||||
{ | ||||
// run ON TRANSACTION START triggers | ||||
JRD_run_trans_start_triggers(tdbb, transaction); | ||||
} | ||||
catch (Exception&) | ||||
{ | ||||
TRA_attach_request(org_transaction, request); | ||||
tdbb->setTransaction(org_transaction); | ||||
throw; | ||||
} | ||||
request->req_auto_trans.push(org_transaction); | request->req_auto_trans.push(org_transaction); | |||
impure->traNumber = transaction->tra_number; | impure->traNumber = transaction->tra_number; | |||
VIO_start_save_point(tdbb, transaction); | VIO_start_save_point(tdbb, transaction); | |||
impure->savNumber = transaction->tra_save_point->sav_number; | impure->savNumber = transaction->tra_save_point->sav_number; | |||
if (!(attachment->att_flags & ATT_no_db_triggers)) | ||||
{ | ||||
// run ON TRANSACTION START triggers | ||||
EXE_execute_db_triggers(tdbb, transaction, TRIGGER_TRANS_ | ||||
START); | ||||
} | ||||
return action; | return action; | |||
} | } | |||
jrd_tra* transaction = request->req_transaction; | jrd_tra* transaction = request->req_transaction; | |||
fb_assert(transaction && transaction != attachment->getSysTransaction()); | fb_assert(transaction && transaction != attachment->getSysTransaction()); | |||
if (!impure->traNumber) | if (!impure->traNumber) | |||
return parentStmt; | return parentStmt; | |||
fb_assert(transaction->tra_number == impure->traNumber); | fb_assert(transaction->tra_number == impure->traNumber); | |||
skipping to change at line 5452 | skipping to change at line 5466 | |||
maxAlignment = MAX(maxAlignment, alignment); | maxAlignment = MAX(maxAlignment, alignment); | |||
if (maxAlignment && shouldPad && index + 1 == padField) | if (maxAlignment && shouldPad && index + 1 == padField) | |||
offset = FB_ALIGN(offset, maxAlignment); | offset = FB_ALIGN(offset, maxAlignment); | |||
// ASF: Odd indexes are the nullable flag. | // ASF: Odd indexes are the nullable flag. | |||
// So we only check even indexes, which is the actual parameter. | // So we only check even indexes, which is the actual parameter. | |||
if (itemInfo.isSpecial() && index % 2 == 0) | if (itemInfo.isSpecial() && index % 2 == 0) | |||
{ | { | |||
csb->csb_dbg_info->argInfoToName.get( | csb->csb_dbg_info->argInfoToName.get(ArgumentInfo(csb->cs | |||
ArgumentInfo(csb->csb_msg_number, index / 2), ite | b_msg_number, index / 2), itemInfo.name); | |||
mInfo.name); | csb->csb_map_item_info.put(Item(Item::TYPE_PARAMETER, mes | |||
sage, index), itemInfo); | ||||
csb->csb_map_item_info.put(Item(Item::TYPE_PARAMETER, csb | ||||
->csb_msg_number, index), | ||||
itemInfo); | ||||
} | } | |||
} | } | |||
format->fmt_length = offset; | format->fmt_length = offset; | |||
} | } | |||
USHORT MessageNode::setupDesc(thread_db* tdbb, CompilerScratch* csb, USHORT /*in dex*/, | USHORT MessageNode::setupDesc(thread_db* tdbb, CompilerScratch* csb, USHORT /*in dex*/, | |||
dsc* desc, ItemInfo* itemInfo) | dsc* desc, ItemInfo* itemInfo) | |||
{ | { | |||
return PAR_desc(tdbb, csb, desc, itemInfo); | return PAR_desc(tdbb, csb, desc, itemInfo); | |||
End of changes. 11 change blocks. | ||||
20 lines changed or deleted | 30 lines changed or added |