From 2e11c74e8a8f6538c924fda5d6567216ff50d642 Mon Sep 17 00:00:00 2001 From: "HOME5\\dmitr" Date: Tue, 28 Nov 2023 11:12:58 +0300 Subject: [PATCH] [UDF] Prohibition of "return BY VALUE" for ISC_TIMESTAMP_TZ, ISC_TIME_TZ and so on It is a fix for issue #7883. Test SQLs: DECLARE EXTERNAL FUNCTION UDF_DUMMY6__3 RETURNS INT128 BY VALUE ENTRY_POINT 'IB_UDF_abs' MODULE_NAME 'ib_udf'; DECLARE EXTERNAL FUNCTION UDF_DUMMY6__3 RETURNS NUMERIC(19,0) BY VALUE ENTRY_POINT 'IB_UDF_abs' MODULE_NAME 'ib_udf'; DECLARE EXTERNAL FUNCTION UDF_DUMMY6__3 RETURNS NUMERIC(19,1) BY VALUE ENTRY_POINT 'IB_UDF_abs' MODULE_NAME 'ib_udf'; DECLARE EXTERNAL FUNCTION UDF_DUMMY6__3 RETURNS DECIMAL(19,0) BY VALUE ENTRY_POINT 'IB_UDF_abs' MODULE_NAME 'ib_udf'; DECLARE EXTERNAL FUNCTION UDF_DUMMY6__3 RETURNS DECIMAL(19,1) BY VALUE ENTRY_POINT 'IB_UDF_abs' MODULE_NAME 'ib_udf'; DECLARE EXTERNAL FUNCTION UDF_DUMMY6__3 RETURNS DECFLOAT(16) BY VALUE ENTRY_POINT 'IB_UDF_abs' MODULE_NAME 'ib_udf'; DECLARE EXTERNAL FUNCTION UDF_DUMMY6__3 RETURNS DECFLOAT(34) BY VALUE ENTRY_POINT 'IB_UDF_abs' MODULE_NAME 'ib_udf'; DECLARE EXTERNAL FUNCTION UDF_DUMMY6__3 RETURNS TIMESTAMP WITH TIME ZONE BY VALUE ENTRY_POINT 'IB_UDF_abs' MODULE_NAME 'ib_udf'; DECLARE EXTERNAL FUNCTION UDF_DUMMY6__3 RETURNS TIME WITH TIME ZONE BY VALUE ENTRY_POINT 'IB_UDF_abs' MODULE_NAME 'ib_udf'; ISQL returns for all the cases: Statement failed, SQLSTATE = HY000 unsuccessful metadata update -CREATE FUNCTION UDF_DUMMY6__3 failed -SQL error code = -607 -Invalid command -Return mode by value not allowed for this data type --- src/dsql/DdlNodes.epp | 47 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/src/dsql/DdlNodes.epp b/src/dsql/DdlNodes.epp index 8652cb7b7b7..0faea8633ee 100644 --- a/src/dsql/DdlNodes.epp +++ b/src/dsql/DdlNodes.epp @@ -1902,16 +1902,45 @@ bool CreateAlterFunctionNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch* // CVC: This is case of "returns [by value|reference]". // Some data types can not be returned as value. - if (returnType->udfMechanism.value == FUN_value && - (field->dtype == dtype_text || field->dtype == dtype_varying || - field->dtype == dtype_cstring || field->dtype == dtype_blob || - field->dtype == dtype_timestamp)) + if (returnType->udfMechanism.value == FUN_value) { - // Return mode by value not allowed for this data type. - status_exception::raise( - Arg::Gds(isc_sqlerr) << Arg::Num(-607) << - Arg::Gds(isc_dsql_command_err) << - Arg::Gds(isc_return_mode_err)); + switch(field->dtype) + { + case dtype_short: + case dtype_long: + case dtype_int64: + case dtype_real: + case dtype_double: + case dtype_d_float: //deprecated + case dtype_boolean: + case dtype_sql_date: + case dtype_sql_time: + break; + case dtype_text: + case dtype_varying: + case dtype_cstring: + case dtype_blob: + case dtype_timestamp: + case dtype_dec64: + case dtype_dec128: + case dtype_int128: //it is a structure + case dtype_timestamp_tz: + case dtype_sql_time_tz: + { + // Return mode by value not allowed for this data type. + status_exception::raise( + Arg::Gds(isc_sqlerr) << Arg::Num(-607) << + Arg::Gds(isc_dsql_command_err) << + Arg::Gds(isc_return_mode_err)); + } + default: + { + fb_assert(false); // it is an abnormal situation + status_exception::raise( + Arg::Gds(isc_sqlerr) << Arg::Num(-607) << + Arg::Gds(isc_random) << Arg::Str("UDF returns an unknown data type")); + } + } } // For functions returning a blob, coerce return argument position to