From: <asf...@us...> - 2011-03-06 02:48:42
|
Revision: 52518 http://firebird.svn.sourceforge.net/firebird/?rev=52518&view=rev Author: asfernandes Date: 2011-03-06 02:48:34 +0000 (Sun, 06 Mar 2011) Log Message: ----------- Reference DML statements in DSQL with StmtNode instead of dsql_nod. Modified Paths: -------------- firebird/trunk/src/dsql/DdlNodes.epp firebird/trunk/src/dsql/DdlNodes.h firebird/trunk/src/dsql/DsqlCompilerScratch.cpp firebird/trunk/src/dsql/DsqlCompilerScratch.h firebird/trunk/src/dsql/StmtNodes.cpp firebird/trunk/src/dsql/StmtNodes.h firebird/trunk/src/dsql/ddl.cpp firebird/trunk/src/dsql/ddl_proto.h firebird/trunk/src/dsql/parse.y firebird/trunk/src/dsql/pass1.cpp Modified: firebird/trunk/src/dsql/DdlNodes.epp =================================================================== --- firebird/trunk/src/dsql/DdlNodes.epp 2011-03-06 01:06:36 UTC (rev 52517) +++ firebird/trunk/src/dsql/DdlNodes.epp 2011-03-06 02:48:34 UTC (rev 52518) @@ -732,7 +732,7 @@ void TypeClause::resolve(DsqlCompilerScratch* dsqlScratch, bool modifying) { DDL_resolve_intl_type2(dsqlScratch, legacyField, - (collate.isEmpty() ? NULL : MAKE_cstring(collate.c_str())), modifying); + (collate.isEmpty() ? NULL : collate), modifying); setup(dsqlScratch); } @@ -1079,12 +1079,14 @@ names.add(parameter.name); } - const dsql_nod* const* ptr = variables->dsqlStatements.begin(); - for (const dsql_nod* const* const end = variables->dsqlStatements.end(); ptr != end; ++ptr) + const NestConst<StmtNode>* ptr = variables->statements.begin(); + for (const NestConst<StmtNode>* const end = variables->statements.end(); ptr != end; ++ptr) { - if ((*ptr)->nod_type == nod_def_field) + const DeclareVariableNode* varNode = (*ptr)->as<DeclareVariableNode>(); + + if (varNode) { - const dsql_fld* field = (dsql_fld*) (*ptr)->nod_arg[e_dfl_field]; + const dsql_fld* field = varNode->dsqlDef->legacyField; DEV_BLKCHK(field, dsql_type_fld); if (names.exist(field->fld_name)) @@ -1614,7 +1616,7 @@ dsqlScratch->loopLevel = 0; dsqlScratch->cursorNumber = 0; - dsql_nod* stmtNode = PASS1_statement(dsqlScratch, body); + StmtNode* stmtNode = body->dsqlPass(dsqlScratch); GEN_hidden_variables(dsqlScratch); dsqlScratch->appendUChar(blr_stall); @@ -1623,7 +1625,7 @@ dsqlScratch->appendUChar(blr_label); dsqlScratch->appendUChar(0); - GEN_statement(dsqlScratch, stmtNode); + stmtNode->genBlr(dsqlScratch); dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_DDL); dsqlScratch->appendUChar(blr_end); @@ -1834,19 +1836,22 @@ names.add(parameter.name); } - const dsql_nod* const* ptr = variables->dsqlStatements.begin(); - for (const dsql_nod* const* const end = variables->dsqlStatements.end(); ptr != end; ++ptr) + const NestConst<StmtNode>* ptr = variables->statements.begin(); + for (const NestConst<StmtNode>* const end = variables->statements.end(); ptr != end; ++ptr) { - if ((*ptr)->nod_type == nod_def_field) + const DeclareVariableNode* varNode = (*ptr)->as<DeclareVariableNode>(); + + if (varNode) { - const dsql_fld* field = (dsql_fld*) (*ptr)->nod_arg[e_dfl_field]; + const dsql_fld* field = varNode->dsqlDef->legacyField; DEV_BLKCHK(field, dsql_type_fld); if (names.exist(field->fld_name)) { status_exception::raise( Arg::Gds(isc_sqlerr) << Arg::Num(-901) << - Arg::Gds(isc_dsql_var_conflict) << Arg::Str(field->fld_name)); + Arg::Gds(isc_dsql_var_conflict) << + Arg::Str(field->fld_name)); } } } @@ -2400,7 +2405,7 @@ dsqlScratch->loopLevel = 0; dsqlScratch->cursorNumber = 0; - dsql_nod* stmtNode = PASS1_statement(dsqlScratch, body); + StmtNode* stmtNode = body->dsqlPass(dsqlScratch); GEN_hidden_variables(dsqlScratch); dsqlScratch->appendUChar(blr_stall); @@ -2409,7 +2414,7 @@ dsqlScratch->appendUChar(blr_label); dsqlScratch->appendUChar(0); - GEN_statement(dsqlScratch, stmtNode); + stmtNode->genBlr(dsqlScratch); dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_DDL); dsqlScratch->appendUChar(blr_end); @@ -2887,7 +2892,7 @@ dsqlScratch->appendUChar(0); dsqlScratch->loopLevel = 0; dsqlScratch->cursorNumber = 0; - GEN_statement(dsqlScratch, PASS1_statement(dsqlScratch, body)); + body->dsqlPass(dsqlScratch)->genBlr(dsqlScratch); dsqlScratch->scopeLevel--; dsqlScratch->appendUChar(blr_end); dsqlScratch->appendUChar(blr_eoc); @@ -5022,7 +5027,10 @@ } if (element->nod_arg[Dsql::e_dfl_collate]) - DDL_resolve_intl_type(dsqlScratch, field, (dsql_str*) element->nod_arg[Dsql::e_dfl_collate]); + { + DDL_resolve_intl_type(dsqlScratch, field, + ((dsql_str*) element->nod_arg[Dsql::e_dfl_collate])->str_data); + } if (element->nod_arg[Dsql::e_dfl_identity]) { @@ -5682,8 +5690,7 @@ ExceptionNode* exceptionNode = FB_NEW(pool) ExceptionNode(pool, CHECK_CONSTRAINT_EXCEPTION); exceptionNode->exception->type = ExceptionItem::GDS_CODE; - actionNode->dsqlStatements.add(MAKE_node(Dsql::nod_class_stmtnode, 1)); - actionNode->dsqlStatements.front()->nod_arg[0] = reinterpret_cast<dsql_nod*>(exceptionNode); + actionNode->statements.add(exceptionNode); dsql_nod* actionNod = MAKE_node(Dsql::nod_class_stmtnode, 1); actionNod->nod_arg[0] = reinterpret_cast<dsql_nod*>(actionNode); @@ -7725,8 +7732,7 @@ ExceptionNode* exceptionNode = FB_NEW(pool) ExceptionNode(pool, CHECK_CONSTRAINT_EXCEPTION); exceptionNode->exception->type = ExceptionItem::GDS_CODE; - actionNode->dsqlStatements.add(MAKE_node(Dsql::nod_class_stmtnode, 1)); - actionNode->dsqlStatements.front()->nod_arg[0] = reinterpret_cast<dsql_nod*>(exceptionNode); + actionNode->statements.add(exceptionNode); // Create the UPDATE trigger. @@ -7843,10 +7849,10 @@ // Generate the action statements for the trigger. - dsql_nod** ptr = actions->dsqlStatements.begin(); + NestConst<StmtNode>* ptr = actions->statements.begin(); - for (const dsql_nod* const* const end = actions->dsqlStatements.end(); ptr != end; ++ptr) - GEN_statement(dsqlScratch, PASS1_statement(dsqlScratch, *ptr)); + for (const NestConst<StmtNode>* const end = actions->statements.end(); ptr != end; ++ptr) + (*ptr)->dsqlPass(dsqlScratch)->genBlr(dsqlScratch); dsqlScratch->appendUChar(blr_end); // of begin dsqlScratch->appendUChar(blr_eoc); Modified: firebird/trunk/src/dsql/DdlNodes.h =================================================================== --- firebird/trunk/src/dsql/DdlNodes.h 2011-03-06 01:06:36 UTC (rev 52517) +++ firebird/trunk/src/dsql/DdlNodes.h 2011-03-06 02:48:34 UTC (rev 52518) @@ -288,7 +288,7 @@ TypeClause returnType; NestConst<CompoundStmtNode> localDeclList; Firebird::string source; - dsql_nod* body; + NestConst<StmtNode> body; bool compiled; bool invalid; Firebird::MetaName package; @@ -392,7 +392,7 @@ Firebird::Array<ParameterClause> returns; Firebird::string source; NestConst<CompoundStmtNode> localDeclList; - dsql_nod* body; + NestConst<StmtNode> body; bool compiled; bool invalid; Firebird::MetaName package; @@ -553,7 +553,7 @@ bool create; bool alter; NestConst<CompoundStmtNode> localDeclList; - dsql_nod* body; + NestConst<StmtNode> body; bool compiled; bool invalid; }; Modified: firebird/trunk/src/dsql/DsqlCompilerScratch.cpp =================================================================== --- firebird/trunk/src/dsql/DsqlCompilerScratch.cpp 2011-03-06 01:06:36 UTC (rev 52517) +++ firebird/trunk/src/dsql/DsqlCompilerScratch.cpp 2011-03-06 02:48:34 UTC (rev 52518) @@ -243,29 +243,34 @@ } // Emit dyn for the local variables declared in a procedure or trigger. -void DsqlCompilerScratch::putLocalVariables(const CompoundStmtNode* parameters, USHORT locals) +void DsqlCompilerScratch::putLocalVariables(CompoundStmtNode* parameters, USHORT locals) { if (!parameters) return; - dsql_nod* const* ptr = parameters->dsqlStatements.begin(); + NestConst<StmtNode>* ptr = parameters->statements.begin(); - for (const dsql_nod* const* const end = parameters->dsqlStatements.end(); ptr != end; ++ptr) + for (const NestConst<StmtNode>* const end = parameters->statements.end(); ptr != end; ++ptr) { - dsql_nod* parameter = *ptr; + StmtNode* parameter = *ptr; - putDebugSrcInfo(parameter->nod_line, parameter->nod_column); + putDebugSrcInfo(parameter->line, parameter->column); - if (parameter->nod_type == Dsql::nod_def_field) + const DeclareVariableNode* varNode; + + if ((varNode = parameter->as<DeclareVariableNode>())) { - dsql_fld* field = (dsql_fld*) parameter->nod_arg[Dsql::e_dfl_field]; - const dsql_nod* const* rest = ptr; + dsql_fld* field = varNode->dsqlDef->legacyField; + const NestConst<StmtNode>* rest = ptr; while (++rest != end) { - if ((*rest)->nod_type == Dsql::nod_def_field) + const DeclareVariableNode* varNode2; + + if ((varNode2 = (*rest)->as<DeclareVariableNode>())) { - const dsql_fld* rest_field = (dsql_fld*) (*rest)->nod_arg[Dsql::e_dfl_field]; + dsql_fld* rest_field = varNode2->dsqlDef->legacyField; + if (field->fld_name == rest_field->fld_name) { ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-637) << @@ -274,10 +279,10 @@ } } - dsql_var* variable = makeVariable(field, field->fld_name.c_str(), dsql_var::TYPE_LOCAL, 0, 0, locals); + dsql_var* variable = makeVariable(field, field->fld_name.c_str(), dsql_var::TYPE_LOCAL, + 0, 0, locals); - putLocalVariable(variable, parameter, - reinterpret_cast<const dsql_str*>(parameter->nod_arg[Dsql::e_dfl_collate])); + putLocalVariable(variable, varNode, varNode->dsqlDef->collate); // Some field attributes are calculated inside putLocalVariable(), so we reinitialize // the descriptor. @@ -287,15 +292,15 @@ } else if (StmtNode::is<DeclareCursorNode>(parameter)) { - PASS1_statement(this, parameter); - GEN_statement(this, parameter); + parameter->dsqlPass(this); + parameter->genBlr(this); } } } // Write out local variable field data type. -void DsqlCompilerScratch::putLocalVariable(dsql_var* variable, dsql_nod* hostParam, - const dsql_str* collationName) +void DsqlCompilerScratch::putLocalVariable(dsql_var* variable, const DeclareVariableNode* hostParam, + const MetaName& collationName) { dsql_fld* field = variable->field; @@ -309,7 +314,7 @@ //field->fld_dtype = dtype; // Check for a default value, borrowed from define_domain - dsql_nod* node = hostParam ? hostParam->nod_arg[Dsql::e_dfl_default] : NULL; + dsql_nod* node = hostParam ? hostParam->dsqlDef->legacyDefault : NULL; if (node || (!field->fld_full_domain && !field->fld_not_nullable)) { Modified: firebird/trunk/src/dsql/DsqlCompilerScratch.h =================================================================== --- firebird/trunk/src/dsql/DsqlCompilerScratch.h 2011-03-06 01:06:36 UTC (rev 52517) +++ firebird/trunk/src/dsql/DsqlCompilerScratch.h 2011-03-06 02:48:34 UTC (rev 52518) @@ -36,6 +36,7 @@ class CompoundStmtNode; class DeclareCursorNode; +class DeclareVariableNode; class TypeClause; class VariableNode; @@ -156,8 +157,9 @@ void putDtype(const dsql_fld* field, bool useSubType); void putType(const TypeClause& type, bool useSubType); - void putLocalVariables(const CompoundStmtNode* parameters, USHORT locals); - void putLocalVariable(dsql_var* variable, dsql_nod* hostParam, const dsql_str* collationName); + void putLocalVariables(CompoundStmtNode* parameters, USHORT locals); + void putLocalVariable(dsql_var* variable, const DeclareVariableNode* hostParam, + const Firebird::MetaName& collationName); dsql_var* makeVariable(dsql_fld*, const char*, const dsql_var::Type type, USHORT, USHORT, USHORT); dsql_var* resolveVariable(const dsql_str* varName); void genReturn(bool eosFlag = false); Modified: firebird/trunk/src/dsql/StmtNodes.cpp =================================================================== --- firebird/trunk/src/dsql/StmtNodes.cpp 2011-03-06 01:06:36 UTC (rev 52517) +++ firebird/trunk/src/dsql/StmtNodes.cpp 2011-03-06 02:48:34 UTC (rev 52518) @@ -69,13 +69,11 @@ static dsql_ctx* dsqlGetContext(const dsql_nod* node); static void dsqlGetContexts(DsqlContextStack& contexts, const dsql_nod* node); static StmtNode* dsqlNullifyReturning(DsqlCompilerScratch*, StmtNode* input, bool returnList); -static void dsqlFieldAppearsOnce(const dsql_nod* const*, size_t, const dsql_nod* const*, - const bool, const char*); -static void dsqlFieldDuplication(const TEXT*, const TEXT*, const dsql_nod*, const char*); +static void dsqlFieldAppearsOnce(const Array<dsql_nod*>&, const char*); static dsql_ctx* dsqlPassCursorContext(DsqlCompilerScratch*, const dsql_nod*, const dsql_nod*); static dsql_nod* dsqlPassCursorReference(DsqlCompilerScratch*, const dsql_nod*, dsql_nod*); static dsql_nod* dsqlPassHiddenVariable(DsqlCompilerScratch* dsqlScratch, dsql_nod* expr); -static dsql_nod* dsqlProcessReturning(DsqlCompilerScratch*, dsql_nod*); +static StmtNode* dsqlProcessReturning(DsqlCompilerScratch*, dsql_nod*); static void dsqlSetParameterName(dsql_nod*, const dsql_nod*, const dsql_rel*); static void dsqlSetParametersName(CompoundStmtNode*, const dsql_nod*); @@ -171,19 +169,19 @@ } // Process the RETURNING clause. - dsql_nod* process(dsql_nod* node) + StmtNode* process(dsql_nod* node) { return dsqlProcessReturning(scratch, node); } // Clone a RETURNING node without create duplicate parameters. - static dsql_nod* clone(DsqlCompilerScratch* scratch, dsql_nod* unprocessed, dsql_nod* processed) + static dsql_nod* clone(DsqlCompilerScratch* scratch, dsql_nod* unprocessed, StmtNode* processed) { if (!processed) return unprocessed; // nod_returning was already processed - CompoundStmtNode* processedStmt = StmtNode::as<CompoundStmtNode>(processed); + CompoundStmtNode* processedStmt = processed->as<CompoundStmtNode>(); fb_assert(processed); // And we create a RETURNING node where the targets are already processed. @@ -191,7 +189,7 @@ FB_NEW(scratch->getPool()) CompoundStmtNode(scratch->getPool()); dsql_nod** srcPtr = unprocessed->nod_arg[Dsql::e_ret_source]->nod_arg; - dsql_nod** dstPtr = processedStmt->dsqlStatements.begin(); + NestConst<StmtNode>* dstPtr = processedStmt->statements.begin(); for (const dsql_nod* const* const end = srcPtr + unprocessed->nod_arg[Dsql::e_ret_source]->nod_count; srcPtr != end; @@ -199,10 +197,8 @@ { AssignmentNode* temp = FB_NEW(scratch->getPool()) AssignmentNode(scratch->getPool()); temp->dsqlAsgnFrom = *srcPtr; - temp->dsqlAsgnTo = StmtNode::as<AssignmentNode>(*dstPtr)->dsqlAsgnTo; - - newNode->dsqlStatements.add(MAKE_node(Dsql::nod_class_stmtnode, 1)); - newNode->dsqlStatements.back()->nod_arg[0] = reinterpret_cast<dsql_nod*>(temp); + temp->dsqlAsgnTo = (*dstPtr)->as<AssignmentNode>()->dsqlAsgnTo; + newNode->statements.add(temp); } dsql_nod* newNod = MAKE_node(Dsql::nod_class_stmtnode, 1); @@ -422,9 +418,7 @@ if (!handlers && !dsqlScratch->errorHandlers) { CompoundStmtNode* node = FB_NEW(getPool()) CompoundStmtNode(getPool()); - node->dsqlStatements.add(MAKE_node(Dsql::nod_class_stmtnode, 1)); - node->dsqlStatements.front()->nod_arg[0] = reinterpret_cast<dsql_nod*>( - action->dsqlPass(dsqlScratch)); + node->statements.add(action->dsqlPass(dsqlScratch)); return node; } @@ -456,10 +450,10 @@ if (handlers) { - const dsql_nod* const* end = handlers->dsqlStatements.end(); + const NestConst<StmtNode>* const end = handlers->statements.end(); - for (dsql_nod** ptr = handlers->dsqlStatements.begin(); ptr != end; ++ptr) - GEN_statement(dsqlScratch, *ptr); + for (NestConst<StmtNode>* ptr = handlers->statements.begin(); ptr != end; ++ptr) + (*ptr)->genBlr(dsqlScratch); } dsqlScratch->appendUChar(blr_end); @@ -731,11 +725,11 @@ { CompoundStmtNode* node = FB_NEW(getPool()) CompoundStmtNode(getPool()); - for (dsql_nod** i = dsqlStatements.begin(); i != dsqlStatements.end(); ++i) + for (NestConst<StmtNode>* i = statements.begin(); i != statements.end(); ++i) { - dsql_nod* ptr = *i; - ptr = PASS1_statement(dsqlScratch, ptr); - node->dsqlStatements.add(ptr); + StmtNode* ptr = *i; + ptr = ptr->dsqlPass(dsqlScratch); + node->statements.add(ptr); } return node; @@ -750,8 +744,8 @@ { dsqlScratch->appendUChar(blr_begin); - for (dsql_nod** i = dsqlStatements.begin(); i != dsqlStatements.end(); ++i) - GEN_statement(dsqlScratch, *i); + for (NestConst<StmtNode>* i = statements.begin(); i != statements.end(); ++i) + (*i)->genBlr(dsqlScratch); dsqlScratch->appendUChar(blr_end); } @@ -1372,7 +1366,7 @@ if (cursor && dsqlScratch->isPsql()) { node->dsqlContext = dsqlPassCursorContext(dsqlScratch, cursor, relation); - node->dsqlStatement = dsqlProcessReturning(dsqlScratch, dsqlReturning); + node->statement = dsqlProcessReturning(dsqlScratch, dsqlReturning); return SavepointEncloseNode::make(getPool(), dsqlScratch, node); } @@ -1416,7 +1410,7 @@ node->dsqlRse = rseNod; node->dsqlRelation = ExprNode::as<RseNode>(rseNod)->dsqlStreams->nod_arg[0]; - node->dsqlStatement = dsqlProcessReturning(dsqlScratch, dsqlReturning); + node->statement = dsqlProcessReturning(dsqlScratch, dsqlReturning); StmtNode* ret = dsqlNullifyReturning(dsqlScratch, node, true); @@ -1439,10 +1433,10 @@ { context = dsqlContext; - if (dsqlStatement) + if (statement) { dsqlScratch->appendUChar(blr_begin); - GEN_statement(dsqlScratch, dsqlStatement); + statement->genBlr(dsqlScratch); dsqlScratch->appendUChar(blr_erase); GEN_stuff_context(dsqlScratch, context); dsqlScratch->appendUChar(blr_end); @@ -1458,10 +1452,10 @@ dsql_nod* temp = dsqlRelation; context = ExprNode::as<RelationSourceNode>(temp)->dsqlContext; - if (dsqlStatement) + if (statement) { dsqlScratch->appendUChar(blr_begin); - GEN_statement(dsqlScratch, dsqlStatement); + statement->genBlr(dsqlScratch); dsqlScratch->appendUChar(blr_erase); GEN_stuff_context(dsqlScratch, context); dsqlScratch->appendUChar(blr_end); @@ -1819,7 +1813,7 @@ { ErrorHandlerNode* node = FB_NEW(getPool()) ErrorHandlerNode(getPool()); node->conditions = conditions; - node->dsqlAction = PASS1_statement(dsqlScratch, dsqlAction); + node->action = action->dsqlPass(dsqlScratch); return node; } @@ -1862,7 +1856,7 @@ } } - GEN_statement(dsqlScratch, dsqlAction); + action->genBlr(dsqlScratch); } ErrorHandlerNode* ErrorHandlerNode::pass1(thread_db* tdbb, CompilerScratch* csb) @@ -2445,11 +2439,11 @@ node->dsqlOutputs = PASS1_node(dsqlScratch, dsqlOutputs); - if (dsqlInnerStmt) + if (innerStmt) { ++dsqlScratch->loopLevel; node->dsqlLabel = PASS1_label(dsqlScratch, false, dsqlLabel); - node->dsqlInnerStmt = PASS1_statement(dsqlScratch, dsqlInnerStmt); + node->innerStmt = innerStmt->dsqlPass(dsqlScratch); --dsqlScratch->loopLevel; dsqlScratch->labels.pop(); } @@ -2473,7 +2467,7 @@ void ExecStatementNode::genBlr(DsqlCompilerScratch* dsqlScratch) { - if (dsqlInnerStmt) + if (innerStmt) { dsqlScratch->appendUChar(blr_label); dsqlScratch->appendUChar((int)(IPTR) dsqlLabel->nod_arg[Dsql::e_label_number]); @@ -2490,10 +2484,10 @@ GEN_expr(dsqlScratch, dsqlSql); - if (dsqlInnerStmt) + if (innerStmt) { dsqlScratch->appendUChar(0); // Non-singleton. - GEN_statement(dsqlScratch, dsqlInnerStmt); + innerStmt->genBlr(dsqlScratch); } else dsqlScratch->appendUChar(1); // Singleton. @@ -2529,10 +2523,10 @@ GEN_expr(dsqlScratch, dsqlSql); // Proc block body. - if (dsqlInnerStmt) + if (innerStmt) { dsqlScratch->appendUChar(blr_exec_stmt_proc_block); - GEN_statement(dsqlScratch, dsqlInnerStmt); + innerStmt->genBlr(dsqlScratch); } // External data source, user, password and role. @@ -2748,8 +2742,9 @@ { IfNode* node = FB_NEW(getPool()) IfNode(getPool()); node->dsqlCondition = PASS1_node(dsqlScratch, dsqlCondition); - node->dsqlTrueAction = PASS1_statement(dsqlScratch, dsqlTrueAction); - node->dsqlFalseAction = PASS1_statement(dsqlScratch, dsqlFalseAction); + node->trueAction = trueAction->dsqlPass(dsqlScratch); + if (falseAction) + node->falseAction = falseAction->dsqlPass(dsqlScratch); return node; } @@ -2757,18 +2752,16 @@ { text = "IfNode"; nodes.add(dsqlCondition); - nodes.add(dsqlTrueAction); - if (dsqlFalseAction) - nodes.add(dsqlFalseAction); } void IfNode::genBlr(DsqlCompilerScratch* dsqlScratch) { dsqlScratch->appendUChar(blr_if); GEN_expr(dsqlScratch, dsqlCondition); - GEN_statement(dsqlScratch, dsqlTrueAction); - if (dsqlFalseAction) - GEN_statement(dsqlScratch, dsqlFalseAction); + trueAction->genBlr(dsqlScratch); + + if (falseAction) + falseAction->genBlr(dsqlScratch); else dsqlScratch->appendUChar(blr_end); } @@ -2836,7 +2829,7 @@ dsqlScratch->flags |= DsqlCompilerScratch::FLAG_IN_AUTO_TRANS_BLOCK; InAutonomousTransactionNode* node = FB_NEW(getPool()) InAutonomousTransactionNode(getPool()); - node->dsqlAction = PASS1_statement(dsqlScratch, dsqlAction); + node->action = action->dsqlPass(dsqlScratch); if (!autoTrans) dsqlScratch->flags &= ~DsqlCompilerScratch::FLAG_IN_AUTO_TRANS_BLOCK; @@ -2847,14 +2840,13 @@ void InAutonomousTransactionNode::print(string& text, Array<dsql_nod*>& nodes) const { text = "InAutonomousTransactionNode"; - nodes.add(dsqlAction); } void InAutonomousTransactionNode::genBlr(DsqlCompilerScratch* dsqlScratch) { dsqlScratch->appendUChar(blr_auto_trans); dsqlScratch->appendUChar(0); // to extend syntax in the future - GEN_statement(dsqlScratch, dsqlAction); + action->genBlr(dsqlScratch); } InAutonomousTransactionNode* InAutonomousTransactionNode::pass1(thread_db* tdbb, CompilerScratch* csb) @@ -3216,8 +3208,6 @@ localDeclList->print(s, nodes); text += s + "\n"; } - - nodes.add(body); } void ExecBlockNode::genBlr(DsqlCompilerScratch* dsqlScratch) @@ -3327,7 +3317,7 @@ dsqlScratch->loopLevel = 0; - dsql_nod* stmtNode = PASS1_statement(dsqlScratch, body); + StmtNode* stmtNode = body->dsqlPass(dsqlScratch); GEN_hidden_variables(dsqlScratch); dsqlScratch->appendUChar(blr_stall); @@ -3336,7 +3326,7 @@ dsqlScratch->appendUChar(blr_label); dsqlScratch->appendUChar(0); - GEN_statement(dsqlScratch, stmtNode); + stmtNode->genBlr(dsqlScratch); if (returns.hasData()) statement->setType(DsqlCompiledStatement::TYPE_SELECT_BLOCK); @@ -3716,7 +3706,7 @@ return node; } -StmtNode* ForNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) +ForNode* ForNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { ForNode* node = FB_NEW(getPool()) ForNode(getPool()); @@ -3746,14 +3736,14 @@ } } - if (dsqlAction) + if (statement) { // CVC: Let's add the ability to BREAK the for_select same as the while, // but only if the command is FOR SELECT, otherwise we have singular SELECT - dsqlScratch->loopLevel++; + ++dsqlScratch->loopLevel; node->dsqlLabel = PASS1_label(dsqlScratch, false, dsqlLabel); - node->dsqlAction = PASS1_statement(dsqlScratch, dsqlAction); - dsqlScratch->loopLevel--; + node->statement = statement->dsqlPass(dsqlScratch); + --dsqlScratch->loopLevel; dsqlScratch->labels.pop(); } @@ -3772,7 +3762,6 @@ nodes.add(dsqlSelect); nodes.add(dsqlInto); nodes.add(dsqlCursor); - nodes.add(dsqlAction); nodes.add(dsqlLabel); } @@ -3780,7 +3769,7 @@ { // CVC: Only put a label if this is not singular; otherwise, // what loop is the user trying to abandon? - if (dsqlAction) + if (statement) { dsqlScratch->appendUChar(blr_label); dsqlScratch->appendUChar((int)(IPTR) dsqlLabel->nod_arg[Dsql::e_label_number]); @@ -3790,7 +3779,7 @@ dsqlScratch->appendUChar(blr_for); - if (!dsqlAction || dsqlForceSingular) + if (!statement || dsqlForceSingular) dsqlScratch->appendUChar(blr_singular); GEN_rse(dsqlScratch, dsqlSelect); @@ -3819,8 +3808,8 @@ } } - if (dsqlAction) - GEN_statement(dsqlScratch, dsqlAction); + if (statement) + statement->genBlr(dsqlScratch); dsqlScratch->appendUChar(blr_end); } @@ -4047,19 +4036,18 @@ void LineColumnNode::print(string& text, Array<dsql_nod*>& nodes) const { text.printf("LineColumnNode: line %d, col %d", line, column); - nodes.add(statement); } LineColumnNode* LineColumnNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - statement = PASS1_statement(dsqlScratch, statement); + statement = statement->dsqlPass(dsqlScratch); return this; } void LineColumnNode::genBlr(DsqlCompilerScratch* dsqlScratch) { dsqlScratch->putDebugSrcInfo(line, column); - GEN_statement(dsqlScratch, statement); + statement->genBlr(dsqlScratch); } @@ -4085,7 +4073,7 @@ // to preserve nesting <==> increasing level number. ++dsqlScratch->loopLevel; node->dsqlLabel = PASS1_label(dsqlScratch, false, dsqlLabel); - node->dsqlStatement = PASS1_statement(dsqlScratch, dsqlStatement); + node->statement = statement->dsqlPass(dsqlScratch); --dsqlScratch->loopLevel; dsqlScratch->labels.pop(); @@ -4105,7 +4093,7 @@ dsqlScratch->appendUChar(blr_begin); dsqlScratch->appendUChar(blr_if); GEN_expr(dsqlScratch, dsqlExpr); - GEN_statement(dsqlScratch, dsqlStatement); + statement->genBlr(dsqlScratch); dsqlScratch->appendUChar(blr_leave); dsqlScratch->appendUChar((UCHAR)(IPTR) dsqlLabel->nod_arg[Dsql::e_label_number]); dsqlScratch->appendUChar(blr_end); @@ -4161,7 +4149,7 @@ class MergeSendNode : public TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_MERGE_SEND> { public: - MergeSendNode(MemoryPool& pool, dsql_nod* aStmt) + MergeSendNode(MemoryPool& pool, StmtNode* aStmt) : TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_MERGE_SEND>(pool), stmt(aStmt) { @@ -4171,7 +4159,6 @@ virtual void print(string& text, Array<dsql_nod*>& nodes) const { text = "MergeSendNode"; - nodes.add(stmt); } // Do not make dsqlPass to process 'stmt'. It's already processed. @@ -4186,11 +4173,11 @@ dsqlScratch->appendUChar(message->msg_number); } - GEN_statement(dsqlScratch, stmt); + stmt->genBlr(dsqlScratch); } private: - dsql_nod* stmt; + StmtNode* stmt; }; thread_db* tdbb = JRD_get_thread_data(); @@ -4275,14 +4262,9 @@ // build a FOR SELECT node ForNode* forNode = FB_NEW(pool) ForNode(pool); forNode->dsqlSelect = select; - forNode->dsqlAction = MAKE_node(Dsql::nod_class_stmtnode, 1); - forNode->dsqlAction->nod_arg[0] = reinterpret_cast<dsql_nod*>( - FB_NEW(pool) CompoundStmtNode(pool)); + forNode->statement = FB_NEW(pool) CompoundStmtNode(pool); - dsql_nod* for_select = MAKE_node(Dsql::nod_class_stmtnode, 1); - for_select->nod_arg[0] = (dsql_nod*) forNode; - for_select = PASS1_statement(dsqlScratch, for_select); - forNode = (ForNode*) for_select->nod_arg[0]; + forNode = forNode->dsqlPass(dsqlScratch); if (dsqlReturning) forNode->dsqlForceSingular = true; @@ -4296,8 +4278,8 @@ DsqlContextStack usingCtxs; dsqlGetContexts(usingCtxs, source); - dsql_nod* update = NULL; - dsql_nod* matchedRet = NULL; + StmtNode* update = NULL; + StmtNode* matchedRet = NULL; StmtNode* nullRet = NULL; if (dsqlWhenMatchedPresent && dsqlWhenMatchedAssignments) @@ -4307,9 +4289,9 @@ Array<dsql_nod*> org_values, new_values; // Separate the new and org values to process in correct contexts. - for (size_t i = 0; i < stmts->dsqlStatements.getCount(); ++i) + for (size_t i = 0; i < stmts->statements.getCount(); ++i) { - const AssignmentNode* const assign = StmtNode::as<AssignmentNode>(stmts->dsqlStatements[i]); + const AssignmentNode* const assign = stmts->statements[i]->as<AssignmentNode>(); fb_assert(assign); org_values.add(assign->dsqlAsgnFrom); new_values.add(assign->dsqlAsgnTo); @@ -4360,7 +4342,7 @@ mod_context->ctx_scope_level = old_context->ctx_scope_level; - matchedRet = modify->dsqlStatement2 = ReturningProcessor( + matchedRet = modify->statement2 = ReturningProcessor( dsqlScratch, old_context, mod_context).process(dsqlReturning); nullRet = dsqlNullifyReturning(dsqlScratch, modify, false); @@ -4372,10 +4354,13 @@ } // Recreate the list of assignments. - modify->dsqlStatement = FB_NEW(pool) CompoundStmtNode(pool); - modify->dsqlStatement->dsqlStatements.resize(stmts->dsqlStatements.getCount()); - for (int i = 0; i < modify->dsqlStatement->dsqlStatements.getCount(); ++i) + CompoundStmtNode* assignStatements = FB_NEW(pool) CompoundStmtNode(pool); + modify->statement = assignStatements; + + assignStatements->statements.resize(stmts->statements.getCount()); + + for (size_t i = 0; i < assignStatements->statements.getCount(); ++i) { if (!PASS1_set_parameter_type(dsqlScratch, org_values[i], new_values[i], false)) PASS1_set_parameter_type(dsqlScratch, new_values[i], org_values[i], false); @@ -4383,17 +4368,13 @@ AssignmentNode* assign = FB_NEW(pool) AssignmentNode(pool); assign->dsqlAsgnFrom = org_values[i]; assign->dsqlAsgnTo = new_values[i]; - modify->dsqlStatement->dsqlStatements[i] = MAKE_node(Dsql::nod_class_stmtnode, 1); - modify->dsqlStatement->dsqlStatements[i]->nod_arg[0] = reinterpret_cast<dsql_nod*>(assign); + assignStatements->statements[i] = assign; } // We do not allow cases like UPDATE SET f1 = v1, f2 = v2, f1 = v3... - dsqlFieldAppearsOnce(modify->dsqlStatement->dsqlStatements.begin(), - modify->dsqlStatement->dsqlStatements.getCount(), - dsqlWhenMatchedAssignments->dsqlStatements.begin(), false, "MERGE"); + dsqlFieldAppearsOnce(new_values, "MERGE"); - update = MAKE_node(Dsql::nod_class_stmtnode, 1); - update->nod_arg[0] = reinterpret_cast<dsql_nod*>(modify); + update = modify; } else if (dsqlWhenMatchedPresent && !dsqlWhenMatchedAssignments) { @@ -4411,7 +4392,7 @@ dsqlScratch->context->push(context); // process old context values - matchedRet = erase->dsqlStatement = ReturningProcessor( + matchedRet = erase->statement = ReturningProcessor( dsqlScratch, context, NULL).process(dsqlReturning); nullRet = dsqlNullifyReturning(dsqlScratch, erase, false); @@ -4422,11 +4403,10 @@ --dsqlScratch->scopeLevel; } - update = MAKE_node(Dsql::nod_class_stmtnode, 1); - update->nod_arg[0] = reinterpret_cast<dsql_nod*>(erase); + update = erase; } - dsql_nod* insert = NULL; + StmtNode* insert = NULL; if (dsqlWhenNotMatchedPresent) { @@ -4460,7 +4440,7 @@ dsql_ctx* context = dsqlGetContext(store->dsqlRelation); context->ctx_scope_level = old_context->ctx_scope_level; - store->dsqlStatement2 = ReturningProcessor( + store->statement2 = ReturningProcessor( dsqlScratch, old_context, context).process(insRet); if (!matchedRet) @@ -4473,8 +4453,7 @@ dsqlScratch->context->pop(); --dsqlScratch->scopeLevel; - insert = MAKE_node(Dsql::nod_class_stmtnode, 1); - insert->nod_arg[0] = reinterpret_cast<dsql_nod*>(store); + insert = store; } MissingBoolNode* missingNode = FB_NEW(pool) MissingBoolNode( @@ -4492,8 +4471,8 @@ if (insert) { - action->dsqlTrueAction = insert; // then INSERT - action->dsqlFalseAction = update; // else UPDATE/DELETE + action->trueAction = insert; // then INSERT + action->falseAction = update; // else UPDATE/DELETE } else { @@ -4504,7 +4483,7 @@ action->dsqlCondition = MAKE_node(Dsql::nod_class_exprnode, 1); action->dsqlCondition->nod_arg[0] = reinterpret_cast<dsql_nod*>(notNode); - action->dsqlTrueAction = update; // then UPDATE/DELETE + action->trueAction = update; // then UPDATE/DELETE } if (!dsqlScratch->isPsql()) @@ -4519,23 +4498,21 @@ } // Insert the IF inside the FOR SELECT. - forNode->dsqlAction = MAKE_node(Dsql::nod_class_stmtnode, 1); - forNode->dsqlAction->nod_arg[0] = reinterpret_cast<dsql_nod*>(action); + forNode->statement = action; + StmtNode* mergeStmt = forNode; + // Setup the main node. if (nullRet) { CompoundStmtNode* temp = FB_NEW(pool) CompoundStmtNode(pool); - temp->dsqlStatements.add(MAKE_node(Dsql::nod_class_stmtnode, 1)); - temp->dsqlStatements.back()->nod_arg[0] = reinterpret_cast<dsql_nod*>(nullRet); - temp->dsqlStatements.add(for_select); - - for_select = MAKE_node(Dsql::nod_class_stmtnode, 1); - for_select->nod_arg[0] = reinterpret_cast<dsql_nod*>(temp); + temp->statements.add(nullRet); + temp->statements.add(forNode); + mergeStmt = temp; } - StmtNode* sendNode = (FB_NEW(pool) MergeSendNode(pool, for_select))->dsqlPass(dsqlScratch); + StmtNode* sendNode = (FB_NEW(pool) MergeSendNode(pool, mergeStmt))->dsqlPass(dsqlScratch); return SavepointEncloseNode::make(getPool(), dsqlScratch, sendNode); } @@ -4719,11 +4696,12 @@ Array<dsql_nod*> org_values, new_values; - CompoundStmtNode* assignments = dsqlStatement; + CompoundStmtNode* assignments = statement->as<CompoundStmtNode>(); + fb_assert(assignments); - for (size_t i = 0; i < assignments->dsqlStatements.getCount(); ++i) + for (size_t i = 0; i < assignments->statements.getCount(); ++i) { - const AssignmentNode* const assign = StmtNode::as<AssignmentNode>(assignments->dsqlStatements[i]); + const AssignmentNode* const assign = assignments->statements[i]->as<AssignmentNode>(); fb_assert(assign); org_values.add(assign->dsqlAsgnFrom); new_values.add(assign->dsqlAsgnTo); @@ -4766,28 +4744,27 @@ for (ptr = new_values.begin(); ptr != new_values.end(); ++ptr) *ptr = PASS1_node_psql(dsqlScratch, *ptr, false); - node->dsqlStatement2 = dsqlProcessReturning(dsqlScratch, dsqlReturning); + node->statement2 = dsqlProcessReturning(dsqlScratch, dsqlReturning); dsqlScratch->context->pop(); // Recreate list of assignments. - node->dsqlStatement = FB_NEW(pool) CompoundStmtNode(pool); - node->dsqlStatement->dsqlStatements.resize(assignments->dsqlStatements.getCount()); + CompoundStmtNode* assignStatements = FB_NEW(pool) CompoundStmtNode(pool); + node->statement = assignStatements; - for (int i = 0; i < node->dsqlStatement->dsqlStatements.getCount(); ++i) + assignStatements->statements.resize(assignments->statements.getCount()); + + for (size_t i = 0; i < assignStatements->statements.getCount(); ++i) { AssignmentNode* assign = FB_NEW(pool) AssignmentNode(pool); assign->dsqlAsgnFrom = org_values[i]; assign->dsqlAsgnTo = new_values[i]; - node->dsqlStatement->dsqlStatements[i] = MAKE_node(Dsql::nod_class_stmtnode, 1); - node->dsqlStatement->dsqlStatements[i]->nod_arg[0] = reinterpret_cast<dsql_nod*>(assign); + assignStatements->statements[i] = assign; } // We do not allow cases like UPDATE T SET f1 = v1, f2 = v2, f1 = v3... - dsqlFieldAppearsOnce(node->dsqlStatement->dsqlStatements.begin(), - node->dsqlStatement->dsqlStatements.getCount(), - dsqlStatement->dsqlStatements.begin(), false, "UPDATE"); + dsqlFieldAppearsOnce(new_values, "UPDATE"); return node; } @@ -4850,7 +4827,7 @@ if (dsqlReturning) { - node->dsqlStatement2 = ReturningProcessor( + node->statement2 = ReturningProcessor( dsqlScratch, old_context, mod_context).process(dsqlReturning); } } @@ -4868,10 +4845,12 @@ // Recreate list of assignments. - node->dsqlStatement = FB_NEW(pool) CompoundStmtNode(pool); - node->dsqlStatement->dsqlStatements.resize(assignments->dsqlStatements.getCount()); + CompoundStmtNode* assignStatements = FB_NEW(pool) CompoundStmtNode(pool); + node->statement = assignStatements; - for (size_t j = 0; j < node->dsqlStatement->dsqlStatements.getCount(); ++j) + assignStatements->statements.resize(assignments->statements.getCount()); + + for (size_t j = 0; j < assignStatements->statements.getCount(); ++j) { dsql_nod* const sub1 = org_values[j]; dsql_nod* const sub2 = new_values[j]; @@ -4882,16 +4861,13 @@ AssignmentNode* assign = FB_NEW(pool) AssignmentNode(pool); assign->dsqlAsgnFrom = sub1; assign->dsqlAsgnTo = sub2; - node->dsqlStatement->dsqlStatements[j] = MAKE_node(Dsql::nod_class_stmtnode, 1); - node->dsqlStatement->dsqlStatements[j]->nod_arg[0] = reinterpret_cast<dsql_nod*>(assign); + assignStatements->statements[j] = assign; } // We do not allow cases like UPDATE T SET f1 = v1, f2 = v2, f1 = v3... - dsqlFieldAppearsOnce(node->dsqlStatement->dsqlStatements.begin(), - node->dsqlStatement->dsqlStatements.getCount(), - dsqlStatement->dsqlStatements.begin(), false, "UPDATE"); + dsqlFieldAppearsOnce(new_values, "UPDATE"); - dsqlSetParametersName(node->dsqlStatement, node->dsqlRelation); + dsqlSetParametersName(assignStatements, node->dsqlRelation); StmtNode* ret = node; if (!updateOrInsert) @@ -4914,7 +4890,7 @@ { const dsql_msg* message = dsqlGenDmlHeader(dsqlScratch, dsqlRse); - dsqlScratch->appendUChar(dsqlStatement2 ? blr_modify2 : blr_modify); + dsqlScratch->appendUChar(statement2 ? blr_modify2 : blr_modify); const dsql_ctx* context; dsql_nod* temp; @@ -4931,10 +4907,10 @@ temp = dsqlRelation; context = ExprNode::as<RelationSourceNode>(temp)->dsqlContext; GEN_stuff_context(dsqlScratch, context); - dsqlStatement->genBlr(dsqlScratch); + statement->genBlr(dsqlScratch); - if (dsqlStatement2) - GEN_statement(dsqlScratch, dsqlStatement2); + if (statement2) + statement2->genBlr(dsqlScratch); if (message) dsqlScratch->appendUChar(blr_end); @@ -5562,10 +5538,18 @@ { const dsql_nod* old_fields = fields; // for error reporting. fields = PASS1_node_psql(dsqlScratch, fields, false); - // We do not allow cases like INSERT INTO T(f1, f2, f1)... - dsqlFieldAppearsOnce(fields->nod_arg, fields->nod_count, - old_fields->nod_arg, true, "INSERT"); + // We do not allow cases like INSERT INTO T (f1, f2, f1)... + { // scope + Array<dsql_nod*> newValues; + + // Separate the new and org values to process in correct contexts. + for (USHORT i = 0; i < fields->nod_count; ++i) + newValues.add(fields->nod_arg[i]); + + dsqlFieldAppearsOnce(newValues, "INSERT"); + } // scope + // begin IBO hack // 02-May-2004, Nickolay Samofatov. Do not constify ptr further e.g. to // const dsql_nod* const* .... etc. It chokes GCC 3.4.0 @@ -5612,7 +5596,8 @@ // Match field fields and values - node->dsqlStatement = FB_NEW(getPool()) CompoundStmtNode(getPool()); + CompoundStmtNode* assignStatements = FB_NEW(getPool()) CompoundStmtNode(getPool()); + node->statement = assignStatements; if (values) { @@ -5633,8 +5618,7 @@ AssignmentNode* temp = FB_NEW(getPool()) AssignmentNode(getPool()); temp->dsqlAsgnFrom = *ptr2; temp->dsqlAsgnTo = *ptr; - node->dsqlStatement->dsqlStatements.add(MAKE_node(Dsql::nod_class_stmtnode, 1)); - node->dsqlStatement->dsqlStatements.back()->nod_arg[0] = reinterpret_cast<dsql_nod*>(temp); + assignStatements->statements.add(temp); PASS1_set_parameter_type(dsqlScratch, *ptr2, *ptr, false); } @@ -5659,7 +5643,7 @@ dsqlScratch->context->push(new_context); } - node->dsqlStatement2 = dsqlProcessReturning(dsqlScratch, dsqlReturning); + node->statement2 = dsqlProcessReturning(dsqlScratch, dsqlReturning); if (updateOrInsert) { @@ -5668,7 +5652,7 @@ dsqlScratch->context->pop(); } - dsqlSetParametersName(node->dsqlStatement, node->dsqlRelation); + dsqlSetParametersName(assignStatements, node->dsqlRelation); StmtNode* ret = node; if (!updateOrInsert) @@ -5693,12 +5677,12 @@ { const dsql_msg* message = dsqlGenDmlHeader(dsqlScratch, dsqlRse); - dsqlScratch->appendUChar(dsqlStatement2 ? blr_store2 : blr_store); + dsqlScratch->appendUChar(statement2 ? blr_store2 : blr_store); GEN_expr(dsqlScratch, dsqlRelation); - dsqlStatement->genBlr(dsqlScratch); + statement->genBlr(dsqlScratch); - if (dsqlStatement2) - GEN_statement(dsqlScratch, dsqlStatement2); + if (statement2) + statement2->genBlr(dsqlScratch); if (message) dsqlScratch->appendUChar(blr_end); @@ -6804,8 +6788,15 @@ --dsqlScratch->scopeLevel; dsqlScratch->context->pop(); - dsqlFieldAppearsOnce(matching_fields->nod_arg, matching_fields->nod_count, - matching->nod_arg, true, "UPDATE OR INSERT"); + { // scope + Array<dsql_nod*> newValues; + + // Separate the new and org values to process in correct contexts. + for (USHORT i = 0; i < matching_fields->nod_count; ++i) + newValues.add(matching_fields->nod_arg[i]); + + dsqlFieldAppearsOnce(newValues, "UPDATE OR INSERT"); + } // scope } else { @@ -6821,12 +6812,15 @@ dsql_nod* match = NULL; USHORT match_count = 0; - DsqlNodStack varStack; + CompoundStmtNode* list = FB_NEW(pool) CompoundStmtNode(pool); CompoundStmtNode* assignments = FB_NEW(pool) CompoundStmtNode(pool); dsql_nod** field_ptr = fields->nod_arg; dsql_nod** value_ptr = values->nod_arg; + Array<NestConst<StmtNode> >& insertStatements = + insert->statement->as<CompoundStmtNode>()->statements; + for (const dsql_nod* const* const field_end = field_ptr + fields->nod_count; field_ptr < field_end; field_ptr++, value_ptr++) { @@ -6836,11 +6830,9 @@ AssignmentNode* assign = FB_NEW(pool) AssignmentNode(pool); assign->dsqlAsgnFrom = *value_ptr; assign->dsqlAsgnTo = *field_ptr; - assignments->dsqlStatements.add(MAKE_node(Dsql::nod_class_stmtnode, 1)); - assignments->dsqlStatements.back()->nod_arg[0] = reinterpret_cast<dsql_nod*>(assign); + assignments->statements.add(assign); - dsql_nod* temp = StmtNode::as<AssignmentNode>( - insert->dsqlStatement->dsqlStatements[field_ptr - fields->nod_arg])->dsqlAsgnTo; + dsql_nod* temp = insertStatements[field_ptr - fields->nod_arg]->as<AssignmentNode>()->dsqlAsgnTo; PASS1_set_parameter_type(dsqlScratch, *value_ptr, temp, false); fb_assert((*field_ptr)->nod_type == Dsql::nod_field_name); @@ -6877,8 +6869,7 @@ ++match_count; const size_t fieldPos = field_ptr - fields->nod_arg; - dsql_nod*& expr = StmtNode::as<AssignmentNode>( - insert->dsqlStatement->dsqlStatements[fieldPos])->dsqlAsgnFrom; + dsql_nod*& expr = insertStatements[fieldPos]->as<AssignmentNode>()->dsqlAsgnFrom; dsql_nod* var = dsqlPassHiddenVariable(dsqlScratch, expr); if (var) @@ -6887,11 +6878,8 @@ varAssign->dsqlAsgnFrom = expr; varAssign->dsqlAsgnTo = var; - dsql_nod* temp2 = MAKE_node(Dsql::nod_class_stmtnode, 1); - temp2->nod_arg[0] = reinterpret_cast<dsql_nod*>(varAssign); + list->statements.add(varAssign); - varStack.push(temp2); - assign->dsqlAsgnFrom = expr = var; } else @@ -6921,14 +6909,14 @@ // build the UPDATE node ModifyNode* update = FB_NEW(pool) ModifyNode(pool); update->dsqlRelation = dsqlRelation; - update->dsqlStatement = assignments; + update->statement = assignments; update->dsqlBoolean = match; if (dsqlReturning) { update->dsqlRseFlags = NOD_SELECT_EXPR_SINGLETON; - update->dsqlReturning = ReturningProcessor::clone(dsqlScratch, - dsqlReturning, insert->dsqlStatement2); + update->dsqlReturning = ReturningProcessor::clone( + dsqlScratch, dsqlReturning, insert->statement2); } update = update->internalDsqlPass(dsqlScratch, true)->as<ModifyNode>(); @@ -6953,20 +6941,13 @@ // If (ROW_COUNT = 0) then INSERT. IfNode* ifNode = FB_NEW(pool) IfNode(pool); ifNode->dsqlCondition = eqlNod; - ifNode->dsqlTrueAction = MAKE_node(Dsql::nod_class_stmtnode, 1); - ifNode->dsqlTrueAction->nod_arg[0] = reinterpret_cast<dsql_nod*>(insert); + ifNode->trueAction = insert; // Build the temporary vars / UPDATE / IF nodes. - CompoundStmtNode* list = FB_NEW(pool) CompoundStmtNode(pool); - while (varStack.hasData()) - list->dsqlStatements.add(varStack.pop()); + list->statements.add(update); + list->statements.add(ifNode); - list->dsqlStatements.add(MAKE_node(Dsql::nod_class_stmtnode, 1)); - list->dsqlStatements.back()->nod_arg[0] = (dsql_nod*) update; - list->dsqlStatements.add(MAKE_node(Dsql::nod_class_stmtnode, 1)); - list->dsqlStatements.back()->nod_arg[0] = (dsql_nod*) ifNode; - // If RETURNING is present, type is already DsqlCompiledStatement::TYPE_EXEC_PROCEDURE. if (!dsqlReturning) dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_INSERT); @@ -7156,17 +7137,17 @@ thread_db* tdbb = JRD_get_thread_data(); MemoryPool& pool = *tdbb->getDefaultPool(); - dsql_nod* returning = NULL; + StmtNode* returning = NULL; EraseNode* eraseNode; ModifyNode* modifyNode; StoreNode* storeNode; if (eraseNode = input->as<EraseNode>()) - returning = eraseNode->dsqlStatement; + returning = eraseNode->statement; else if (modifyNode = input->as<ModifyNode>()) - returning = modifyNode->dsqlStatement2; + returning = modifyNode->statement2; else if (storeNode = input->as<StoreNode>()) - returning = storeNode->dsqlStatement2; + returning = storeNode->statement2; else { fb_assert(false); @@ -7182,26 +7163,23 @@ // completely removed. // nod_returning was already processed - CompoundStmtNode* returningStmt = StmtNode::as<CompoundStmtNode>(returning); + CompoundStmtNode* returningStmt = returning->as<CompoundStmtNode>(); fb_assert(returningStmt); CompoundStmtNode* nullAssign = FB_NEW(pool) CompoundStmtNode(pool); - dsql_nod** ret_ptr = returningStmt->dsqlStatements.begin(); - dsql_nod** null_ptr = nullAssign->dsqlStatements.getBuffer(returningStmt->dsqlStatements.getCount()); - dsql_nod* temp; + NestConst<StmtNode>* ret_ptr = returningStmt->statements.begin(); + NestConst<StmtNode>* null_ptr = nullAssign->statements.getBuffer(returningStmt->statements.getCount()); - for (const dsql_nod* const* const end = ret_ptr + returningStmt->dsqlStatements.getCount(); + for (const NestConst<StmtNode>* const end = ret_ptr + returningStmt->statements.getCount(); ret_ptr != end; ++ret_ptr, ++null_ptr) { AssignmentNode* assign = FB_NEW(pool) AssignmentNode(pool); assign->dsqlAsgnFrom = MAKE_node(Dsql::nod_class_exprnode, 1); assign->dsqlAsgnFrom->nod_arg[0] = reinterpret_cast<dsql_nod*>(FB_NEW(pool) NullNode(pool)); - assign->dsqlAsgnTo = StmtNode::as<AssignmentNode>(*ret_ptr)->dsqlAsgnTo; - - *null_ptr = MAKE_node(Dsql::nod_class_stmtnode, 1); - (*null_ptr)->nod_arg[0] = reinterpret_cast<dsql_nod*>(assign); + assign->dsqlAsgnTo = (*ret_ptr)->as<AssignmentNode>()->dsqlAsgnTo; + *null_ptr = assign; } // If asked for, return a compound statement with the initialization and the @@ -7209,10 +7187,8 @@ if (returnList) { CompoundStmtNode* list = FB_NEW(pool) CompoundStmtNode(pool); - list->dsqlStatements.add(MAKE_node(Dsql::nod_class_stmtnode, 1)); - list->dsqlStatements.back()->nod_arg[0] = reinterpret_cast<dsql_nod*>(nullAssign); - list->dsqlStatements.add(MAKE_node(Dsql::nod_class_stmtnode, 1)); - list->dsqlStatements.back()->nod_arg[0] = reinterpret_cast<dsql_nod*>(input); + list->statements.add(nullAssign); + list->statements.add(input); return list; } else @@ -7220,71 +7196,39 @@ } // Check that a field is named only once in INSERT or UPDATE statements. -static void dsqlFieldAppearsOnce(const dsql_nod* const* fieldsArgs, size_t count, - const dsql_nod* const* oldFieldsArgs, const bool is_insert, const char* dsqlScratch) +static void dsqlFieldAppearsOnce(const Array<dsql_nod*>& values, const char* command) { - for (size_t i = 0; i < count; ++i) + for (size_t i = 0; i < values.getCount(); ++i) { - const dsql_nod* elem1 = fieldsArgs[i]; - const AssignmentNode* assign1 = StmtNode::as<AssignmentNode>(elem1); + const FieldNode* field1 = ExprNode::as<FieldNode>(values[i]); + fb_assert(field1); - if (assign1 && !is_insert) - elem1 = assign1->dsqlAsgnTo; + const MetaName& name1 = field1->dsqlField->fld_name; - const FieldNode* fieldNode1 = ExprNode::as<FieldNode>(elem1); - - if (fieldNode1) + for (size_t j = i + 1; j < values.getCount(); ++j) { - const MetaName& n1 = fieldNode1->dsqlField->fld_name; + const FieldNode* field2 = ExprNode::as<FieldNode>(values[j]); + fb_assert(field2); - for (int j = i + 1; j < count; ++j) + const MetaName& name2 = field2->dsqlField->fld_name; + + if (name1 == name2) { - const dsql_nod* elem2 = fieldsArgs[j]; - const AssignmentNode* assign2 = StmtNode::as<AssignmentNode>(elem2); + string str = field1->dsqlContext->ctx_relation->rel_name.c_str(); + str += "."; + str += name1.c_str(); - if (assign2 && !is_insert) - elem2 = assign2->dsqlAsgnTo; - - const FieldNode* fieldNode2 = ExprNode::as<FieldNode>(elem2); - - if (fieldNode2) - { - const MetaName& n2 = fieldNode2->dsqlField->fld_name; - - if (n1 == n2) - { - const dsql_ctx* tmp_ctx = fieldNode2->dsqlContext; - const dsql_rel* bad_rel = tmp_ctx ? tmp_ctx->ctx_relation : NULL; - dsqlFieldDuplication((bad_rel ? bad_rel->rel_name.c_str() : NULL), - n2.c_str(), - (is_insert ? oldFieldsArgs[j] : oldFieldsArgs[j]->nod_arg[1]), - dsqlScratch); - } - } + //// FIXME: line/column is not very accurate for MERGE ... INSERT. + ERRD_post( + Arg::Gds(isc_sqlerr) << Arg::Num(-206) << + Arg::Gds(isc_dsql_no_dup_name) << str << command << + Arg::Gds(isc_dsql_line_col_error) << + Arg::Num(values[j]->nod_line) << Arg::Num(values[j]->nod_column)); } } } } -// Report a field duplication error in INSERT or UPDATE statements. -static void dsqlFieldDuplication(const TEXT* qualifier_name, const TEXT* field_name, - const dsql_nod* flawed_node, const char* dsqlScratch) -{ - TEXT field_buffer[MAX_SQL_IDENTIFIER_SIZE * 2]; - - if (qualifier_name) - { - sprintf(field_buffer, "%.*s.%.*s", (int) MAX_SQL_IDENTIFIER_LEN, qualifier_name, - (int) MAX_SQL_IDENTIFIER_LEN, field_name); - field_name = field_buffer; - } - - ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-206) << - Arg::Gds(isc_dsql_no_dup_name) << Arg::Str(field_name) << Arg::Str(dsqlScratch) << - Arg::Gds(isc_dsql_line_col_error) << Arg::Num(flawed_node->nod_line) << - Arg::Num(flawed_node->nod_column)); -} - // Turn a cursor reference into a record selection expression. static dsql_ctx* dsqlPassCursorContext( DsqlCompilerScratch* dsqlScratch, const dsql_nod* cursor, const dsql_nod* relation_name) @@ -7516,14 +7460,17 @@ } // Compile a RETURNING clause (nod_returning or not). -static dsql_nod* dsqlProcessReturning(DsqlCompilerScratch* dsqlScratch, dsql_nod* input) +static StmtNode* dsqlProcessReturning(DsqlCompilerScratch* dsqlScratch, dsql_nod* input) { DEV_BLKCHK(dsqlScratch, dsql_type_req); DEV_BLKCHK(input, dsql_type_nod); + if (!input) + return NULL; + dsql_nod* node; - if (!input || input->nod_type == Dsql::nod_returning) + if (input->nod_type == Dsql::nod_returning) node = PASS1_node(dsqlScratch, input); else { @@ -7534,7 +7481,8 @@ if (input && !dsqlScratch->isPsql()) dsqlScratch->getStatement()->setType(DsqlCompiledStatement::TYPE_EXEC_PROCEDURE); - return node; + fb_assert(node->nod_type == Dsql::nod_class_stmtnode); + return reinterpret_cast<StmtNode*>(node->nod_arg[0]); } // Setup parameter parameter name. @@ -7608,19 +7556,19 @@ DEV_BLKCHK(context, dsql_type_ctx); const dsql_rel* relation = context->ctx_relation; - size_t count = statements->dsqlStatements.getCount(); - dsql_nod** ptr = statements->dsqlStatements.begin(); + size_t count = statements->statements.getCount(); + NestConst<StmtNode>* ptr = statements->statements.begin(); - for (const dsql_nod* const* const end = ptr + count; ptr != end; ++ptr) + for (const NestConst<StmtNode>* const end = ptr + count; ptr != end; ++ptr) { - DEV_BLKCHK(*ptr, dsql_type_nod); + const AssignmentNode* assign = (*ptr)->as<AssignmentNode>(); - AssignmentNode* assign = StmtNode::as<AssignmentNode>(*ptr); - if (assign) dsqlSetParameterName(assign->dsqlAsgnFrom, assign->dsqlAsgnTo, relation); else - fb_assert(FALSE); + { + fb_assert(false); + } } } Modified: firebird/trunk/src/dsql/StmtNodes.h =================================================================== --- firebird/trunk/src/dsql/StmtNodes.h 2011-03-06 01:06:36 UTC (rev 52517) +++ firebird/trunk/src/dsql/StmtNodes.h 2011-03-06 02:48:34 UTC (rev 52518) @@ -159,7 +159,6 @@ public: explicit CompoundStmtNode(MemoryPool& pool) : TypedNode<StmtNode, StmtNode::TYPE_COMPOUND_STMT>(pool), - dsqlStatements(pool), statements(pool), onlyAssignments(false) { @@ -177,7 +176,6 @@ virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; public: - Firebird::Array<dsql_nod*> dsqlStatements; Firebird::Array<NestConst<StmtNode> > statements; bool onlyAssignments; }; @@ -309,6 +307,7 @@ public: explicit DeclareVariableNode(MemoryPool& pool) : TypedNode<StmtNode, StmtNode::TYPE_DECLARE_VARIABLE>(pool), + dsqlDef(NULL), varId(0) { varDesc.clear(); @@ -326,6 +325,7 @@ virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; public: + NestConst<ParameterClause> dsqlDef; USHORT varId; dsc varDesc; }; @@ -337,7 +337,6 @@ explicit EraseNode(MemoryPool& pool) : TypedNode<StmtNode, StmtNode::TYPE_ERASE>(pool), dsqlRelation(NULL), - dsqlStatement(NULL), dsqlBoolean(NULL), dsqlPlan(NULL), dsqlSort(NULL), @@ -368,7 +367,6 @@ public: dsql_nod* dsqlRelation; - dsql_nod* dsqlStatement; dsql_nod* dsqlBoolean; dsql_nod* dsqlPlan; dsql_nod* dsqlSort; @@ -388,7 +386,6 @@ public: explicit ErrorHandlerNode(MemoryPool& pool) : TypedNode<StmtNode, StmtNode::TYPE_ERROR_HANDLER>(pool), - dsqlAction(NULL), action(NULL), conditions(pool) { @@ -405,7 +402,6 @@ virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; public: - dsql_nod* dsqlAction; NestConst<StmtNode> action; ExceptionArray conditions; }; @@ -469,7 +465,6 @@ dsqlUserName(NULL), dsqlPassword(NULL), dsqlRole(NULL), - dsqlInnerStmt(NULL), dsqlInputs(NULL), dsqlOutputs(NULL), dsqlLabel(NULL), @@ -509,7 +504,6 @@ dsql_nod* dsqlUserName; dsql_nod* dsqlPassword; dsql_nod* dsqlRole; - dsql_nod* dsqlInnerStmt; dsql_nod* dsqlInputs; dsql_nod* dsqlOutputs; dsql_nod* dsqlLabel; @@ -533,8 +527,6 @@ explicit IfNode(MemoryPool& pool) : TypedNode<StmtNode, StmtNode::TYPE_IF>(pool), dsqlCondition(NULL), - dsqlTrueAction(NULL), - dsqlFalseAction(NULL), condition(NULL), trueAction(NULL), falseAction(NULL) @@ -553,8 +545,6 @@ public: dsql_nod* dsqlCondition; - dsql_nod* dsqlTrueAction; - dsql_nod* dsqlFalseAction; NestConst<BoolExprNode> condition; NestConst<StmtNode> trueAction; NestConst<StmtNode> falseAction; @@ -566,7 +556,6 @@ public: explicit InAutonomousTransactionNode(MemoryPool& pool) : TypedNode<StmtNode, StmtNode::TYPE_IN_AUTO_TRANS>(pool), - dsqlAction(NULL), action(NULL), savNumberOffset(0) { @@ -583,7 +572,6 @@ virtual const StmtNode* execute(thread_db* tdbb, jrd_req* request, ExeState* exeState) const; public: - dsql_nod* dsqlAction; NestConst<StmtNode> action; SLONG savNumberOffset; }; @@ -641,7 +629,7 @@ Firebird::Array<ParameterClause> parameters; Firebird::Array<ParameterClause> returns; NestConst<CompoundStmtNode> localDeclList; - dsql_nod* body; + NestConst<StmtNode> body; }; @@ -715,7 +703,6 @@ dsqlSelect(NULL), dsqlInto(NULL), dsqlCursor(NULL), - dsqlAction(NULL), dsqlLabel(NULL), dsqlForceSingular(false), needSavePoint(false), @@ -730,7 +717,7 @@ static DmlNode* parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, UCHAR blrOp); virtual void print(Firebird::string& text, Firebird::Array<dsql_nod*>& nodes) const; - virtual StmtNode* dsqlPass(DsqlCompilerScratch* dsqlScratch); + 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); @@ -740,7 +727,6 @@ dsql_nod* dsqlSelect; dsql_nod* dsqlInto; dsql_nod* dsqlCursor; - dsql_nod* dsqlAction; dsql_nod* dsqlLabel; bool dsqlForceSingular; bool needSavePoint; @@ -804,7 +790,7 @@ class LineColumnNode : public TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_LINE_COLUMN> { public: - explicit LineColumnNode(MemoryPool& pool, USHORT aLine, USHORT aColumn, dsql_nod* aStatement) + explicit LineColumnNode(MemoryPool& pool, USHORT aLine, USHORT aColumn, StmtNode* aStatement) : TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_LINE_COLUMN>(pool), statement(aStatement) { @@ -818,7 +804,7 @@ virtual void genBlr(DsqlCompilerScratch* dsqlScratch); private: - dsql_nod* statement; + NestConst<StmtNode> statement; }; @@ -829,7 +815,6 @@ : TypedNode<StmtNode, StmtNode::TYPE_LOOP>(pool), dsqlLabel(NULL), dsqlExpr(NULL), - dsqlStatement(NULL), statement(NULL) { } @@ -847,7 +832,6 @@ public: dsql_nod* dsqlLabel; dsql_nod* dsqlExpr; - dsql_nod* dsqlStatement; NestConst<StmtNode> statement; }; @@ -925,8 +909,6 @@ explicit ModifyNode(MemoryPool& pool) : TypedNode<StmtNode, StmtNode::TYPE_MODIFY>(pool), dsqlRelation(NULL), - dsqlStatement(NULL), - dsqlStatement2(NULL), dsqlBoolean(NULL), dsqlPlan(NULL), dsqlSort(NULL), @@ -963,8 +945,6 @@ public: dsql_nod* dsqlRelation; - CompoundStmtNode* dsqlStatement; - dsql_nod* dsqlStatement2; dsql_nod* dsqlBoolean; dsql_nod* dsqlPlan; dsql_nod* dsqlSort; @@ -1048,8 +1028,6 @@ dsqlRelation(NULL), dsqlFields(NULL), dsqlValues(NULL), - dsqlStatement(NULL), - dsqlStatement2(NULL), dsqlReturning(NULL), dsqlRse(NULL), statement(NULL), @@ -1080,8 +1058,6 @@ dsql_nod* dsqlRelation; dsql_nod* dsqlFields; dsql_nod* dsqlValues; - CompoundStmtNode* dsqlStatement; - dsql_nod* dsqlStatement2; dsql_nod* dsqlReturning; dsql_nod* dsqlRse; NestConst<StmtNode> statement; Modified: firebird/trunk/src/dsql/ddl.cpp =================================================================== --- firebird/trunk/src/dsql/ddl.cpp 2011-03-06 01:06:36 UTC (rev 52517) +++ firebird/trunk/src/dsql/ddl.cpp 2011-03-06 02:48:34 UTC (rev 52518) @@ -273,16 +273,15 @@ // wrapper that sets the last parameter to false to indicate // we are creating a field, not modifying one. // -void DDL_resolve_intl_type(DsqlCompilerScratch* dsqlScratch, dsql_fld* field, const dsql_str* collation_name) +void DDL_resolve_intl_type(DsqlCompilerScratch* dsqlScratch, dsql_fld* field, + const MetaName& collation_name) { DDL_resolve_intl_type2(dsqlScratch, field, collation_name, false); } -void DDL_resolve_intl_type2(DsqlCompilerScratch* dsqlScratch, - dsql_fld* field, - const dsql_str* collation_name, - bool modifying) +void DDL_resolve_intl_type2(DsqlCompilerScratch* dsqlScratch, dsql_fld* field, + const MetaName& collation_name, bool modifying) { /************************************** * @@ -368,7 +367,7 @@ if ((field->fld_dtype > dtype_any_text) && field->fld_dtype != dtype_blob) { - if (field->fld_character_set || collation_name || field->fld_flags & FLD_national) + if (field->fld_character_set || collation_name.hasData() || field->fld_flags & FLD_national) { ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-204) << Arg::Gds(isc_dsql_datatype_err) << Arg::Gds(isc_collation_requires_text)); @@ -410,7 +409,7 @@ Arg::Gds(isc_collation_requires_text)); } - if (collation_name && (field->fld_sub_type != isc_blob_text)) + if (collation_name.hasData() && (field->fld_sub_type != isc_blob_text)) { ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-204) << Arg::Gds(isc_dsql_datatype_err) << @@ -421,7 +420,7 @@ return; } - if (field->fld_character_set_id != 0 && !collation_name) + if (field->fld_character_set_id != 0 && collation_name.isEmpty()) { // This field has already been resolved once, and the collation // hasn't changed. Therefore, no need to do it again. @@ -499,7 +498,7 @@ assign_field_length(field, 1); field->fld_ttype = 0; - if (!collation_name) + if (collation_name.isEmpty()) return; } } @@ -532,10 +531,10 @@ resolved_type = resolved_charset; } - if (collation_name) + if (collation_name.hasData()) { const dsql_intlsym* resolved_collation = METD_get_collation(dsqlScratch->getTransaction(), - collation_name->str_data, field->fld_character_set_id); + collation_name, field->fld_character_set_id); if (!resolved_collation) { @@ -552,8 +551,7 @@ // Specified collation not found ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Nu... [truncated message content] |