Skip to content

Commit 9110b33

Browse files
committed
Add numeric <-> int8 and numeric <-> int2 conversion functions, as well
as a unary minus operator for numeric. Now that long numeric constants will get converted to NUMERIC in early parsing, it's essential to have numeric->int8 conversion to avoid 'can't convert' errors on undecorated int8 constants. Threw in the rest for completeness while I was in the area. I did not force an initdb for this, since the system will still run without the new pg_proc/pg_operator entries. Possibly I should've.
1 parent 512669d commit 9110b33

File tree

4 files changed

+268
-95
lines changed

4 files changed

+268
-95
lines changed

src/backend/utils/adt/numeric.c

+153-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*
66
* 1998 Jan Wieck
77
*
8-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/numeric.c,v 1.24 2000/01/20 02:21:44 tgl Exp $
8+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/numeric.c,v 1.25 2000/02/24 02:05:30 tgl Exp $
99
*
1010
* ----------
1111
*/
@@ -357,7 +357,7 @@ numeric(Numeric num, int32 typmod)
357357

358358
/* ----------------------------------------------------------------------
359359
*
360-
* Rounding and the like
360+
* Sign manipulation, rounding and the like
361361
*
362362
* ----------------------------------------------------------------------
363363
*/
@@ -395,6 +395,51 @@ numeric_abs(Numeric num)
395395
}
396396

397397

