add proc: bin_to_num

This commit is contained in:
JulianZhang
2024-09-22 11:09:48 +08:00
parent a4c143a2e4
commit d5cd7adb9a
11 changed files with 247 additions and 2 deletions

View File

@ -511,6 +511,11 @@
AddFuncGroup(
"bigint_tid", 1,
AddBuiltinFunc(_0(3214), _1("bigint_tid"), _2(1), _3(true), _4(false), _5(bigint_tid), _6(27), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 20), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("bigint_tid"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0))
),
AddFuncGroup(
"bin_to_num", 2,
AddBuiltinFunc(_0(971), _1("bin_to_num"), _2(1), _3(true), _4(false), _5(bin_to_num), _6(1700), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(0), _11(0), _12(1700), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 1231), _21(1,1231), _22(1,'v'), _23(NULL), _24(NULL), _25("bin_to_num"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("convert bits to number"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(1,1231)),
AddBuiltinFunc(_0(974), _1("bin_to_num"), _2(0), _3(false), _4(false), _5(bin_to_num_noparam), _6(1700), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(0), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(0), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("bin_to_num_noparam"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("convert bits to number"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0))
),
AddFuncGroup(
"bit", 3,

View File

@ -7971,6 +7971,58 @@ Datum numtodsinterval(PG_FUNCTION_ARGS)
CHECK_RETNULL_RETURN_DATUM(result);
}
/* Convert binary array to number*/
Datum bin_to_num(PG_FUNCTION_ARGS)
{
int i;
Numeric arg;
double argD;
int32 argI;
Datum result = DirectFunctionCall1(int4_numeric, Int32GetDatum(0));
ArrayType* arr = PG_GETARG_ARRAYTYPE_P(0);
Datum *elemValues;
bool *elemNulls;
int elemCount;
deconstruct_array(arr, NUMERICOID, -1, false, 'i', &elemValues, &elemNulls, &elemCount);
for (i = 0; i < elemCount; i++) {
if (elemNulls[i]) {
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("illegal argument for function")));
}
arg = DatumGetNumeric(elemValues[i]);
argD = numeric_to_double_no_overflow(arg);
if (argD > INT32_MAX) {
argI = INT32_MAX;
} else if (argD < INT32_MIN) {
argI = INT32_MIN;
} else {
argI = (argD < 0) ? ceil(argD) : floor(argD);
}
if (argI == 0) {
result = DirectFunctionCall2(numeric_add, result, result);
} else if (argI == 1) {
result = DirectFunctionCall2(numeric_add, result, result);
result = DirectFunctionCall1(numeric_inc, result);
} else {
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("argument %d is out of range", argI)));
}
}
PG_RETURN_DATUM(result);
}
/* Convert binary array to number*/
Datum bin_to_num_noparam(PG_FUNCTION_ARGS)
{
PG_RETURN_NUMERIC(make_result(&const_zero));
}
/* Convert numeric to interval */
Datum numeric_interval(PG_FUNCTION_ARGS)
{

View File

@ -77,7 +77,7 @@ bool will_shutdown = false;
*
********************************************/
const uint32 GRAND_VERSION_NUM = 93008;
const uint32 GRAND_VERSION_NUM = 93009;
/********************************************
* 2.VERSION NUM FOR EACH FEATURE

View File

@ -0,0 +1,2 @@
DROP FUNCTION IF EXISTS pg_catalog.bin_to_num(VARIADIC bins numeric[]) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.bin_to_num() CASCADE;

View File

@ -0,0 +1,2 @@
DROP FUNCTION IF EXISTS pg_catalog.bin_to_num(VARIADIC bins numeric[]) CASCADE;
DROP FUNCTION IF EXISTS pg_catalog.bin_to_num() CASCADE;

View File

@ -0,0 +1,6 @@
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 971;
CREATE OR REPLACE FUNCTION pg_catalog.bin_to_num(VARIADIC bins numeric[])
RETURNS numeric LANGUAGE INTERNAL VOLATILE STRICT as 'bin_to_num';
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 974;
CREATE OR REPLACE FUNCTION pg_catalog.bin_to_num()
RETURNS numeric LANGUAGE INTERNAL VOLATILE as 'bin_to_num_noparam';

View File

@ -0,0 +1,6 @@
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 971;
CREATE OR REPLACE FUNCTION pg_catalog.bin_to_num(VARIADIC bins numeric[])
RETURNS numeric LANGUAGE INTERNAL VOLATILE STRICT as 'bin_to_num';
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 974;
CREATE OR REPLACE FUNCTION pg_catalog.bin_to_num()
RETURNS numeric LANGUAGE INTERNAL VOLATILE as 'bin_to_num_noparam';

View File

@ -197,6 +197,8 @@ extern bool numeric_is_nan(Numeric num);
int32 numeric_maximum_size(int32 typmod);
extern char* numeric_out_sci(Numeric num, int scale);
extern Datum numtodsinterval(PG_FUNCTION_ARGS);
extern Datum bin_to_num(PG_FUNCTION_ARGS);
extern Datum bin_to_num_noparam(PG_FUNCTION_ARGS);
extern int cmp_numerics(Numeric num1, Numeric num2);
extern int128 numeric_int16_internal(Numeric num);
extern char* output_numeric_out(Numeric num);

View File

@ -396,6 +396,144 @@ from varlentype order by col_int;
drop table type;
drop table varlentype;
drop table time;
-- test function bin_to_num
select bin_to_num(1,0,0);
bin_to_num
------------
4
(1 row)
select bin_to_num('1',0,0);
bin_to_num
------------
4
(1 row)
select bin_to_num('1',2-1,0);
bin_to_num
------------
6
(1 row)
select bin_to_num(NULL);
ERROR: illegal argument for function
CONTEXT: referenced column: bin_to_num
select bin_to_num();
bin_to_num
------------
0
(1 row)
select bin_to_num('a','b');
ERROR: invalid input syntax for type numeric: "a"
LINE 1: select bin_to_num('a','b');
^
CONTEXT: referenced column: bin_to_num
select bin_to_num(-2.9);
ERROR: argument -2 is out of range
CONTEXT: referenced column: bin_to_num
select bin_to_num(-2.1);
ERROR: argument -2 is out of range
CONTEXT: referenced column: bin_to_num
select bin_to_num(-2.0);
ERROR: argument -2 is out of range
CONTEXT: referenced column: bin_to_num
select bin_to_num(-1.9);
ERROR: argument -1 is out of range
CONTEXT: referenced column: bin_to_num
select bin_to_num(-1.1);
ERROR: argument -1 is out of range
CONTEXT: referenced column: bin_to_num
select bin_to_num(-1.0);
ERROR: argument -1 is out of range
CONTEXT: referenced column: bin_to_num
select bin_to_num(-0.9);
bin_to_num
------------
0
(1 row)
select bin_to_num(-0.1);
bin_to_num
------------
0
(1 row)
select bin_to_num(-0.0);
bin_to_num
------------
0
(1 row)
select bin_to_num(0.0);
bin_to_num
------------
0
(1 row)
select bin_to_num(0.1);
bin_to_num
------------
0
(1 row)
select bin_to_num(0.9);
bin_to_num
------------
0
(1 row)
select bin_to_num(1.0);
bin_to_num
------------
1
(1 row)
select bin_to_num(1.1);
bin_to_num
------------
1
(1 row)
select bin_to_num(1.4);
bin_to_num
------------
1
(1 row)
select bin_to_num(1.5);
bin_to_num
------------
1
(1 row)
select bin_to_num(1.6);
bin_to_num
------------
1
(1 row)
select bin_to_num(1.9);
bin_to_num
------------
1
(1 row)
select bin_to_num(2.0);
ERROR: argument 2 is out of range
CONTEXT: referenced column: bin_to_num
select bin_to_num(2.1);
ERROR: argument 2 is out of range
CONTEXT: referenced column: bin_to_num
select bin_to_num(2.9);
ERROR: argument 2 is out of range
CONTEXT: referenced column: bin_to_num
select bin_to_num(9999999999000);
ERROR: argument 2147483647 is out of range
CONTEXT: referenced column: bin_to_num
select bin_to_num(-9999999999000);
ERROR: argument -2147483648 is out of range
CONTEXT: referenced column: bin_to_num
-- tests for repeat
-- create table at first
create table test_null_repeat(id int, col2 text);

View File

@ -1,6 +1,7 @@
select provariadic,oid, proname from pg_proc where arraycontains(proargmodes::char[],ARRAY['v'::char]) order by oid;
provariadic | oid | proname
-------------+------+-------------------------------------
1700 | 971 | bin_to_num
2276 | 3058 | concat
2276 | 3059 | concat_ws
1185 | 3119 | standby_statement_history
@ -26,7 +27,7 @@ select provariadic,oid, proname from pg_proc where arraycontains(proargmodes::ch
2276 | 7107 | db4ai_predict_by_numeric
2276 | 7108 | db4ai_predict_by_text
2276 | 7109 | db4ai_predict_by_float8_array
(25 rows)
(26 rows)
select prokind,length(prokind),count(*) from pg_proc where oid < 16384 group by prokind;
prokind | length | count

View File

@ -178,6 +178,37 @@ drop table type;
drop table varlentype;
drop table time;
-- test function bin_to_num
select bin_to_num(1,0,0);
select bin_to_num('1',0,0);
select bin_to_num('1',2-1,0);
select bin_to_num(NULL);
select bin_to_num();
select bin_to_num('a','b');
select bin_to_num(-2.9);
select bin_to_num(-2.1);
select bin_to_num(-2.0);
select bin_to_num(-1.9);
select bin_to_num(-1.1);
select bin_to_num(-1.0);
select bin_to_num(-0.9);
select bin_to_num(-0.1);
select bin_to_num(-0.0);
select bin_to_num(0.0);
select bin_to_num(0.1);
select bin_to_num(0.9);
select bin_to_num(1.0);
select bin_to_num(1.1);
select bin_to_num(1.4);
select bin_to_num(1.5);
select bin_to_num(1.6);
select bin_to_num(1.9);
select bin_to_num(2.0);
select bin_to_num(2.1);
select bin_to_num(2.9);
select bin_to_num(9999999999000);
select bin_to_num(-9999999999000);
-- tests for repeat
-- create table at first
create table test_null_repeat(id int, col2 text);