diff --git a/sql/MyFirstUDRKit.ddl b/sql/MyFirstUDRKit.ddl index e763bb7..dba3aa8 100644 --- a/sql/MyFirstUDRKit.ddl +++ b/sql/MyFirstUDRKit.ddl @@ -3,9 +3,9 @@ */ create or alter function div ( - anumerator integer, adenominator integer + anumerator bigint, adenominator bigint ) -returns double precision +returns bigint external name 'MyFirstUDRKit!MFK_div!Divide anumerator by adenominator' engine udr; grant execute on function div to public; diff --git a/sql/MyFirstUDRKitPackage.sql b/sql/MyFirstUDRKitPackage.sql index 52c78bb..c11018a 100644 --- a/sql/MyFirstUDRKitPackage.sql +++ b/sql/MyFirstUDRKitPackage.sql @@ -11,9 +11,9 @@ begin function div ( - anumerator integer, adenominator integer + anumerator bigint, adenominator bigint ) - returns double precision; + returns bigint; function flagged ( flags integer, flag integer @@ -34,9 +34,9 @@ as begin function div ( - anumerator integer, adenominator integer - ) - returns double precision + anumerator bigint, adenominator bigint + ) + returns bigint external name 'MyFirstUDRKit!MFK_div!Divide anumerator by adenominator' engine udr; function flagged ( diff --git a/src/MyFirstUDRKit.cpp b/src/MyFirstUDRKit.cpp index 1bb95b0..faac21b 100644 --- a/src/MyFirstUDRKit.cpp +++ b/src/MyFirstUDRKit.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #ifdef HAVE_MATH_H #include @@ -78,23 +79,25 @@ using namespace Firebird; /*** * create function div ( - * anumerator integer, - * adenominator integer - * ) returns double precision + * anumerator bigint, + * adenominator bigint + * ) returns bigint * external name 'MyFirstUDRKit!MFK_div!Divide anumerator by adenominator' * engine udr; ***/ FB_UDR_BEGIN_FUNCTION(MFK_div) // Divide integer anumerator 1 by integer adenominator using the stdlib - +// Note this differs from the example that shifts with firebird as it returns +// a bigint, not a double precision +//BEGIN FB_UDR_MESSAGE(InMessage, - (FB_INTEGER, anumerator) - (FB_INTEGER, adenominator) + (FB_BIGINT, anumerator) + (FB_BIGINT, adenominator) ); FB_UDR_MESSAGE(OutMessage, - (FB_DOUBLE, result) + (FB_BIGINT, result) ); FB_UDR_EXECUTE_FUNCTION @@ -108,12 +111,11 @@ FB_UDR_EXECUTE_FUNCTION { out->resultNull = FB_FALSE; if (in->adenominator) { - out->result = div(in->anumerator, in->adenominator).quot; + out->result = std::div(in->anumerator, in->adenominator).quot; } else { -// This is old style - surely we can do better? - out->result = std::numeric_limits::infinity(); + out->result = int( std::numeric_limits::infinity() ); ISC_STATUS_ARRAY StatusVector = {isc_arg_gds, isc_arith_except, isc_arg_gds, isc_exception_integer_divide_by_zero, isc_arg_end}; FbException::check(isc_exception_integer_divide_by_zero, status, StatusVector); @@ -121,7 +123,7 @@ FB_UDR_EXECUTE_FUNCTION } } FB_UDR_END_FUNCTION - +//END @@ -130,11 +132,13 @@ create function flagged ( flags integer, flag integer ) returns integer - external name 'MyFirstUDRKit!MFK_flagged!How is this function used?' + external name 'MyFirstUDRKit!MFK_flagged!Check if flag is set in flags. flag is zero-based.' engine udr; + ***/ -FB_UDR_BEGIN_FUNCTION(MFK_flagged) - FB_UDR_MESSAGE(InMessage, +FB_UDR_BEGIN_FUNCTION (MFK_flagged) +//BEGIN +FB_UDR_MESSAGE(InMessage, (FB_INTEGER, flags) (FB_INTEGER, flag) ); @@ -145,10 +149,6 @@ FB_UDR_BEGIN_FUNCTION(MFK_flagged) FB_UDR_EXECUTE_FUNCTION { -// Original code -// if ( flags == NULL ) { -// return 0; -// } if ( in->flagsNull != 0 ) { out->resultNull = FB_TRUE; out->result = 0; @@ -156,17 +156,12 @@ FB_UDR_BEGIN_FUNCTION(MFK_flagged) else { out->resultNull = FB_FALSE; -// Original code -// ISC_UINT64 i = ( 1ULL << *flag ); -// return ( *flags & i ) ? 1 : 0; ISC_UINT64 i = ( 1ULL << in->flag ); out->result = ( in->flags & i ) ? 1 : 0; } } FB_UDR_END_FUNCTION - - - +//END /*** DDL * create or alter function LoadBlobFromFile ( diff --git a/test/testudrkit.ddl b/test/testudrkit.ddl index 945f1d9..be8ffec 100644 --- a/test/testudrkit.ddl +++ b/test/testudrkit.ddl @@ -6,14 +6,16 @@ create sequence test_div_seq; commit; create domain D_ID as BIGINT; -create domain D_DOUBLE as double precision; create domain D_BIGINT as BIGINT; create table test_div( test_div_id d_id generated always as identity , numerator D_BIGINT , denominator D_BIGINT - , result D_DOUBLE + , result COMPUTED BY ( DIV(numerator, denominator) ) + ); +commit; +