diff --git a/doc/sql.extensions/README.builtin_functions.txt b/doc/sql.extensions/README.builtin_functions.txt index 3e67eb9c31..de368961ec 100644 --- a/doc/sql.extensions/README.builtin_functions.txt +++ b/doc/sql.extensions/README.builtin_functions.txt @@ -729,6 +729,9 @@ Notes: In the case of string literal, relation ID is evaluated at prepare time. In the case of expression, relation ID is evaluated at execution time. If the relation couldn't be found, then isc_relnotdef error is raised. + Relation ID's could be changed after database restore thus beware of using + integer literals in the first argument (relation) in stored PSQL code + (procedures, functions, triggers). 2) If the first argument (relation) is a numeric expression or literal, then it's treated as a relation ID and used "as is", without verification against existing relations. diff --git a/src/dsql/ExprNodes.cpp b/src/dsql/ExprNodes.cpp index 7b30ea0ea9..aabea66e78 100644 --- a/src/dsql/ExprNodes.cpp +++ b/src/dsql/ExprNodes.cpp @@ -12321,6 +12321,23 @@ DmlNode* SysFuncCallNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScrat node->args = PAR_args(tdbb, csb); + if (name == "MAKE_DBKEY") + { + // Special handling for system function MAKE_DBKEY: + // convert constant relation name into ID at the parsing time + + auto literal = nodeAs(node->args->items[0]); + + if (literal && literal->litDesc.isText()) + { + const MetaName relName = literal->getText(); + const jrd_rel* const relation = MET_lookup_relation(tdbb, relName); + + if (relation) + node->args->items[0] = MAKE_const_slong(relation->rel_id); + } + } + return node; } @@ -12462,32 +12479,6 @@ ValueExprNode* SysFuncCallNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) if (node->function) { - if (name == "MAKE_DBKEY") - { - // Special handling for system function MAKE_DBKEY: - // convert constant relation name into ID at the parsing time - - auto literal = nodeAs(node->args->items[0]); - - if (literal && literal->litDesc.isText()) - { - const MetaName relName = literal->getText(); - - const dsql_rel* const relation = - METD_get_relation(dsqlScratch->getTransaction(), dsqlScratch, relName); - - if (!relation) - { - status_exception::raise( - Arg::Gds(isc_sqlerr) << Arg::Num(-607) << - Arg::Gds(isc_dsql_command_err) << - Arg::Gds(isc_dsql_table_not_found) << relName); - } - - node->args->items[0] = MAKE_const_slong(relation->rel_id); - } - } - if (node->function->setParamsFunc) { Array tempDescs(node->args->items.getCount());