398+
Numeric
399+
numeric_uminus(Numeric num)
400+
{
401+
Numeric res;
402+
403+
/* ----------
404+
* Handle NULL
405+
* ----------
406+
*/
407+
if (num == NULL)
408+
return NULL;
409+
410+
/* ----------
411+
* Handle NaN
412+
* ----------
413+
*/
414+
if (NUMERIC_IS_NAN(num))
415+
return make_result(&const_nan);
416+
417+
/* ----------
418+
* Do it the easy way directly on the packed format
419+
* ----------
420+
*/
421+
res = (Numeric) palloc(num->varlen);
422+
memcpy(res, num, num->varlen);
423+
424+
/* ----------
425+
* The packed format is known to be totally zero digit trimmed
426+
* always. So we can identify a ZERO by the fact that there
427+
* are no digits at all. Do nothing to a zero.
428+
* ----------
429+
*/
430+
if (num->varlen != NUMERIC_HDRSZ)
431+
{
432+
/* Else, flip the sign */
433+
if (NUMERIC_SIGN(num) == NUMERIC_POS)
434+
res->n_sign_dscale = NUMERIC_NEG | NUMERIC_DSCALE(num);
435+
else
436+
res->n_sign_dscale = NUMERIC_POS | NUMERIC_DSCALE(num);
437+
}
438+
439+
return res;
440+
}
441+
442+
398443
Numeric
399444
numeric_sign(Numeric num)
400445
{
@@ -1465,7 +1510,7 @@ numeric_ln(Numeric num)
14651510

14661511

14671512
/* ----------
1468-
* numeric_ln() -
1513+
* numeric_log() -
14691514
*
14701515
* Compute the logarithm of x in a given base
14711516
* ----------
@@ -1596,6 +1641,8 @@ numeric_power(Numeric num1, Numeric num2)
15961641
*
15971642
* ----------------------------------------------------------------------
15981643
*/
1644+
1645+
15991646
Numeric
16001647
int4_numeric(int32 val)
16011648
{
@@ -1627,7 +1674,7 @@ numeric_int4(Numeric num)
16271674
return 0;
16281675

16291676
if (NUMERIC_IS_NAN(num))
1630-
return 0;
1677+
elog(ERROR, "Cannot convert NaN to int4");
16311678

16321679
/* ----------
16331680
* Get the number in the variable format so we can round to integer.
@@ -1647,6 +1694,108 @@ numeric_int4(Numeric num)
16471694
}
16481695

16491696

1697+
Numeric
1698+
int8_numeric(int64 *val)
1699+
{
1700+
Numeric res;
1701+
NumericVar result;
1702+
char *tmp;
1703+
1704+
init_var(&result);
1705+
1706+
tmp = int8out(val);
1707+
set_var_from_str(tmp, &result);
1708+
res = make_result(&result);
1709+
1710+
free_var(&result);
1711+
pfree(tmp);
1712+
1713+
return res;
1714+
}
1715+
1716+
1717+
int64 *
1718+
numeric_int8(Numeric num)
1719+
{
1720+
NumericVar x;
1721+
char *str;
1722+
int64 *result;
1723+
1724+
if (num == NULL)
1725+
return NULL;
1726+
1727+
if (NUMERIC_IS_NAN(num))
1728+
elog(ERROR, "Cannot convert NaN to int8");
1729+
1730+
/* ----------
1731+
* Get the number in the variable format so we can round to integer.
1732+
* ----------
1733+
*/
1734+
init_var(&x);
1735+
set_var_from_num(num, &x);
1736+
1737+
str = get_str_from_var(&x, 0); /* dscale = 0 produces rounding */
1738+
1739+
free_var(&x);
1740+
1741+
result = int8in(str);
1742+
pfree(str);
1743+
1744+
return result;
1745+
}
1746+
1747+
1748+
Numeric
1749+
int2_numeric(int16 val)
1750+
{
1751+
Numeric res;
1752+
NumericVar result;
1753+
char *tmp;
1754+
1755+
init_var(&result);
1756+
1757+
tmp = int2out(val);
1758+
set_var_from_str(tmp, &result);
1759+
res = make_result(&result);
1760+
1761+
free_var(&result);
1762+
pfree(tmp);
1763+
1764+
return res;
1765+
}
1766+
1767+
1768+
int16
1769+
numeric_int2(Numeric num)
1770+
{
1771+
NumericVar x;
1772+
char *str;
1773+
int16 result;
1774+
1775+
if (num == NULL)
1776+
return 0;
1777+
1778+
if (NUMERIC_IS_NAN(num))
1779+
elog(ERROR, "Cannot convert NaN to int2");
1780+
1781+
/* ----------
1782+
* Get the number in the variable format so we can round to integer.
1783+
* ----------
1784+
*/
1785+
init_var(&x);
1786+
set_var_from_num(num, &x);
1787+
1788+
str = get_str_from_var(&x, 0); /* dscale = 0 produces rounding */
1789+
1790+
free_var(&x);
1791+
1792+
result = int2in(str);
1793+
pfree(str);
1794+
1795+
return result;
1796+
}
1797+
1798+
16501799
Numeric
16511800
float8_numeric(float64 val)
16521801
{

src/include/catalog/pg_operator.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
99
* Portions Copyright (c) 1994, Regents of the University of California
1010
*
11-
* $Id: pg_operator.h,v 1.69 2000/02/17 03:39:48 tgl Exp $
11+
* $Id: pg_operator.h,v 1.70 2000/02/24 02:05:28 tgl Exp $
1212
*
1313
* NOTES
1414
* the genbki.sh script reads this file and generates .bki
@@ -682,6 +682,7 @@ DATA(insert OID = 1760 ( "*" PGUID 0 b t f 1700 1700 1700 1760 0 0 0 numeric
682682
DATA(insert OID = 1761 ( "/" PGUID 0 b t f 1700 1700 1700 0 0 0 0 numeric_div - - ));
683683
DATA(insert OID = 1762 ( "%" PGUID 0 b t f 1700 1700 1700 0 0 0 0 numeric_mod - - ));
684684
DATA(insert OID = 1763 ( "@" PGUID 0 l t f 0 1700 1700 0 0 0 0 numeric_abs - - ));
685+
DATA(insert OID = 1788 ( "-" PGUID 0 l t f 0 1700 1700 0 0 0 0 numeric_uminus - - ));
685686

686687

687688
/*

src/include/catalog/pg_proc.h

+25-7
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: pg_proc.h,v 1.124 2000/02/21 03:36:55 tgl Exp $
10+
* $Id: pg_proc.h,v 1.125 2000/02/24 02:05:27 tgl Exp $
1111
*
1212
* NOTES
1313
* The script catalog/genbki.sh reads this file and generates .bki
@@ -430,7 +430,7 @@ DESCR("addition");
430430
DATA(insert OID = 205 ( float4mi PGUID 11 f t t 2 f 700 "700 700" 100 0 0 100 float4mi - ));
431431
DESCR("subtract");
432432
DATA(insert OID = 206 ( float4um PGUID 11 f t t 1 f 700 "700" 100 0 0 100 float4um - ));
433-
DESCR("subtract");
433+
DESCR("negate");
434434
DATA(insert OID = 207 ( float4abs PGUID 11 f t t 1 f 700 "700" 100 0 0 100 float4abs - ));
435435
DESCR("absolute value");
436436
DATA(insert OID = 208 ( float4inc PGUID 11 f t t 1 f 700 "700" 100 0 0 100 float4inc - ));
@@ -441,9 +441,9 @@ DATA(insert OID = 211 ( float4smaller PGUID 11 f t t 2 f 700 "700 700" 100 0
441441
DESCR("smaller of two");
442442

443443
DATA(insert OID = 212 ( int4um PGUID 11 f t t 1 f 23 "23" 100 0 0 100 int4um - ));
444-
DESCR("subtract");
444+
DESCR("negate");
445445
DATA(insert OID = 213 ( int2um PGUID 11 f t t 1 f 21 "21" 100 0 0 100 int2um - ));
446-
DESCR("subtract");
446+
DESCR("negate");
447447

448448
DATA(insert OID = 214 ( float8in PGUID 11 f t t 1 f 701 "0" 100 0 0 100 float8in - ));
449449
DESCR("(internal)");
@@ -458,7 +458,7 @@ DESCR("addition");
458458
DATA(insert OID = 219 ( float8mi PGUID 11 f t t 2 f 701 "701 701" 100 0 0 100 float8mi - ));
459459
DESCR("subtract");
460460
DATA(insert OID = 220 ( float8um PGUID 11 f t t 1 f 701 "701" 100 0 0 100 float8um - ));
461-
DESCR("subtract");
461+
DESCR("negate");
462462
DATA(insert OID = 221 ( float8abs PGUID 11 f t t 1 f 701 "701" 100 0 0 100 float8abs - ));
463463
DESCR("absolute value");
464464
DATA(insert OID = 222 ( float8inc PGUID 11 f t t 1 f 701 "701" 100 0 0 100 float8inc - ));
@@ -847,7 +847,7 @@ DESCR("(internal)");
847847
DATA(insert OID = 461 ( int8out PGUID 11 f t t 1 f 23 "0" 100 0 0 100 int8out - ));
848848
DESCR("(internal)");
849849
DATA(insert OID = 462 ( int8um PGUID 11 f t t 1 f 20 "20" 100 0 0 100 int8um - ));
850-
DESCR("unary minus");
850+
DESCR("negate");
851851
DATA(insert OID = 463 ( int8pl PGUID 11 f t t 2 f 20 "20 20" 100 0 0 100 int8pl - ));
852852
DESCR("addition");
853853
DATA(insert OID = 464 ( int8mi PGUID 11 f t t 2 f 20 "20 20" 100 0 0 100 int8mi - ));
@@ -2333,6 +2333,24 @@ DATA(insert OID = 1767 ( numeric_larger PGUID 11 f t t 2 f 1700 "1700 1700" 10
23332333
DESCR("larger of two numbers");
23342334
DATA(insert OID = 1769 ( numeric_cmp PGUID 11 f t t 2 f 23 "1700 1700" 100 0 0 100 numeric_cmp - ));
23352335
DESCR("compare two numbers");
2336+
DATA(insert OID = 1771 ( numeric_uminus PGUID 11 f t t 1 f 1700 "1700" 100 0 0 100 numeric_uminus - ));
2337+
DESCR("negate");
2338+
DATA(insert OID = 1779 ( int8_numeric PGUID 11 f t t 1 f 1700 "20" 100 0 0 100 int8_numeric - ));
2339+
DESCR("(internal)");
2340+
DATA(insert OID = 1781 ( numeric PGUID 11 f t t 1 f 1700 "20" 100 0 0 100 int8_numeric - ));
2341+
DESCR("(internal)");
2342+
DATA(insert OID = 1782 ( numeric_int8 PGUID 11 f t t 1 f 20 "1700" 100 0 0 100 numeric_int8 - ));
2343+
DESCR("(internal)");
2344+
DATA(insert OID = 1783 ( int8 PGUID 11 f t t 1 f 20 "1700" 100 0 0 100 numeric_int8 - ));
2345+
DESCR("(internal)");
2346+
DATA(insert OID = 1784 ( int2_numeric PGUID 11 f t t 1 f 1700 "21" 100 0 0 100 int2_numeric - ));
2347+
DESCR("(internal)");
2348+
DATA(insert OID = 1785 ( numeric PGUID 11 f t t 1 f 1700 "21" 100 0 0 100 int2_numeric - ));
2349+
DESCR("(internal)");
2350+
DATA(insert OID = 1786 ( numeric_int2 PGUID 11 f t t 1 f 21 "1700" 100 0 0 100 numeric_int2 - ));
2351+
DESCR("(internal)");
2352+
DATA(insert OID = 1787 ( int2 PGUID 11 f t t 1 f 21 "1700" 100 0 0 100 numeric_int2 - ));
2353+
DESCR("(internal)");
23362354

23372355
/* formatting */
23382356
DATA(insert OID = 1770 ( to_char PGUID 11 f t f 2 f 25 "1184 25" 100 0 0 100 timestamp_to_char - ));
@@ -2349,7 +2367,7 @@ DATA(insert OID = 1776 ( to_char PGUID 11 f t f 2 f 25 "701 25" 100 0 0 100
23492367
DESCR("convert / formatting float8 to text");
23502368
DATA(insert OID = 1777 ( to_number PGUID 11 f t f 2 f 1700 "25 25" 100 0 0 100 numeric_to_number - ));
23512369
DESCR("convert text to numeric");
2352-
DATA(insert OID = 1778 ( to_timestamp PGUID 11 f t f 2 f 1184 "25 25" 100 0 0 100 to_timestamp - ));
2370+
DATA(insert OID = 1778 ( to_timestamp PGUID 11 f t f 2 f 1184 "25 25" 100 0 0 100 to_timestamp - ));
23532371
DESCR("convert text to timestamp");
23542372
DATA(insert OID = 1780 ( to_date PGUID 11 f t f 2 f 1082 "25 25" 100 0 0 100 to_date - ));
23552373
DESCR("convert text to date");

0 commit comments

Comments
 (0)