Skip to content

Commit 3ef7dc1

Browse files
authored
typmod handling for aggregate functions. (#3854)
Issue: In resolve_numeric_typmod_from_exp we missed the handling for typmod calculation for some aggregate functions like COUNT(), COUNT_BIG(), STRING_AGG(). Changes made to fix the issues: Added handling for COUNT(), COUNT_BIG() and STRING_AGG() aggregates in T_Aggref node Issues Resolved Task: BABEL-5882 Authored-by: yashneet vinayak yashneet@amazon.com Signed-off-by: yashneet vinayak yashneet@amazon.com
1 parent 9e43a47 commit 3ef7dc1

File tree

6 files changed

+2584
-56
lines changed

6 files changed

+2584
-56
lines changed

contrib/babelfishpg_tsql/src/pltsql_coerce.c

Lines changed: 66 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,12 @@ static bool is_tsql_int4_bit(Oid oid);
8585
#define SMALLINT_PRECISION_RADIX 5
8686
#define INT_PRECISION_RADIX 10
8787
#define BIGINT_PRECISION_RADIX 19
88+
#define TINYINT_PRECISION_RADIX 3
8889

8990
#define DEFAULT_SMALLINT_TYPMOD ((SMALLINT_PRECISION_RADIX << 16) | 0) + VARHDRSZ
9091
#define DEFAULT_INT_TYPMOD ((INT_PRECISION_RADIX << 16) | 0) + VARHDRSZ
9192
#define DEFAULT_BIGINT_TYPMOD ((BIGINT_PRECISION_RADIX << 16) | 0) + VARHDRSZ
93+
#define DEFAULT_TINYINT_TYPMOD ((TINYINT_PRECISION_RADIX << 16) | 0) + VARHDRSZ
9294

9395
/* Numeirc operator OID from pg_proc.dat */
9496
#define NUMERIC_ADD_OID 1724
@@ -1227,7 +1229,6 @@ resolve_numeric_typmod_from_exp(Plan *plan, Node *expr, bool *found)
12271229
case T_Param:
12281230
{
12291231
Param *param = (Param *) expr;
1230-
12311232
if (param->paramtypmod == -1)
12321233
{
12331234
/* UDT handling in T_Param */
@@ -1242,11 +1243,13 @@ resolve_numeric_typmod_from_exp(Plan *plan, Node *expr, bool *found)
12421243

12431244
/* handling for fixed length datatypes */
12441245
if (param->paramtype == INT4OID)
1245-
return ((INT_PRECISION_RADIX << 16) | 0) + VARHDRSZ;
1246+
return DEFAULT_INT_TYPMOD;
12461247
else if (param->paramtype == INT8OID)
1247-
return ((BIGINT_PRECISION_RADIX << 16) | 0) + VARHDRSZ;
1248+
return DEFAULT_BIGINT_TYPMOD;
12481249
else if (param->paramtype == INT2OID)
1249-
return ((SMALLINT_PRECISION_RADIX << 16) | 0) + VARHDRSZ;
1250+
return DEFAULT_SMALLINT_TYPMOD;
1251+
else if ((*common_utility_plugin_ptr->is_tsql_tinyint_datatype) (param->paramtype))
1252+
return DEFAULT_TINYINT_TYPMOD;
12501253
}
12511254

12521255
if (!is_numeric_datatype(param->paramtype) &&
@@ -1420,6 +1423,8 @@ resolve_numeric_typmod_from_exp(Plan *plan, Node *expr, bool *found)
14201423
return DEFAULT_BIGINT_TYPMOD;
14211424
else if (plan && var->vartype == INT2OID)
14221425
return DEFAULT_SMALLINT_TYPMOD;
1426+
else if (plan && (*common_utility_plugin_ptr->is_tsql_tinyint_datatype) (var->vartype))
1427+
return DEFAULT_TINYINT_TYPMOD;
14231428

14241429
if (found != NULL) *found = false;
14251430
}
@@ -1832,38 +1837,74 @@ resolve_numeric_typmod_from_exp(Plan *plan, Node *expr, bool *found)
18321837
if ((*common_utility_plugin_ptr->is_tsql_money_datatype)(aggref->aggtype) ||
18331838
(*common_utility_plugin_ptr->is_tsql_smallmoney_datatype)(aggref->aggtype))
18341839
{
1840+
pfree(aggFuncName);
18351841
return TSQL_MONEY_TYPMOD;
18361842
}
18371843
else if (aggref->aggtype == INT4OID)
18381844
{
1839-
return ((INT_PRECISION_RADIX << 16) | 0) + VARHDRSZ;
1845+
pfree(aggFuncName);
1846+
return DEFAULT_INT_TYPMOD;
18401847
}
18411848
else if (aggref->aggtype == INT8OID)
18421849
{
1843-
return ((BIGINT_PRECISION_RADIX << 16) | 0) + VARHDRSZ;
1850+
pfree(aggFuncName);
1851+
return DEFAULT_BIGINT_TYPMOD;
18441852
}
18451853
}
18461854

1847-
/*
1848-
* [BABEL-3074] NUMERIC overflow causes TDS error for
1849-
* aggregate function sum(); resultant precision should be
1850-
* tds_default_numeric_precision
1851-
*/
1852-
if (aggFuncName && strlen(aggFuncName) == 3 &&
1853-
(strncmp(aggFuncName, "sum", 3) == 0))
1854-
precision = tds_default_numeric_precision;
1855-
1856-
1857-
/*
1858-
* For aggregate function avg(); resultant precision should be
1859-
* tds_default_numeric_precision and resultant scale =
1860-
* max(input scale, 6)
1861-
*/
1862-
if (aggFuncName && strlen(aggFuncName) == 3 &&
1863-
(strncmp(aggFuncName, "avg", 3) == 0))
1855+
if (aggFuncName)
18641856
{
1865-
precision = tds_default_numeric_precision;
1866-
scale = Max(scale, 6);
1857+
if (strlen(aggFuncName) == 3 &&
1858+
(strncmp(aggFuncName, "sum", 3) == 0))
1859+
{
1860+
/*
1861+
* [BABEL-3074] NUMERIC overflow causes TDS error for
1862+
* aggregate function sum(); resultant precision should be
1863+
* tds_default_numeric_precision
1864+
*/
1865+
precision = tds_default_numeric_precision;
1866+
}
1867+
else if (strlen(aggFuncName) == 3 &&
1868+
(strncmp(aggFuncName, "avg", 3) == 0))
1869+
{
1870+
/*
1871+
* For aggregate function avg(); resultant precision
1872+
* should be tds_default_numeric_precision and resultant
1873+
* scale = max(input scale, 6)
1874+
*/
1875+
precision = tds_default_numeric_precision;
1876+
scale = Max(scale, 6);
1877+
}
1878+
else if (strlen(aggFuncName) == 5 &&
1879+
(strncmp(aggFuncName, "count", 5) == 0))
1880+
{
1881+
/*
1882+
* For aggregate function count(); resultant precision
1883+
* should be INT_PRECISION_RADIX and scale should be 0.
1884+
*/
1885+
precision = INT_PRECISION_RADIX;
1886+
scale = 0;
1887+
}
1888+
else if (strlen(aggFuncName) == 9 &&
1889+
(strncmp(aggFuncName, "count_big", 9) == 0))
1890+
{
1891+
/*
1892+
* For aggregate function count_big(); resultant precision
1893+
* should be BIGINT_PRECISION_RADIX and scale should be 0.
1894+
*/
1895+
precision = BIGINT_PRECISION_RADIX;
1896+
scale = 0;
1897+
}
1898+
else if (strlen(aggFuncName) == 10 &&
1899+
(strncmp(aggFuncName, "string_agg", 10) == 0))
1900+
{
1901+
/*
1902+
* For aggregate function string_agg(); we should not return
1903+
* typmod, so return -1.
1904+
*/
1905+
pfree(aggFuncName);
1906+
return -1;
1907+
}
18671908
}
18681909

18691910
pfree(aggFuncName);

test/JDBC/expected/TestExactNumeric.out

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -237,9 +237,25 @@ numeric#!#numeric#!#numeric#!#numeric
237237
<NULL>#!#-32767.00000000#!#<NULL>#!#<NULL>
238238
<NULL>#!#<NULL>#!#-2147483647.00000000#!#<NULL>
239239
<NULL>#!#<NULL>#!#<NULL>#!#-9223372036854775807.00000000
240-
~~ERROR (Code: 33557097)~~
241-
242-
~~ERROR (Message: Arithmetic overflow error for data type numeric.)~~
240+
128.00000000#!#<NULL>#!#<NULL>#!#<NULL>
241+
<NULL>#!#32768.00000000#!#<NULL>#!#<NULL>
242+
<NULL>#!#<NULL>#!#2147483648.00000000#!#<NULL>
243+
<NULL>#!#<NULL>#!#<NULL>#!#9223372036854775808.00000000
244+
<NULL>#!#<NULL>#!#<NULL>#!#<NULL>
245+
<NULL>#!#<NULL>#!#<NULL>#!#<NULL>
246+
<NULL>#!#<NULL>#!#<NULL>#!#<NULL>
247+
<NULL>#!#<NULL>#!#<NULL>#!#<NULL>
248+
1.00000000#!#<NULL>#!#<NULL>#!#<NULL>
249+
<NULL>#!#1.00000000#!#<NULL>#!#<NULL>
250+
<NULL>#!#<NULL>#!#1.00000000#!#<NULL>
251+
<NULL>#!#<NULL>#!#<NULL>#!#1.00000000
252+
1.00000000#!#<NULL>#!#<NULL>#!#<NULL>
253+
<NULL>#!#1.00000000#!#<NULL>#!#<NULL>
254+
<NULL>#!#<NULL>#!#1.00000000#!#<NULL>
255+
<NULL>#!#<NULL>#!#<NULL>#!#1.00000000
256+
129.00000000#!#<NULL>#!#<NULL>#!#<NULL>
257+
6.00000000#!#101.00000000#!#10001.00000000#!#1000000001.00000000
258+
~~END~~
243259

244260

245261
SELECT
@@ -255,9 +271,25 @@ numeric#!#numeric#!#numeric#!#numeric
255271
<NULL>#!#-32768.00000000#!#<NULL>#!#<NULL>
256272
<NULL>#!#<NULL>#!#-2147483648.00000000#!#<NULL>
257273
<NULL>#!#<NULL>#!#<NULL>#!#-9223372036854775808.00000000
258-
~~ERROR (Code: 33557097)~~
259-
260-
~~ERROR (Message: Arithmetic overflow error for data type numeric.)~~
274+
127.00000000#!#<NULL>#!#<NULL>#!#<NULL>
275+
<NULL>#!#32767.00000000#!#<NULL>#!#<NULL>
276+
<NULL>#!#<NULL>#!#2147483647.00000000#!#<NULL>
277+
<NULL>#!#<NULL>#!#<NULL>#!#9223372036854775807.00000000
278+
<NULL>#!#<NULL>#!#<NULL>#!#<NULL>
279+
<NULL>#!#<NULL>#!#<NULL>#!#<NULL>
280+
<NULL>#!#<NULL>#!#<NULL>#!#<NULL>
281+
<NULL>#!#<NULL>#!#<NULL>#!#<NULL>
282+
0E-8#!#<NULL>#!#<NULL>#!#<NULL>
283+
<NULL>#!#0E-8#!#<NULL>#!#<NULL>
284+
<NULL>#!#<NULL>#!#0E-8#!#<NULL>
285+
<NULL>#!#<NULL>#!#<NULL>#!#0E-8
286+
0E-8#!#<NULL>#!#<NULL>#!#<NULL>
287+
<NULL>#!#0E-8#!#<NULL>#!#<NULL>
288+
<NULL>#!#<NULL>#!#0E-8#!#<NULL>
289+
<NULL>#!#<NULL>#!#<NULL>#!#0E-8
290+
128.00000000#!#<NULL>#!#<NULL>#!#<NULL>
291+
5.00000000#!#100.00000000#!#10000.00000000#!#1000000000.00000000
292+
~~END~~
261293

262294

263295
-- DEGREES and RADIANS
@@ -556,9 +588,25 @@ numeric#!#numeric#!#numeric#!#numeric
556588
<NULL>#!#-32768.00000000#!#<NULL>#!#<NULL>
557589
<NULL>#!#<NULL>#!#-2147483648.00000000#!#<NULL>
558590
<NULL>#!#<NULL>#!#<NULL>#!#-9223372036854775808.00000000
559-
~~ERROR (Code: 33557097)~~
560-
561-
~~ERROR (Message: Arithmetic overflow error for data type numeric.)~~
591+
128.00000000#!#<NULL>#!#<NULL>#!#<NULL>
592+
<NULL>#!#32768.00000000#!#<NULL>#!#<NULL>
593+
<NULL>#!#<NULL>#!#2147483648.00000000#!#<NULL>
594+
<NULL>#!#<NULL>#!#<NULL>#!#9223372036854775808.00000000
595+
<NULL>#!#<NULL>#!#<NULL>#!#<NULL>
596+
<NULL>#!#<NULL>#!#<NULL>#!#<NULL>
597+
<NULL>#!#<NULL>#!#<NULL>#!#<NULL>
598+
<NULL>#!#<NULL>#!#<NULL>#!#<NULL>
599+
1.00000000#!#<NULL>#!#<NULL>#!#<NULL>
600+
<NULL>#!#1.00000000#!#<NULL>#!#<NULL>
601+
<NULL>#!#<NULL>#!#1.00000000#!#<NULL>
602+
<NULL>#!#<NULL>#!#<NULL>#!#1.00000000
603+
1.00000000#!#<NULL>#!#<NULL>#!#<NULL>
604+
<NULL>#!#1.00000000#!#<NULL>#!#<NULL>
605+
<NULL>#!#<NULL>#!#1.00000000#!#<NULL>
606+
<NULL>#!#<NULL>#!#<NULL>#!#1.00000000
607+
129.00000000#!#<NULL>#!#<NULL>#!#<NULL>
608+
6.00000000#!#101.00000000#!#10001.00000000#!#1000000001.00000000
609+
~~END~~
562610

563611

564612

0 commit comments

Comments
 (0)