mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 16:03:03 +01:00
Started simplification of local declarations.
This commit is contained in:
parent
2d8f94862b
commit
bf72356edb
@ -1664,26 +1664,7 @@ DdlNode* CreateAlterFunctionNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
||||
{
|
||||
dsqlScratch->flags |= (DsqlCompilerScratch::FLAG_BLOCK | DsqlCompilerScratch::FLAG_FUNCTION);
|
||||
|
||||
// check for duplicated parameters and declaration names
|
||||
|
||||
StrArray names;
|
||||
|
||||
for (FB_SIZE_T i = 0; i < parameters.getCount(); ++i)
|
||||
{
|
||||
const ParameterClause* const parameter = parameters[i];
|
||||
|
||||
if (names.exist(parameter->name.c_str()))
|
||||
{
|
||||
status_exception::raise(
|
||||
Arg::Gds(isc_sqlerr) << Arg::Num(-901) <<
|
||||
Arg::Gds(isc_dsql_duplicate_spec) << Arg::Str(parameter->name));
|
||||
}
|
||||
|
||||
if (parameter->name.hasData()) // legacy UDFs has unnamed parameters
|
||||
names.add(parameter->name.c_str());
|
||||
}
|
||||
|
||||
PASS1_check_unique_fields_names(names, localDeclList);
|
||||
LocalDeclarationsNode::checkUniqueFieldsNames(localDeclList, ¶meters, nullptr);
|
||||
|
||||
source.ltrim("\n\r\t ");
|
||||
|
||||
@ -2329,7 +2310,8 @@ void CreateAlterFunctionNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch*
|
||||
// of previous calls to PASS1_node and PASS1_statement.
|
||||
dsqlScratch->setPsql(true);
|
||||
|
||||
dsqlScratch->putLocalVariables(localDeclList, 1);
|
||||
if (localDeclList)
|
||||
localDeclList->genBlr(dsqlScratch);
|
||||
|
||||
dsqlScratch->loopLevel = 0;
|
||||
dsqlScratch->cursorNumber = 0;
|
||||
@ -2635,39 +2617,7 @@ DdlNode* CreateAlterProcedureNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
||||
{
|
||||
dsqlScratch->flags |= (DsqlCompilerScratch::FLAG_BLOCK | DsqlCompilerScratch::FLAG_PROCEDURE);
|
||||
|
||||
// check for duplicated parameters and declaration names
|
||||
|
||||
StrArray names;
|
||||
|
||||
for (FB_SIZE_T i = 0; i < parameters.getCount(); ++i)
|
||||
{
|
||||
const ParameterClause* const parameter = parameters[i];
|
||||
|
||||
if (names.exist(parameter->name.c_str()))
|
||||
{
|
||||
status_exception::raise(
|
||||
Arg::Gds(isc_sqlerr) << Arg::Num(-901) <<
|
||||
Arg::Gds(isc_dsql_duplicate_spec) << Arg::Str(parameter->name));
|
||||
}
|
||||
|
||||
names.add(parameter->name.c_str());
|
||||
}
|
||||
|
||||
for (FB_SIZE_T i = 0; i < returns.getCount(); ++i)
|
||||
{
|
||||
const ParameterClause* const parameter = returns[i];
|
||||
|
||||
if (names.exist(parameter->name.c_str()))
|
||||
{
|
||||
status_exception::raise(
|
||||
Arg::Gds(isc_sqlerr) << Arg::Num(-901) <<
|
||||
Arg::Gds(isc_dsql_duplicate_spec) << Arg::Str(parameter->name));
|
||||
}
|
||||
|
||||
names.add(parameter->name.c_str());
|
||||
}
|
||||
|
||||
PASS1_check_unique_fields_names(names, localDeclList);
|
||||
LocalDeclarationsNode::checkUniqueFieldsNames(localDeclList, ¶meters, &returns);
|
||||
|
||||
source.ltrim("\n\r\t ");
|
||||
|
||||
@ -3200,7 +3150,8 @@ void CreateAlterProcedureNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch*
|
||||
// of previous calls to PASS1_node and PASS1_statement.
|
||||
dsqlScratch->setPsql(true);
|
||||
|
||||
dsqlScratch->putLocalVariables(localDeclList, returns.getCount());
|
||||
if (localDeclList)
|
||||
localDeclList->genBlr(dsqlScratch);
|
||||
|
||||
dsqlScratch->loopLevel = 0;
|
||||
dsqlScratch->cursorNumber = 0;
|
||||
@ -3717,7 +3668,9 @@ void CreateAlterTriggerNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch* d
|
||||
dsqlScratch->appendUChar(blr_begin);
|
||||
|
||||
dsqlScratch->setPsql(true);
|
||||
dsqlScratch->putLocalVariables(localDeclList, 0);
|
||||
|
||||
if (localDeclList)
|
||||
localDeclList->genBlr(dsqlScratch);
|
||||
|
||||
dsqlScratch->loopLevel = 0;
|
||||
dsqlScratch->cursorNumber = 0;
|
||||
|
@ -39,7 +39,7 @@
|
||||
|
||||
namespace Jrd {
|
||||
|
||||
class CompoundStmtNode;
|
||||
class LocalDeclarationsNode;
|
||||
class RelationSourceNode;
|
||||
class ValueListNode;
|
||||
class SecDbContext;
|
||||
@ -469,7 +469,7 @@ public:
|
||||
bool deterministic;
|
||||
Firebird::Array<NestConst<ParameterClause> > parameters;
|
||||
NestConst<ParameterClause> returnType;
|
||||
NestConst<CompoundStmtNode> localDeclList;
|
||||
NestConst<LocalDeclarationsNode> localDeclList;
|
||||
Firebird::string source;
|
||||
NestConst<StmtNode> body;
|
||||
bool compiled;
|
||||
@ -605,7 +605,7 @@ public:
|
||||
Firebird::Array<NestConst<ParameterClause> > parameters;
|
||||
Firebird::Array<NestConst<ParameterClause> > returns;
|
||||
Firebird::string source;
|
||||
NestConst<CompoundStmtNode> localDeclList;
|
||||
NestConst<LocalDeclarationsNode> localDeclList;
|
||||
NestConst<StmtNode> body;
|
||||
bool compiled;
|
||||
bool invalid;
|
||||
@ -782,7 +782,7 @@ private:
|
||||
public:
|
||||
bool create;
|
||||
bool alter;
|
||||
NestConst<CompoundStmtNode> localDeclList;
|
||||
NestConst<LocalDeclarationsNode> localDeclList;
|
||||
NestConst<StmtNode> body;
|
||||
bool compiled;
|
||||
bool invalid;
|
||||
|
@ -283,97 +283,6 @@ void DsqlCompilerScratch::putType(const TypeClause* type, bool useSubType)
|
||||
}
|
||||
}
|
||||
|
||||
// Emit dyn for the local variables declared in a procedure or trigger.
|
||||
void DsqlCompilerScratch::putLocalVariables(CompoundStmtNode* parameters, USHORT locals)
|
||||
{
|
||||
if (!parameters)
|
||||
return;
|
||||
|
||||
Array<dsql_var*> declaredVariables;
|
||||
|
||||
const auto end = parameters->statements.end();
|
||||
|
||||
for (auto ptr = parameters->statements.begin(); ptr != end; ++ptr)
|
||||
{
|
||||
auto parameter = *ptr;
|
||||
|
||||
putDebugSrcInfo(parameter->line, parameter->column);
|
||||
|
||||
if (const auto varNode = nodeAs<DeclareVariableNode>(parameter))
|
||||
{
|
||||
dsql_fld* field = varNode->dsqlDef->type;
|
||||
const NestConst<StmtNode>* rest = ptr;
|
||||
|
||||
while (++rest != end)
|
||||
{
|
||||
if (const auto varNode2 = nodeAs<DeclareVariableNode>(*rest))
|
||||
{
|
||||
const dsql_fld* rest_field = varNode2->dsqlDef->type;
|
||||
|
||||
if (field->fld_name == rest_field->fld_name)
|
||||
{
|
||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-637) <<
|
||||
Arg::Gds(isc_dsql_duplicate_spec) << Arg::Str(field->fld_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const auto variable = makeVariable(field, field->fld_name.c_str(), dsql_var::TYPE_LOCAL, 0, 0, locals);
|
||||
declaredVariables.add(variable);
|
||||
|
||||
putLocalVariableDecl(variable, varNode, varNode->dsqlDef->type->collate);
|
||||
|
||||
// Some field attributes are calculated inside putLocalVariable(), so we reinitialize
|
||||
// the descriptor.
|
||||
DsqlDescMaker::fromField(&variable->desc, field);
|
||||
|
||||
++locals;
|
||||
}
|
||||
else if (nodeIs<DeclareCursorNode>(parameter) ||
|
||||
nodeIs<DeclareSubProcNode>(parameter) ||
|
||||
nodeIs<DeclareSubFuncNode>(parameter))
|
||||
{
|
||||
parameter->dsqlPass(this);
|
||||
parameter->genBlr(this);
|
||||
}
|
||||
else
|
||||
fb_assert(false);
|
||||
}
|
||||
|
||||
auto declVarIt = declaredVariables.begin();
|
||||
|
||||
for (const auto parameter : parameters->statements)
|
||||
{
|
||||
if (const auto varNode = nodeAs<DeclareVariableNode>(parameter))
|
||||
putLocalVariableInit(*declVarIt++, varNode);
|
||||
}
|
||||
|
||||
if (!(flags & DsqlCompilerScratch::FLAG_SUB_ROUTINE))
|
||||
{
|
||||
// Check not implemented sub-functions.
|
||||
for (const auto& [name, subFunc] : subFunctions)
|
||||
{
|
||||
if (subFunc->isForwardDecl())
|
||||
{
|
||||
status_exception::raise(
|
||||
Arg::Gds(isc_subfunc_not_impl) <<
|
||||
name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// Check not implemented sub-procedures.
|
||||
for (const auto& [name, subProc] : subProcedures)
|
||||
{
|
||||
if (subProc->isForwardDecl())
|
||||
{
|
||||
status_exception::raise(
|
||||
Arg::Gds(isc_subproc_not_impl) <<
|
||||
name.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write out local variable field data type.
|
||||
void DsqlCompilerScratch::putLocalVariableDecl(dsql_var* variable, DeclareVariableNode* hostParam,
|
||||
const MetaName& collationName)
|
||||
|
@ -35,7 +35,7 @@ namespace Jrd
|
||||
{
|
||||
|
||||
class BinaryBoolNode;
|
||||
class CompoundStmtNode;
|
||||
class LocalDeclarationsNode;
|
||||
class DeclareCursorNode;
|
||||
class DeclareLocalTableNode;
|
||||
class DeclareVariableNode;
|
||||
@ -153,7 +153,6 @@ public:
|
||||
void putBlrMarkers(ULONG marks);
|
||||
void putDtype(const TypeClause* field, bool useSubType);
|
||||
void putType(const TypeClause* type, bool useSubType);
|
||||
void putLocalVariables(CompoundStmtNode* parameters, USHORT locals);
|
||||
void putLocalVariableDecl(dsql_var* variable, DeclareVariableNode* hostParam, const MetaName& collationName);
|
||||
void putLocalVariableInit(dsql_var* variable, const DeclareVariableNode* hostParam);
|
||||
|
||||
@ -238,9 +237,19 @@ public:
|
||||
bool isPsql() const { return psql; }
|
||||
void setPsql(bool value) { psql = value; }
|
||||
|
||||
const auto& getSubFunctions() const
|
||||
{
|
||||
return subFunctions;
|
||||
}
|
||||
|
||||
DeclareSubFuncNode* getSubFunction(const MetaName& name);
|
||||
void putSubFunction(DeclareSubFuncNode* subFunc, bool replace = false);
|
||||
|
||||
const auto& getSubProcedures() const
|
||||
{
|
||||
return subProcedures;
|
||||
}
|
||||
|
||||
DeclareSubProcNode* getSubProcedure(const MetaName& name);
|
||||
void putSubProcedure(DeclareSubProcNode* subProc, bool replace = false);
|
||||
|
||||
|
@ -1432,6 +1432,7 @@ public:
|
||||
TYPE_HANDLER,
|
||||
TYPE_LABEL,
|
||||
TYPE_LINE_COLUMN,
|
||||
TYPE_LOCAL_DECLARATIONS,
|
||||
TYPE_LOOP,
|
||||
TYPE_MERGE,
|
||||
TYPE_MERGE_SEND,
|
||||
|
@ -4354,34 +4354,7 @@ ExecBlockNode* ExecBlockNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
||||
node->localDeclList = localDeclList;
|
||||
node->body = body;
|
||||
|
||||
const FB_SIZE_T count = node->parameters.getCount() + node->returns.getCount() +
|
||||
(node->localDeclList ? node->localDeclList->statements.getCount() : 0);
|
||||
|
||||
if (count != 0)
|
||||
{
|
||||
StrArray names(*getDefaultMemoryPool(), count);
|
||||
|
||||
// Hand-made PASS1_check_unique_fields_names for arrays of ParameterClause
|
||||
|
||||
Array<NestConst<ParameterClause> > params(parameters);
|
||||
params.add(returns.begin(), returns.getCount());
|
||||
|
||||
for (FB_SIZE_T i = 0; i < params.getCount(); ++i)
|
||||
{
|
||||
ParameterClause* parameter = params[i];
|
||||
|
||||
FB_SIZE_T pos;
|
||||
if (!names.find(parameter->name.c_str(), pos))
|
||||
names.insert(pos, parameter->name.c_str());
|
||||
else
|
||||
{
|
||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-637) <<
|
||||
Arg::Gds(isc_dsql_duplicate_spec) << Arg::Str(parameter->name));
|
||||
}
|
||||
}
|
||||
|
||||
PASS1_check_unique_fields_names(names, node->localDeclList);
|
||||
}
|
||||
LocalDeclarationsNode::checkUniqueFieldsNames(node->localDeclList, ¶meters, &returns);
|
||||
|
||||
return node;
|
||||
}
|
||||
@ -4507,15 +4480,15 @@ void ExecBlockNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
||||
}
|
||||
}
|
||||
|
||||
const Array<dsql_var*>& variables = subRoutine ? dsqlScratch->outputVariables : dsqlScratch->variables;
|
||||
const auto& variables = subRoutine ? dsqlScratch->outputVariables : dsqlScratch->variables;
|
||||
|
||||
for (const auto variable : variables)
|
||||
dsqlScratch->putLocalVariable(variable, nullptr, {});
|
||||
|
||||
dsqlScratch->setPsql(true);
|
||||
|
||||
dsqlScratch->putLocalVariables(localDeclList,
|
||||
USHORT((subRoutine ? 0 : parameters.getCount()) + returns.getCount()));
|
||||
if (localDeclList)
|
||||
localDeclList->genBlr(dsqlScratch);
|
||||
|
||||
dsqlScratch->loopLevel = 0;
|
||||
|
||||
@ -5442,6 +5415,166 @@ void LineColumnNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
||||
//--------------------
|
||||
|
||||
|
||||
// Check duplicate fields (params, variables, cursors etc).
|
||||
void LocalDeclarationsNode::checkUniqueFieldsNames(const LocalDeclarationsNode* node,
|
||||
const Array<NestConst<ParameterClause>>* inputParameters,
|
||||
const Array<NestConst<ParameterClause>>* outputParameters)
|
||||
{
|
||||
const FB_SIZE_T count = (inputParameters ? inputParameters->getCount() : 0) +
|
||||
(outputParameters ? outputParameters->getCount() : 0) +
|
||||
(node ? node->statements.getCount() : 0);
|
||||
|
||||
StrArray names(*getDefaultMemoryPool(), count);
|
||||
|
||||
for (const auto parameters : {inputParameters, outputParameters})
|
||||
{
|
||||
if (parameters)
|
||||
{
|
||||
for (const auto parameter : *parameters)
|
||||
{
|
||||
if (parameter->name.hasData()) // legacy UDFs has unnamed parameters
|
||||
{
|
||||
FB_SIZE_T pos;
|
||||
if (!names.find(parameter->name.c_str(), pos))
|
||||
names.insert(pos, parameter->name.c_str());
|
||||
else
|
||||
{
|
||||
ERRD_post(
|
||||
Arg::Gds(isc_sqlerr) << Arg::Num(-637) <<
|
||||
Arg::Gds(isc_dsql_duplicate_spec) << Arg::Str(parameter->name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (node)
|
||||
{
|
||||
for (const auto statement : node->statements)
|
||||
{
|
||||
const char* name = nullptr;
|
||||
|
||||
if (auto varNode = nodeAs<DeclareVariableNode>(statement))
|
||||
name = varNode->dsqlDef->name.c_str();
|
||||
else if (auto cursorNode = nodeAs<DeclareCursorNode>(statement))
|
||||
name = cursorNode->dsqlName.c_str();
|
||||
else if (nodeAs<DeclareSubProcNode>(statement) || nodeAs<DeclareSubFuncNode>(statement))
|
||||
continue;
|
||||
|
||||
fb_assert(name);
|
||||
|
||||
FB_SIZE_T pos;
|
||||
if (!names.find(name, pos))
|
||||
names.insert(pos, name);
|
||||
else
|
||||
{
|
||||
ERRD_post(
|
||||
Arg::Gds(isc_sqlerr) << Arg::Num(-637) <<
|
||||
Arg::Gds(isc_dsql_duplicate_spec) << Arg::Str(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LocalDeclarationsNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
||||
{
|
||||
// Sub routine needs a different approach from EXECUTE BLOCK.
|
||||
// EXECUTE BLOCK needs "ports", which creates DSQL messages using the client charset.
|
||||
// Sub routine doesn't need ports and should generate BLR as declared in its metadata.
|
||||
const bool isSubRoutine = dsqlScratch->flags & DsqlCompilerScratch::FLAG_SUB_ROUTINE;
|
||||
const auto& variables = isSubRoutine ? dsqlScratch->outputVariables : dsqlScratch->variables;
|
||||
USHORT locals = variables.getCount();
|
||||
|
||||
Array<dsql_var*> declaredVariables;
|
||||
|
||||
const auto end = statements.end();
|
||||
|
||||
for (auto ptr = statements.begin(); ptr != end; ++ptr)
|
||||
{
|
||||
auto parameter = *ptr;
|
||||
|
||||
dsqlScratch->putDebugSrcInfo(parameter->line, parameter->column);
|
||||
|
||||
if (const auto varNode = nodeAs<DeclareVariableNode>(parameter))
|
||||
{
|
||||
dsql_fld* field = varNode->dsqlDef->type;
|
||||
const NestConst<StmtNode>* rest = ptr;
|
||||
|
||||
while (++rest != end)
|
||||
{
|
||||
if (const auto varNode2 = nodeAs<DeclareVariableNode>(*rest))
|
||||
{
|
||||
const dsql_fld* rest_field = varNode2->dsqlDef->type;
|
||||
|
||||
if (field->fld_name == rest_field->fld_name)
|
||||
{
|
||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-637) <<
|
||||
Arg::Gds(isc_dsql_duplicate_spec) << Arg::Str(field->fld_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const auto variable = dsqlScratch->makeVariable(field, field->fld_name.c_str(),
|
||||
dsql_var::TYPE_LOCAL, 0, 0, locals);
|
||||
declaredVariables.add(variable);
|
||||
|
||||
dsqlScratch->putLocalVariableDecl(variable, varNode, varNode->dsqlDef->type->collate);
|
||||
|
||||
// Some field attributes are calculated inside putLocalVariable(), so we reinitialize
|
||||
// the descriptor.
|
||||
DsqlDescMaker::fromField(&variable->desc, field);
|
||||
|
||||
++locals;
|
||||
}
|
||||
else if (nodeIs<DeclareCursorNode>(parameter) ||
|
||||
nodeIs<DeclareSubProcNode>(parameter) ||
|
||||
nodeIs<DeclareSubFuncNode>(parameter))
|
||||
{
|
||||
parameter->dsqlPass(dsqlScratch);
|
||||
parameter->genBlr(dsqlScratch);
|
||||
}
|
||||
else
|
||||
fb_assert(false);
|
||||
}
|
||||
|
||||
auto declVarIt = declaredVariables.begin();
|
||||
|
||||
for (const auto parameter : statements)
|
||||
{
|
||||
if (const auto varNode = nodeAs<DeclareVariableNode>(parameter))
|
||||
dsqlScratch->putLocalVariableInit(*declVarIt++, varNode);
|
||||
}
|
||||
|
||||
if (!isSubRoutine)
|
||||
{
|
||||
// Check not implemented sub-functions.
|
||||
for (const auto& [name, subFunc] : dsqlScratch->getSubFunctions())
|
||||
{
|
||||
if (subFunc->isForwardDecl())
|
||||
{
|
||||
status_exception::raise(
|
||||
Arg::Gds(isc_subfunc_not_impl) <<
|
||||
name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// Check not implemented sub-procedures.
|
||||
for (const auto& [name, subProc] : dsqlScratch->getSubProcedures())
|
||||
{
|
||||
if (subProc->isForwardDecl())
|
||||
{
|
||||
status_exception::raise(
|
||||
Arg::Gds(isc_subproc_not_impl) <<
|
||||
name.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------
|
||||
|
||||
|
||||
static RegisterNode<LoopNode> regLoopNode({blr_loop});
|
||||
|
||||
DmlNode* LoopNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb, const UCHAR /*blrOp*/)
|
||||
|
@ -791,7 +791,7 @@ private:
|
||||
public:
|
||||
Firebird::Array<NestConst<ParameterClause>> parameters;
|
||||
Firebird::Array<NestConst<ParameterClause>> returns;
|
||||
NestConst<CompoundStmtNode> localDeclList;
|
||||
NestConst<LocalDeclarationsNode> localDeclList;
|
||||
NestConst<StmtNode> body;
|
||||
};
|
||||
|
||||
@ -989,6 +989,28 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class LocalDeclarationsNode final : public TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_LOCAL_DECLARATIONS>
|
||||
{
|
||||
public:
|
||||
explicit LocalDeclarationsNode(MemoryPool& pool)
|
||||
: TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_LOCAL_DECLARATIONS>(pool),
|
||||
statements(pool)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
static void checkUniqueFieldsNames(const LocalDeclarationsNode* node,
|
||||
const Firebird::Array<NestConst<ParameterClause>>* inputParameters,
|
||||
const Firebird::Array<NestConst<ParameterClause>>* outputParameters);
|
||||
|
||||
public:
|
||||
void genBlr(DsqlCompilerScratch* dsqlScratch) override;
|
||||
|
||||
public:
|
||||
Firebird::Array<NestConst<StmtNode>> statements;
|
||||
};
|
||||
|
||||
|
||||
class LoopNode final : public TypedNode<StmtNode, StmtNode::TYPE_LOOP>
|
||||
{
|
||||
public:
|
||||
|
@ -831,6 +831,7 @@ using namespace Firebird;
|
||||
Jrd::DeclareCursorNode* declCursorNode;
|
||||
Jrd::ErrorHandlerNode* errorHandlerNode;
|
||||
Jrd::ExecStatementNode* execStatementNode;
|
||||
Jrd::LocalDeclarationsNode* localDeclarationsNode;
|
||||
Jrd::MergeNode* mergeNode;
|
||||
Jrd::MergeNode::NotMatched* mergeNotMatchedClause;
|
||||
Jrd::MergeNode::Matched* mergeMatchedClause;
|
||||
@ -3025,12 +3026,12 @@ package_body_item
|
||||
;
|
||||
|
||||
|
||||
%type <compoundStmtNode> local_declarations_opt
|
||||
%type <localDeclarationsNode> local_declarations_opt
|
||||
local_declarations_opt
|
||||
: local_forward_declarations_opt local_nonforward_declarations_opt
|
||||
{
|
||||
CompoundStmtNode* forward = $1;
|
||||
CompoundStmtNode* nonForward = $2;
|
||||
LocalDeclarationsNode* forward = $1;
|
||||
LocalDeclarationsNode* nonForward = $2;
|
||||
|
||||
if (!forward)
|
||||
$$ = nonForward;
|
||||
@ -3044,17 +3045,17 @@ local_declarations_opt
|
||||
}
|
||||
;
|
||||
|
||||
%type <compoundStmtNode> local_forward_declarations_opt
|
||||
%type <localDeclarationsNode> local_forward_declarations_opt
|
||||
local_forward_declarations_opt
|
||||
: /* nothing */ { $$ = NULL; }
|
||||
: /* nothing */ { $$ = nullptr; }
|
||||
| local_forward_declarations
|
||||
;
|
||||
|
||||
%type <compoundStmtNode> local_forward_declarations
|
||||
%type <localDeclarationsNode> local_forward_declarations
|
||||
local_forward_declarations
|
||||
: local_forward_declaration
|
||||
{
|
||||
$$ = newNode<CompoundStmtNode>();
|
||||
$$ = newNode<LocalDeclarationsNode>();
|
||||
$$->statements.add($1);
|
||||
}
|
||||
| local_forward_declarations local_forward_declaration
|
||||
@ -3070,17 +3071,17 @@ local_forward_declaration
|
||||
| local_declaration_subfunc_start ';' { $$ = $1; }
|
||||
;
|
||||
|
||||
%type <compoundStmtNode> local_nonforward_declarations_opt
|
||||
%type <localDeclarationsNode> local_nonforward_declarations_opt
|
||||
local_nonforward_declarations_opt
|
||||
: /* nothing */ { $$ = NULL; }
|
||||
: /* nothing */ { $$ = nullptr; }
|
||||
| local_nonforward_declarations
|
||||
;
|
||||
|
||||
%type <compoundStmtNode> local_nonforward_declarations
|
||||
%type <localDeclarationsNode> local_nonforward_declarations
|
||||
local_nonforward_declarations
|
||||
: local_nonforward_declaration
|
||||
{
|
||||
$$ = newNode<CompoundStmtNode>();
|
||||
$$ = newNode<LocalDeclarationsNode>();
|
||||
$$->statements.add($1);
|
||||
}
|
||||
| local_nonforward_declarations local_nonforward_declaration
|
||||
|
@ -672,46 +672,6 @@ void PASS1_ambiguity_check(DsqlCompilerScratch* dsqlScratch,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
PASS1_check_unique_fields_names
|
||||
|
||||
check fields (params, variables, cursors etc) names against
|
||||
sorted array
|
||||
if success, add them into array
|
||||
**/
|
||||
void PASS1_check_unique_fields_names(StrArray& names, const CompoundStmtNode* fields)
|
||||
{
|
||||
if (!fields)
|
||||
return;
|
||||
|
||||
const NestConst<StmtNode>* ptr = fields->statements.begin();
|
||||
const NestConst<StmtNode>* const end = fields->statements.end();
|
||||
|
||||
for (; ptr != end; ++ptr)
|
||||
{
|
||||
const char* name = NULL;
|
||||
|
||||
if (auto varNode = nodeAs<DeclareVariableNode>(*ptr))
|
||||
name = varNode->dsqlDef->name.c_str();
|
||||
else if (auto cursorNode = nodeAs<DeclareCursorNode>(*ptr))
|
||||
name = cursorNode->dsqlName.c_str();
|
||||
else if (nodeAs<DeclareSubProcNode>(*ptr) || nodeAs<DeclareSubFuncNode>(*ptr))
|
||||
continue;
|
||||
|
||||
fb_assert(name);
|
||||
|
||||
FB_SIZE_T pos;
|
||||
if (!names.find(name, pos))
|
||||
names.insert(pos, name);
|
||||
else
|
||||
{
|
||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-637) <<
|
||||
Arg::Gds(isc_dsql_duplicate_spec) << Arg::Str(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Compose two booleans.
|
||||
BoolExprNode* PASS1_compose(BoolExprNode* expr1, BoolExprNode* expr2, UCHAR blrOp)
|
||||
{
|
||||
|
@ -39,7 +39,6 @@ namespace Jrd
|
||||
}
|
||||
|
||||
void PASS1_ambiguity_check(Jrd::DsqlCompilerScratch*, const Jrd::MetaName&, const Jrd::DsqlContextStack&);
|
||||
void PASS1_check_unique_fields_names(Jrd::StrArray& names, const Jrd::CompoundStmtNode* fields);
|
||||
Jrd::BoolExprNode* PASS1_compose(Jrd::BoolExprNode*, Jrd::BoolExprNode*, UCHAR);
|
||||
Jrd::DeclareCursorNode* PASS1_cursor_name(Jrd::DsqlCompilerScratch*, const Jrd::MetaName&, USHORT, bool);
|
||||
Jrd::RseNode* PASS1_derived_table(Jrd::DsqlCompilerScratch*, Jrd::SelectExprNode*, const char*,
|
||||
|
Loading…
Reference in New Issue
Block a user