Make the div function use bigint for inputs and output
This commit is contained in:
parent
6064402f85
commit
2c9b46512b
@ -3,9 +3,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
create or alter function div (
|
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;
|
external name 'MyFirstUDRKit!MFK_div!Divide anumerator by adenominator' engine udr;
|
||||||
grant execute on function div to public;
|
grant execute on function div to public;
|
||||||
|
|
||||||
|
@ -11,9 +11,9 @@ begin
|
|||||||
|
|
||||||
|
|
||||||
function div (
|
function div (
|
||||||
anumerator integer, adenominator integer
|
anumerator bigint, adenominator bigint
|
||||||
)
|
)
|
||||||
returns double precision;
|
returns bigint;
|
||||||
|
|
||||||
function flagged (
|
function flagged (
|
||||||
flags integer, flag integer
|
flags integer, flag integer
|
||||||
@ -34,9 +34,9 @@ as
|
|||||||
begin
|
begin
|
||||||
|
|
||||||
function div (
|
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;
|
external name 'MyFirstUDRKit!MFK_div!Divide anumerator by adenominator' engine udr;
|
||||||
|
|
||||||
function flagged (
|
function flagged (
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#ifdef HAVE_MATH_H
|
#ifdef HAVE_MATH_H
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@ -78,23 +79,25 @@ using namespace Firebird;
|
|||||||
|
|
||||||
/***
|
/***
|
||||||
* create function div (
|
* create function div (
|
||||||
* anumerator integer,
|
* anumerator bigint,
|
||||||
* adenominator integer
|
* adenominator bigint
|
||||||
* ) returns double precision
|
* ) returns bigint
|
||||||
* external name 'MyFirstUDRKit!MFK_div!Divide anumerator by adenominator'
|
* external name 'MyFirstUDRKit!MFK_div!Divide anumerator by adenominator'
|
||||||
* engine udr;
|
* engine udr;
|
||||||
***/
|
***/
|
||||||
FB_UDR_BEGIN_FUNCTION(MFK_div)
|
FB_UDR_BEGIN_FUNCTION(MFK_div)
|
||||||
|
|
||||||
// Divide integer anumerator 1 by integer adenominator using the stdlib
|
// 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_UDR_MESSAGE(InMessage,
|
||||||
(FB_INTEGER, anumerator)
|
(FB_BIGINT, anumerator)
|
||||||
(FB_INTEGER, adenominator)
|
(FB_BIGINT, adenominator)
|
||||||
);
|
);
|
||||||
|
|
||||||
FB_UDR_MESSAGE(OutMessage,
|
FB_UDR_MESSAGE(OutMessage,
|
||||||
(FB_DOUBLE, result)
|
(FB_BIGINT, result)
|
||||||
);
|
);
|
||||||
|
|
||||||
FB_UDR_EXECUTE_FUNCTION
|
FB_UDR_EXECUTE_FUNCTION
|
||||||
@ -108,12 +111,11 @@ FB_UDR_EXECUTE_FUNCTION
|
|||||||
{
|
{
|
||||||
out->resultNull = FB_FALSE;
|
out->resultNull = FB_FALSE;
|
||||||
if (in->adenominator) {
|
if (in->adenominator) {
|
||||||
out->result = div(in->anumerator, in->adenominator).quot;
|
out->result = std::div(in->anumerator, in->adenominator).quot;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// This is old style - surely we can do better?
|
out->result = int( std::numeric_limits<double>::infinity() );
|
||||||
out->result = std::numeric_limits<double>::infinity();
|
|
||||||
ISC_STATUS_ARRAY StatusVector = {isc_arg_gds, isc_arith_except,
|
ISC_STATUS_ARRAY StatusVector = {isc_arg_gds, isc_arith_except,
|
||||||
isc_arg_gds, isc_exception_integer_divide_by_zero, isc_arg_end};
|
isc_arg_gds, isc_exception_integer_divide_by_zero, isc_arg_end};
|
||||||
FbException::check(isc_exception_integer_divide_by_zero, status, StatusVector);
|
FbException::check(isc_exception_integer_divide_by_zero, status, StatusVector);
|
||||||
@ -121,7 +123,7 @@ FB_UDR_EXECUTE_FUNCTION
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
FB_UDR_END_FUNCTION
|
FB_UDR_END_FUNCTION
|
||||||
|
//END
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -130,11 +132,13 @@ create function flagged (
|
|||||||
flags integer,
|
flags integer,
|
||||||
flag integer
|
flag integer
|
||||||
) returns 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;
|
engine udr;
|
||||||
|
|
||||||
***/
|
***/
|
||||||
FB_UDR_BEGIN_FUNCTION(MFK_flagged)
|
FB_UDR_BEGIN_FUNCTION (MFK_flagged)
|
||||||
FB_UDR_MESSAGE(InMessage,
|
//BEGIN
|
||||||
|
FB_UDR_MESSAGE(InMessage,
|
||||||
(FB_INTEGER, flags)
|
(FB_INTEGER, flags)
|
||||||
(FB_INTEGER, flag)
|
(FB_INTEGER, flag)
|
||||||
);
|
);
|
||||||
@ -145,10 +149,6 @@ FB_UDR_BEGIN_FUNCTION(MFK_flagged)
|
|||||||
|
|
||||||
FB_UDR_EXECUTE_FUNCTION
|
FB_UDR_EXECUTE_FUNCTION
|
||||||
{
|
{
|
||||||
// Original code
|
|
||||||
// if ( flags == NULL ) {
|
|
||||||
// return 0;
|
|
||||||
// }
|
|
||||||
if ( in->flagsNull != 0 ) {
|
if ( in->flagsNull != 0 ) {
|
||||||
out->resultNull = FB_TRUE;
|
out->resultNull = FB_TRUE;
|
||||||
out->result = 0;
|
out->result = 0;
|
||||||
@ -156,17 +156,12 @@ FB_UDR_BEGIN_FUNCTION(MFK_flagged)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
out->resultNull = FB_FALSE;
|
out->resultNull = FB_FALSE;
|
||||||
// Original code
|
|
||||||
// ISC_UINT64 i = ( 1ULL << *flag );
|
|
||||||
// return ( *flags & i ) ? 1 : 0;
|
|
||||||
ISC_UINT64 i = ( 1ULL << in->flag );
|
ISC_UINT64 i = ( 1ULL << in->flag );
|
||||||
out->result = ( in->flags & i ) ? 1 : 0;
|
out->result = ( in->flags & i ) ? 1 : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FB_UDR_END_FUNCTION
|
FB_UDR_END_FUNCTION
|
||||||
|
//END
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*** DDL
|
/*** DDL
|
||||||
* create or alter function LoadBlobFromFile (
|
* create or alter function LoadBlobFromFile (
|
||||||
|
@ -6,14 +6,16 @@
|
|||||||
create sequence test_div_seq;
|
create sequence test_div_seq;
|
||||||
commit;
|
commit;
|
||||||
create domain D_ID as BIGINT;
|
create domain D_ID as BIGINT;
|
||||||
create domain D_DOUBLE as double precision;
|
|
||||||
create domain D_BIGINT as BIGINT;
|
create domain D_BIGINT as BIGINT;
|
||||||
|
|
||||||
create table test_div(
|
create table test_div(
|
||||||
test_div_id d_id generated always as identity
|
test_div_id d_id generated always as identity
|
||||||
, numerator D_BIGINT
|
, numerator D_BIGINT
|
||||||
, denominator D_BIGINT
|
, denominator D_BIGINT
|
||||||
, result D_DOUBLE
|
, result COMPUTED BY ( DIV(numerator, denominator) )
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
commit;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user