From 4330b1c526dc46f8281b7ddc428040e4306996db Mon Sep 17 00:00:00 2001 From: Alexander Zhdanov Date: Thu, 5 Sep 2024 14:21:09 +0300 Subject: [PATCH 1/2] Move the call of the checkArgsMismatch function before the call of the setParamsFunc function --- src/dsql/ExprNodes.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/dsql/ExprNodes.cpp b/src/dsql/ExprNodes.cpp index 76149a54118..abbc3560634 100644 --- a/src/dsql/ExprNodes.cpp +++ b/src/dsql/ExprNodes.cpp @@ -12386,7 +12386,6 @@ void SysFuncCallNode::make(DsqlCompilerScratch* dsqlScratch, dsc* desc) } DSqlDataTypeUtil dataTypeUtil(dsqlScratch); - function->checkArgsMismatch(argsArray.getCount()); function->makeFunc(&dataTypeUtil, function, desc, argsArray.getCount(), argsArray.begin()); } @@ -12481,14 +12480,18 @@ ValueExprNode* SysFuncCallNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) if (node->function) { + auto& items = node->args->items; + + node->function->checkArgsMismatch(items.getCount()); + if (node->function->setParamsFunc) { - Array tempDescs(node->args->items.getCount()); - tempDescs.resize(node->args->items.getCount()); + Array tempDescs(items.getCount()); + tempDescs.resize(items.getCount()); - Array argsArray(node->args->items.getCount()); + Array argsArray(items.getCount()); - for (auto& item : node->args->items) + for (auto& item : items) { DsqlDescMaker::fromNode(dsqlScratch, item); @@ -12507,7 +12510,7 @@ ValueExprNode* SysFuncCallNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) node->function->setParamsFunc(&dataTypeUtil, node->function, argsArray.getCount(), argsArray.begin()); - for (auto& item : node->args->items) + for (auto& item : items) { PASS1_set_parameter_type(dsqlScratch, item, [&] (dsc* desc) { *desc = item->getDsqlDesc(); }, From b41b1281c53f5201e456bcf15b728ec6ac84e12c Mon Sep 17 00:00:00 2001 From: Dmitry Yemanov Date: Mon, 6 Oct 2025 15:17:31 +0300 Subject: [PATCH 2/2] Replace unneeded checks with asserts. Move the JRD-level validation from pass2() to parse(). --- src/dsql/ExprNodes.cpp | 4 +- src/jrd/SysFunction.cpp | 193 ++++++++++++++++++++-------------------- 2 files changed, 100 insertions(+), 97 deletions(-) diff --git a/src/dsql/ExprNodes.cpp b/src/dsql/ExprNodes.cpp index abbc3560634..e4bc6ec751b 100644 --- a/src/dsql/ExprNodes.cpp +++ b/src/dsql/ExprNodes.cpp @@ -12321,6 +12321,8 @@ DmlNode* SysFuncCallNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScrat node->args = PAR_args(tdbb, csb); + node->function->checkArgsMismatch(node->args->items.getCount()); + if (name == "MAKE_DBKEY") { // Special handling for system function MAKE_DBKEY: @@ -12447,8 +12449,6 @@ ValueExprNode* SysFuncCallNode::pass2(thread_db* tdbb, CompilerScratch* csb) { ValueExprNode::pass2(tdbb, csb); - function->checkArgsMismatch(args->items.getCount()); - dsc desc; getDesc(tdbb, csb, &desc); impureOffset = csb->allocImpure(); diff --git a/src/jrd/SysFunction.cpp b/src/jrd/SysFunction.cpp index ad7ff7ba5d3..792fd5040e6 100644 --- a/src/jrd/SysFunction.cpp +++ b/src/jrd/SysFunction.cpp @@ -611,24 +611,27 @@ void setParamsInt64(DataTypeUtilBase*, const SysFunction*, int argsCount, dsc** void setParamsSecondInteger(DataTypeUtilBase*, const SysFunction*, int argsCount, dsc** args) { - if (argsCount >= 2) - { - if (args[1]->isUnknown()) - args[1]->makeLong(0); - } + fb_assert(argsCount >= 2); + + if (args[1]->isUnknown()) + args[1]->makeLong(0); } void setParamsAsciiVal(DataTypeUtilBase*, const SysFunction*, int argsCount, dsc** args) { - if (argsCount >= 1 && args[0]->isUnknown()) + fb_assert(argsCount >= 1); + + if (args[0]->isUnknown()) args[0]->makeText(1, CS_ASCII); } void setParamsBlobAppend(DataTypeUtilBase*, const SysFunction*, int argsCount, dsc** args) { - if (argsCount >= 1 && args[0]->isUnknown()) + fb_assert(argsCount >= 1); + + if (args[0]->isUnknown()) args[0]->makeBlob(isc_blob_text, CS_dynamic); for (int i = 1; i < argsCount; ++i) @@ -641,14 +644,18 @@ void setParamsBlobAppend(DataTypeUtilBase*, const SysFunction*, int argsCount, d void setParamsCharToUuid(DataTypeUtilBase*, const SysFunction*, int argsCount, dsc** args) { - if (argsCount >= 1 && args[0]->isUnknown()) + fb_assert(argsCount >= 1); + + if (args[0]->isUnknown()) args[0]->makeText(Uuid::STR_LEN, ttype_ascii); } void setParamsDateAdd(DataTypeUtilBase*, const SysFunction*, int argsCount, dsc** args) { - if (argsCount >= 1 && args[0]->isUnknown()) + fb_assert(argsCount >= 3); + + if (args[0]->isUnknown()) { if (args[1]->dsc_address && // constant CVT_get_long(args[1], 0, JRD_get_thread_data()->getAttachment()->att_dec_status, ERR_post) == blr_extract_millisecond) @@ -659,31 +666,32 @@ void setParamsDateAdd(DataTypeUtilBase*, const SysFunction*, int argsCount, dsc* args[0]->makeInt64(0); } - if (argsCount >= 3 && args[2]->isUnknown()) + if (args[2]->isUnknown()) args[2]->makeTimestamp(); } void setParamsDateDiff(DataTypeUtilBase*, const SysFunction*, int argsCount, dsc** args) { - if (argsCount >= 3) + fb_assert(argsCount >= 3); + + if (args[1]->isUnknown() && args[2]->isUnknown()) { - if (args[1]->isUnknown() && args[2]->isUnknown()) - { - args[1]->makeTimestamp(); - args[2]->makeTimestamp(); - } - else if (args[1]->isUnknown()) - *args[1] = *args[2]; - else if (args[2]->isUnknown()) - *args[2] = *args[1]; + args[1]->makeTimestamp(); + args[2]->makeTimestamp(); } + else if (args[1]->isUnknown()) + *args[1] = *args[2]; + else if (args[2]->isUnknown()) + *args[2] = *args[1]; } void setParamsUnicodeVal(DataTypeUtilBase*, const SysFunction*, int argsCount, dsc** args) { - if (argsCount >= 1 && args[0]->isUnknown()) + fb_assert(argsCount >= 1); + + if (args[0]->isUnknown()) args[0]->makeText(4, CS_UTF8); } @@ -819,23 +827,24 @@ void setParamsRsaPublic(DataTypeUtilBase*, const SysFunction*, int argsCount, ds void setParamsFirstLastDay(DataTypeUtilBase*, const SysFunction*, int argsCount, dsc** args) { - if (argsCount >= 2) - { - if (args[1]->isUnknown()) - args[1]->makeTimestamp(); - } + fb_assert(argsCount >= 2); + + if (args[1]->isUnknown()) + args[1]->makeTimestamp(); } void setParamsGetSetContext(DataTypeUtilBase*, const SysFunction*, int argsCount, dsc** args) { - if (argsCount >= 1 && args[0]->isUnknown()) + fb_assert(argsCount >= 2); + + if (args[0]->isUnknown()) { args[0]->makeVarying(80, ttype_none); args[0]->setNullable(true); } - if (argsCount >= 2 && args[1]->isUnknown()) + if (args[1]->isUnknown()) { args[1]->makeVarying(80, ttype_none); args[1]->setNullable(true); @@ -861,86 +870,84 @@ void setParamsMakeDbkey(DataTypeUtilBase*, const SysFunction*, int argsCount, ds { // MAKE_DBKEY ( REL_NAME | REL_ID, RECNUM [, DPNUM [, PPNUM] ] ) - if (argsCount > 1) - { - if (args[0]->isUnknown()) - args[0]->makeLong(0); + fb_assert(argsCount >= 2); - if (args[1]->isUnknown()) - args[1]->makeInt64(0); - } + if (args[0]->isUnknown()) + args[0]->makeLong(0); - if (argsCount > 2 && args[2]->isUnknown()) + if (args[1]->isUnknown()) + args[1]->makeInt64(0); + + if (argsCount >= 3 && args[2]->isUnknown()) args[2]->makeInt64(0); - if (argsCount > 3 && args[3]->isUnknown()) + if (argsCount >= 4 && args[3]->isUnknown()) args[3]->makeInt64(0); } void setParamsOverlay(DataTypeUtilBase*, const SysFunction*, int argsCount, dsc** args) { - if (argsCount >= 3) + fb_assert(argsCount >= 3); + + if (!(args[0]->isUnknown() && args[1]->isUnknown())) { - if (!(args[0]->isUnknown() && args[1]->isUnknown())) - { - if (args[1]->isUnknown()) - *args[1] = *args[0]; - else if (args[0]->isUnknown()) - *args[0] = *args[1]; - } + if (args[1]->isUnknown()) + *args[1] = *args[0]; + else if (args[0]->isUnknown()) + *args[0] = *args[1]; + } - if (argsCount >= 4) + if (argsCount >= 4) + { + if (args[2]->isUnknown() && args[3]->isUnknown()) { - if (args[2]->isUnknown() && args[3]->isUnknown()) - { - args[2]->makeLong(0); - args[3]->makeLong(0); - } - else if (args[2]->isUnknown()) - *args[2] = *args[3]; - else if (args[3]->isUnknown()) - *args[3] = *args[2]; - } - - if (args[2]->isUnknown()) args[2]->makeLong(0); + args[3]->makeLong(0); + } + else if (args[2]->isUnknown()) + *args[2] = *args[3]; + else if (args[3]->isUnknown()) + *args[3] = *args[2]; } + + if (args[2]->isUnknown()) + args[2]->makeLong(0); } void setParamsPosition(DataTypeUtilBase*, const SysFunction*, int argsCount, dsc** args) { - if (argsCount >= 2) - { - if (args[0]->isUnknown()) - *args[0] = *args[1]; + fb_assert(argsCount >= 2); - if (args[1]->isUnknown()) - *args[1] = *args[0]; - } + if (args[0]->isUnknown()) + *args[0] = *args[1]; + + if (args[1]->isUnknown()) + *args[1] = *args[0]; } void setParamsRoundTrunc(DataTypeUtilBase*, const SysFunction*, int argsCount, dsc** args) { - if (argsCount >= 1) - { - if (args[0]->isUnknown()) - args[0]->makeDouble(); + fb_assert(argsCount >= 1); - if (argsCount >= 2) - { - if (args[1]->isUnknown()) - args[1]->makeLong(0); - } + if (args[0]->isUnknown()) + args[0]->makeDouble(); + + if (argsCount >= 2) + { + if (args[1]->isUnknown()) + args[1]->makeLong(0); } } void setParamsUuidToChar(DataTypeUtilBase*, const SysFunction*, int argsCount, dsc** args) { - if (argsCount >= 1 && args[0]->isUnknown()) + fb_assert(argsCount >= 1); + + if (args[0]->isUnknown()) args[0]->makeText(16, ttype_binary); } @@ -1304,23 +1311,20 @@ void makeBlobAppend(DataTypeUtilBase* dataTypeUtil, const SysFunction* function, result->makeBlob(isc_blob_untyped, ttype_binary); result->setNullable(true); - if (argsCount > 0) + for (int i = 0; i < argsCount; ++i) { - for (int i = 0; i < argsCount; ++i) - { - if (makeBlobAppendBlob(result, args[i])) - break; - } + if (makeBlobAppendBlob(result, args[i])) + break; + } - result->setNullable(true); + result->setNullable(true); - for (int i = 0; i < argsCount; ++i) + for (int i = 0; i < argsCount; ++i) + { + if (!args[i]->isNullable()) { - if (!args[i]->isNullable()) - { - result->setNullable(false); - break; - } + result->setNullable(false); + break; } } } @@ -1417,13 +1421,12 @@ void makeFirstLastDayResult(DataTypeUtilBase*, const SysFunction*, dsc* result, result->makeDate(); - if (argsCount >= 2) - { - if (args[1]->dsc_dtype == dtype_timestamp) - result->makeTimestamp(); - else if (args[1]->dsc_dtype == dtype_timestamp_tz) - result->makeTimestampTz(); - } + fb_assert(argsCount >= 2); + + if (args[1]->dsc_dtype == dtype_timestamp) + result->makeTimestamp(); + else if (args[1]->dsc_dtype == dtype_timestamp_tz) + result->makeTimestampTz(); result->setNullable(isNullable); }