From d3d70475b8310f73bfdb55b9aaf884546200648b Mon Sep 17 00:00:00 2001 From: Vlad Khorsun Date: Thu, 27 Jun 2024 11:12:51 +0300 Subject: [PATCH] Fixed bug #8168 : MAKE_DBKEY bug after backup/restore Added warning in documentation. --- .../README.builtin_functions.txt | 3 ++ src/dsql/ExprNodes.cpp | 50 +++++++++---------- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/doc/sql.extensions/README.builtin_functions.txt b/doc/sql.extensions/README.builtin_functions.txt index e387f8f52d..fd5afe2ac0 100644 --- a/doc/sql.extensions/README.builtin_functions.txt +++ b/doc/sql.extensions/README.builtin_functions.txt @@ -726,6 +726,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 4528319b3e..46663d2733 100644 --- a/src/dsql/ExprNodes.cpp +++ b/src/dsql/ExprNodes.cpp @@ -12297,6 +12297,30 @@ 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) + { + 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); + } + } + return node; } @@ -12443,32 +12467,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());