diff --git a/contrib/babelfishpg_tds/src/backend/tds/tdsresponse.c b/contrib/babelfishpg_tds/src/backend/tds/tdsresponse.c index ab674d84bf..9fa76a8d35 100644 --- a/contrib/babelfishpg_tds/src/backend/tds/tdsresponse.c +++ b/contrib/babelfishpg_tds/src/backend/tds/tdsresponse.c @@ -24,8 +24,10 @@ #include "catalog/pg_proc.h" #include "catalog/pg_type.h" #include "miscadmin.h" +#include "nodes/makefuncs.h" #include "nodes/pathnodes.h" #include "parser/parse_coerce.h" +#include "parser/parse_type.h" #include "parser/parsetree.h" #include "utils/fmgroids.h" #include "utils/lsyscache.h" @@ -126,6 +128,7 @@ static TdsColumnMetaData *colMetaData = NULL; static List *relMetaDataInfoList = NULL; static Oid sys_vector_oid = InvalidOid; +static Oid decimal_oid = InvalidOid; static void FillTabNameWithNumParts(StringInfo buf, uint8 numParts, TdsRelationMetaDataInfo relMetaDataInfo); static void FillTabNameWithoutNumParts(StringInfo buf, uint8 numParts, TdsRelationMetaDataInfo relMetaDataInfo); @@ -511,6 +514,24 @@ resolve_numeric_typmod_outer_var(Plan *plan, AttrNumber attno) return resolve_numeric_typmod_from_exp(outerplan, (Node *)tle->expr); } +/* + * is_numeric_datatype - returns bool if given datatype is numeric or decimal. + */ +static bool +is_numeric_datatype(Oid typid) +{ + if (typid == NUMERICOID) + { + return true; + } + if (!OidIsValid(decimal_oid)) + { + TypeName *typename = makeTypeNameFromNameList(list_make2(makeString("sys"), makeString("decimal"))); + decimal_oid = LookupTypeNameOid(NULL, typename, false); + } + return decimal_oid == typid; +} + /* look for a typmod to return from a numeric expression */ static int32 resolve_numeric_typmod_from_exp(Plan *plan, Node *expr) @@ -524,15 +545,10 @@ resolve_numeric_typmod_from_exp(Plan *plan, Node *expr) Const *con = (Const *) expr; Numeric num; - /* - * TODO: We used a workaround here, that we will assume typmod - * is 0 if the value we have is not numeric. See walkaround in - * T_FuncExpr part of this function. JIRA: BABEL-1007 - */ - if (con->consttype != NUMERICOID || con->constisnull) + if (!is_numeric_datatype(con->consttype) || con->constisnull) { - return 0; - /* Typmod doesn 't really matter since it' s a const NULL. */ + /* typmod is undefined */ + return -1; } else { diff --git a/test/JDBC/expected/babel_numeric.out b/test/JDBC/expected/babel_numeric.out index 40988a6857..8d3bb92a09 100644 --- a/test/JDBC/expected/babel_numeric.out +++ b/test/JDBC/expected/babel_numeric.out @@ -121,3 +121,368 @@ numeric drop table t1; go + +select * from +( + select cast(1.23 as decimal(18,2)) as col + union all + select cast(1.23 as decimal(7,2)) as col +) dummy order by col; +go +~~START~~ +numeric +1.23 +1.23 +~~END~~ + + +select * from +( + select cast(NULL as decimal(18,2)) as col + union all + select cast(1.23 as decimal(7,2)) as col +) dummy order by col; +go +~~START~~ +numeric + +1.23 +~~END~~ + + +select * from +( + select cast(9999999999999999.99 as decimal(18,2)) as col + union all + select cast(99999.99 as decimal(7,2)) as col +) dummy order by col; +go +~~START~~ +numeric +99999.99 +9999999999999999.99 +~~END~~ + + +create type decimal_18_2 from decimal(18,2); +go + +create type decimal_7_2 from decimal(7,2); +go + +select * from +( + select cast(1.23 as decimal_18_2) as col + union all + select cast(1.23 as decimal_7_2) as col +) dummy order by col; +go +~~START~~ +numeric +1.23 +1.23 +~~END~~ + + +select * from +( + select cast(1.23 as decimal_18_2) as col + union all + select cast(NULL as decimal_7_2) as col +) dummy order by col; +go +~~START~~ +numeric + +1.23 +~~END~~ + + +select * from +( + select cast(9999999999999999.99 as decimal_18_2) as col + union all + select cast(99999.99 as decimal_7_2) as col +) dummy order by col; +go +~~START~~ +numeric +99999.99 +9999999999999999.99 +~~END~~ + + +create table babel_5086_t1 (a decimal(18,2), b decimal(7,2), c decimal_18_2, d decimal_7_2); +go + +insert into babel_5086_t1 values (1.23, 1.23, 1.23, 1.23); +insert into babel_5086_t1 values (9999999999999999.99, NULL, 9999999999999999.99, NULL); +insert into babel_5086_t1 values (NULL, 99999.99, NULL, 99999.99); +go +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +select * from +( + select a as col from babel_5086_t1 + union all + select b as col from babel_5086_t1 +) dummy order by col; +go +~~START~~ +numeric + + +1.23 +1.23 +99999.99 +9999999999999999.99 +~~END~~ + + +select * from +( + select c as col from babel_5086_t1 + union all + select d as col from babel_5086_t1 +) dummy order by col; +go +~~START~~ +numeric + + +1.23000000 +1.23000000 +99999.99000000 +9999999999999999.99000000 +~~END~~ + + +select * from +( + select a as col from babel_5086_t1 + union all + select b as col from babel_5086_t1 + union all + select c as col from babel_5086_t1 + union all + select d as col from babel_5086_t1 +) dummy order by col; +go +~~START~~ +numeric + + + + +1.23 +1.23 +1.23 +1.23 +99999.99 +99999.99 +9999999999999999.99 +9999999999999999.99 +~~END~~ + + +select * from +( + select a as col from babel_5086_t1 + union all + select c as col from babel_5086_t1 +) dummy order by col; +go +~~START~~ +numeric + + +1.23 +1.23 +9999999999999999.99 +9999999999999999.99 +~~END~~ + + +select * from +( + select b as col from babel_5086_t1 + union all + select d as col from babel_5086_t1 +) dummy order by col; +go +~~START~~ +numeric + + +1.23 +1.23 +99999.99 +99999.99 +~~END~~ + + +create type numeric_18_2 from numeric(18,2); +go + +create type numeric_7_2 from numeric(7,2); +go + +select * from +( + select cast(1.23 as numeric_18_2) as col + union all + select cast(1.23 as numeric_7_2) as col +) dummy order by col; +go +~~START~~ +numeric +1.23 +1.23 +~~END~~ + + +select * from +( + select cast(12344.234 as numeric_18_2) as col + union all + select cast(1.23 as numeric_7_2) as col +) dummy order by col; +go +~~START~~ +numeric +1.23 +12344.23 +~~END~~ + + +create table babel_5086_t2 (a numeric(18,2), b numeric(7,2), c numeric_18_2, d numeric_7_2); +go + +insert into babel_5086_t2 values (1.23, 1.23, 1.23, 1.23); +insert into babel_5086_t2 values (9999999999999999.99, NULL, 9999999999999999.99, NULL); +insert into babel_5086_t2 values (NULL, 99999.99, NULL, 99999.99); +go +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +select * from +( + select a as col from babel_5086_t2 + union all + select b as col from babel_5086_t2 +) dummy order by col; +go +~~START~~ +numeric + + +1.23 +1.23 +99999.99 +9999999999999999.99 +~~END~~ + + +select * from +( + select c as col from babel_5086_t2 + union all + select d as col from babel_5086_t2 +) dummy order by col; +go +~~START~~ +numeric + + +1.23000000 +1.23000000 +99999.99000000 +9999999999999999.99000000 +~~END~~ + + +select * from +( + select a as col from babel_5086_t2 + union all + select b as col from babel_5086_t2 + union all + select c as col from babel_5086_t2 + union all + select d as col from babel_5086_t2 +) dummy order by col; +go +~~START~~ +numeric + + + + +1.23 +1.23 +1.23 +1.23 +99999.99 +99999.99 +9999999999999999.99 +9999999999999999.99 +~~END~~ + + +select * from +( + select a as col from babel_5086_t2 + union all + select c as col from babel_5086_t2 +) dummy order by col; +go +~~START~~ +numeric + + +1.23 +1.23 +9999999999999999.99 +9999999999999999.99 +~~END~~ + + + +select * from +( + select b as col from babel_5086_t2 + union all + select d as col from babel_5086_t2 +) dummy order by col; +go +~~START~~ +numeric + + +1.23 +1.23 +99999.99 +99999.99 +~~END~~ + + +drop table babel_5086_t1; +go + +drop table babel_5086_t2; +go + +drop type decimal_18_2; +drop type decimal_7_2; +drop type numeric_18_2; +drop type numeric_7_2; +go diff --git a/test/JDBC/input/babel_numeric.sql b/test/JDBC/input/babel_numeric.sql index 2dab904ac1..5717e3e540 100644 --- a/test/JDBC/input/babel_numeric.sql +++ b/test/JDBC/input/babel_numeric.sql @@ -60,4 +60,197 @@ select * from t1; go drop table t1; -go \ No newline at end of file +go + +select * from +( + select cast(1.23 as decimal(18,2)) as col + union all + select cast(1.23 as decimal(7,2)) as col +) dummy order by col; +go + +select * from +( + select cast(NULL as decimal(18,2)) as col + union all + select cast(1.23 as decimal(7,2)) as col +) dummy order by col; +go + +select * from +( + select cast(9999999999999999.99 as decimal(18,2)) as col + union all + select cast(99999.99 as decimal(7,2)) as col +) dummy order by col; +go + +create type decimal_18_2 from decimal(18,2); +go + +create type decimal_7_2 from decimal(7,2); +go + +select * from +( + select cast(1.23 as decimal_18_2) as col + union all + select cast(1.23 as decimal_7_2) as col +) dummy order by col; +go + +select * from +( + select cast(1.23 as decimal_18_2) as col + union all + select cast(NULL as decimal_7_2) as col +) dummy order by col; +go + +select * from +( + select cast(9999999999999999.99 as decimal_18_2) as col + union all + select cast(99999.99 as decimal_7_2) as col +) dummy order by col; +go + +create table babel_5086_t1 (a decimal(18,2), b decimal(7,2), c decimal_18_2, d decimal_7_2); +go + +insert into babel_5086_t1 values (1.23, 1.23, 1.23, 1.23); +insert into babel_5086_t1 values (9999999999999999.99, NULL, 9999999999999999.99, NULL); +insert into babel_5086_t1 values (NULL, 99999.99, NULL, 99999.99); +go + +select * from +( + select a as col from babel_5086_t1 + union all + select b as col from babel_5086_t1 +) dummy order by col; +go + +select * from +( + select c as col from babel_5086_t1 + union all + select d as col from babel_5086_t1 +) dummy order by col; +go + +select * from +( + select a as col from babel_5086_t1 + union all + select b as col from babel_5086_t1 + union all + select c as col from babel_5086_t1 + union all + select d as col from babel_5086_t1 +) dummy order by col; +go + +select * from +( + select a as col from babel_5086_t1 + union all + select c as col from babel_5086_t1 +) dummy order by col; +go + +select * from +( + select b as col from babel_5086_t1 + union all + select d as col from babel_5086_t1 +) dummy order by col; +go + +create type numeric_18_2 from numeric(18,2); +go + +create type numeric_7_2 from numeric(7,2); +go + +select * from +( + select cast(1.23 as numeric_18_2) as col + union all + select cast(1.23 as numeric_7_2) as col +) dummy order by col; +go + +select * from +( + select cast(12344.234 as numeric_18_2) as col + union all + select cast(1.23 as numeric_7_2) as col +) dummy order by col; +go + +create table babel_5086_t2 (a numeric(18,2), b numeric(7,2), c numeric_18_2, d numeric_7_2); +go + +insert into babel_5086_t2 values (1.23, 1.23, 1.23, 1.23); +insert into babel_5086_t2 values (9999999999999999.99, NULL, 9999999999999999.99, NULL); +insert into babel_5086_t2 values (NULL, 99999.99, NULL, 99999.99); +go + +select * from +( + select a as col from babel_5086_t2 + union all + select b as col from babel_5086_t2 +) dummy order by col; +go + +select * from +( + select c as col from babel_5086_t2 + union all + select d as col from babel_5086_t2 +) dummy order by col; +go + +select * from +( + select a as col from babel_5086_t2 + union all + select b as col from babel_5086_t2 + union all + select c as col from babel_5086_t2 + union all + select d as col from babel_5086_t2 +) dummy order by col; +go + +select * from +( + select a as col from babel_5086_t2 + union all + select c as col from babel_5086_t2 +) dummy order by col; +go + + +select * from +( + select b as col from babel_5086_t2 + union all + select d as col from babel_5086_t2 +) dummy order by col; +go + +drop table babel_5086_t1; +go + +drop table babel_5086_t2; +go + +drop type decimal_18_2; +drop type decimal_7_2; +drop type numeric_18_2; +drop type numeric_7_2; +go