8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 00:43:03 +01:00

Enhance UDF support a bit

This commit is contained in:
robocop 2004-08-27 04:58:10 +00:00
parent a38df7177b
commit 1c981d6a83

View File

@ -30,7 +30,7 @@
* 2003.08.10 Claudio Valderrama: Fix SF Bugs #544132 and #728839. * 2003.08.10 Claudio Valderrama: Fix SF Bugs #544132 and #728839.
*/ */
/* /*
$Id: fun.epp,v 1.64 2004-08-21 09:36:53 robocop Exp $ $Id: fun.epp,v 1.65 2004-08-27 04:58:10 robocop Exp $
*/ */
#include "firebird.h" #include "firebird.h"
@ -258,15 +258,23 @@ void FUN_evaluate(UserFunction* function, jrd_nod* node, impure_value* value)
arg_ptr = reinterpret_cast<UDF_ARG*>(p); arg_ptr = reinterpret_cast<UDF_ARG*>(p);
continue; continue;
} }
else if (tail->fun_mechanism != FUN_ref_with_null)
MOVE_CLEAR(temp_ptr, (SLONG) length);
else else
{ {
MOVE_CLEAR(temp_ptr, (SLONG) length);
// CVC: Replace the previous line by these two and you'll have
// an engine that sends the null pointer for NULL input values.
// Probably for arrays and blobs it's better to preserve the // Probably for arrays and blobs it's better to preserve the
// current behavior that sends a zeroed memory chunk. // current behavior that sends a zeroed memory chunk.
//*arg_ptr++ = 0; switch (tail->fun_desc.dsc_dtype)
//continue; {
case dtype_quad:
case dtype_array:
case dtype_blob:
MOVE_CLEAR(temp_ptr, (SLONG) length);
break;
default: // FUN_ref_with_null, non-blob, non-array: we send null pointer.
*arg_ptr++ = 0;
continue;
}
} }
} }
else if ((SSHORT) abs(tail->fun_mechanism) == FUN_scalar_array) else if ((SSHORT) abs(tail->fun_mechanism) == FUN_scalar_array)
@ -527,8 +535,8 @@ void FUN_evaluate(UserFunction* function, jrd_nod* node, impure_value* value)
// Udfs work in the assumption that they ignore that the handle is the real // Udfs work in the assumption that they ignore that the handle is the real
// internal blob and this has been always the tale. // internal blob and this has been always the tale.
if (temp_ptr == NULL || function->fun_return_arg && if (temp_ptr == NULL || function->fun_return_arg &&
(return_ptr->fun_mechanism == FUN_descriptor && (value->vlu_desc.dsc_flags & DSC_null) (abs(return_ptr->fun_mechanism) == FUN_descriptor && (value->vlu_desc.dsc_flags & DSC_null)
|| return_ptr->fun_mechanism == FUN_blob_struct && return_blob_struct && || abs(return_ptr->fun_mechanism) == FUN_blob_struct && return_blob_struct &&
!return_blob_struct->blob_handle)) !return_blob_struct->blob_handle))
{ {
request->req_flags |= req_null; request->req_flags |= req_null;
@ -1042,15 +1050,21 @@ static void invoke(UserFunction* function,
// The assumption is that the user didn't modify the return type, // The assumption is that the user didn't modify the return type,
// that has no sense after all, because it is carved in stone. // that has no sense after all, because it is carved in stone.
dsc* return_dsc = 0; dsc* return_dsc = 0;
if (return_ptr->fun_mechanism == FUN_descriptor) bool null_signaled = false;
if (abs(return_ptr->fun_mechanism) == FUN_descriptor)
{ {
// The formal param's type is contained in value->vlu_desc.dsc_dtype // The formal param's type is contained in value->vlu_desc.dsc_dtype
// but I want to know if the UDF changed it to a compatible type // but I want to know if the UDF changed it to a compatible type
// from its returned descriptor, that will be return_dsc. // from its returned descriptor, that will be return_dsc.
return_dsc = reinterpret_cast<DSC*>(temp_ptr); return_dsc = reinterpret_cast<DSC*>(temp_ptr);
temp_ptr = return_dsc->dsc_address; temp_ptr = return_dsc->dsc_address;
if (!temp_ptr || (return_dsc->dsc_flags & DSC_null))
{
null_signaled = true;
value->vlu_desc.dsc_flags |= DSC_null;
} }
if (temp_ptr) }
if (!null_signaled)
{ {
switch (value->vlu_desc.dsc_dtype) switch (value->vlu_desc.dsc_dtype)
{ {
@ -1157,13 +1171,14 @@ static void invoke(UserFunction* function,
unsup_datatype = true; unsup_datatype = true;
break; break;
} }
}
// check if this is function has the FREE_IT set, if set and // check if this is function has the FREE_IT set, if set and
// return_value is not null, then free the return value // return_value is not null, then free the return value
if (((SLONG) return_ptr->fun_mechanism < 0) && temp_ptr) if ((SLONG) return_ptr->fun_mechanism < 0 && temp_ptr)
{ {
free(temp_ptr); free(temp_ptr);
} }
}
// CVC: Let's free the descriptor, too. // CVC: Let's free the descriptor, too.
if (return_dsc) if (return_dsc)
free(return_dsc); free(return_dsc);