]> granicus.if.org Git - postgresql/commitdiff
Revise int2/int4/int8/float4/float8 input routines to allow for
authorNeil Conway <neilc@samurai.com>
Thu, 11 Mar 2004 02:11:14 +0000 (02:11 +0000)
committerNeil Conway <neilc@samurai.com>
Thu, 11 Mar 2004 02:11:14 +0000 (02:11 +0000)
any amount of leading or trailing whitespace (where "whitespace"
is defined by isspace()). This is for SQL conformance, as well
as consistency with other numeric types (e.g. oid, numeric).

Also refactor pg_atoi() to avoid looking at errno where not
necessary, and add a bunch of regression tests for the input
to these types.

19 files changed:
src/backend/utils/adt/float.c
src/backend/utils/adt/int8.c
src/backend/utils/adt/numutils.c
src/backend/utils/adt/oid.c
src/test/regress/expected/float4.out
src/test/regress/expected/float8.out
src/test/regress/expected/int2.out
src/test/regress/expected/int4.out
src/test/regress/expected/int8.out
src/test/regress/expected/numeric.out
src/test/regress/expected/oid.out
src/test/regress/output/misc.source
src/test/regress/sql/float4.sql
src/test/regress/sql/float8.sql
src/test/regress/sql/int2.sql
src/test/regress/sql/int4.sql
src/test/regress/sql/int8.sql
src/test/regress/sql/numeric.sql
src/test/regress/sql/oid.sql

index f9c4894794f4e73c4ff857900ff8d53e7cebba31..2707c83fd62a43c487bdd7ba5a18943059d78437 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.97 2004/03/04 21:47:18 neilc Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.98 2004/03/11 02:11:13 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -185,14 +185,37 @@ float4in(PG_FUNCTION_ARGS)
 
        errno = 0;
        val = strtod(num, &endptr);
-       if (*endptr != '\0')
+
+       if (errno == ERANGE)
+               ereport(ERROR,
+                               (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+                                errmsg("\"%s\" is out of range for type real", num)));
+
+       if (num == endptr)
        {
                /*
-                * XXX we should accept "Infinity" and "-Infinity" too, but what
-                * are the correct values to assign?  HUGE_VAL will provoke an
-                * error from CheckFloat4Val.
+                * We didn't find anything that looks like a float in the input
+                *
+                * In releases prior to 7.5, we accepted an empty string as
+                * valid input (yielding a float8 of 0). In 7.5, we accept
+                * empty strings, but emit a warning noting that the feature
+                * is deprecated. In 7.6+, the warning should be replaced by
+                * an error.
+                *
+                * XXX we should accept "Infinity" and "-Infinity" too, but
+                * what are the correct values to assign?  HUGE_VAL will
+                * provoke an error from CheckFloat4Val.
                 */
-               if (strcasecmp(num, "NaN") == 0)
+               if (*num == '\0')
+               {
+                       ereport(WARNING,
+                                       (errcode(ERRCODE_WARNING_DEPRECATED_FEATURE),
+                                        errmsg("deprecated input syntax for type real: \"\""),
+                                        errdetail("This input will be rejected in "
+                                                          "a future release of PostgreSQL.")));
+                       Assert(val == 0.0);
+               }
+               else if (strcasecmp(num, "NaN") == 0)
                        val = NAN;
                else
                        ereport(ERROR,
@@ -200,26 +223,17 @@ float4in(PG_FUNCTION_ARGS)
                                         errmsg("invalid input syntax for type real: \"%s\"",
                                                        num)));
        }
-       else
-       {
-               if (errno == ERANGE)
-                       ereport(ERROR,
-                                       (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
-                                        errmsg("\"%s\" is out of range for type real", num)));
-       }
 
-       /*
-        * In releases prior to 7.5, we accepted an empty string as valid
-        * input (yielding a float4 of 0). In 7.5, we accept empty
-        * strings, but emit a warning noting that the feature is
-        * deprecated. In 7.6+, the warning should be replaced by an error.
-        */
-       if (num == endptr)
-               ereport(WARNING,
-                               (errcode(ERRCODE_WARNING_DEPRECATED_FEATURE),
-                                errmsg("deprecated input syntax for type real: \"\""),
-                                errdetail("This input will be rejected in "
-                                                  "a future release of PostgreSQL.")));
+       /* skip trailing whitespace */
+       while (*endptr != '\0' && isspace(*endptr))
+               endptr++;
+
+       /* if there is any junk left at the end of the string, bail out */
+       if (*endptr != '\0')
+               ereport(ERROR,
+                               (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+                                errmsg("invalid input syntax for type real: \"%s\"",
+                                               num)));
 
        /*
         * if we get here, we have a legal double, still need to check to see
@@ -300,9 +314,33 @@ float8in(PG_FUNCTION_ARGS)
 
        errno = 0;
        val = strtod(num, &endptr);
-       if (*endptr != '\0')
+
+       if (errno == ERANGE)
+               ereport(ERROR,
+                               (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+                                errmsg("\"%s\" is out of range for type double precision", num)));
+
+       if (num == endptr)
        {
-               if (strcasecmp(num, "NaN") == 0)
+               /*
+                * We didn't find anything that looks like a float in the input
+                *
+                * In releases prior to 7.5, we accepted an empty string as
+                * valid input (yielding a float8 of 0). In 7.5, we accept
+                * empty strings, but emit a warning noting that the feature
+                * is deprecated. In 7.6+, the warning should be replaced by
+                * an error.
+                */
+               if (*num == '\0')
+               {
+                       ereport(WARNING,
+                                       (errcode(ERRCODE_WARNING_DEPRECATED_FEATURE),
+                                        errmsg("deprecated input syntax for type double precision: \"\""),
+                                        errdetail("This input will be rejected in "
+                                                          "a future release of PostgreSQL.")));
+                       Assert(val == 0.0);
+               }
+               else if (strcasecmp(num, "NaN") == 0)
                        val = NAN;
                else if (strcasecmp(num, "Infinity") == 0)
                        val = HUGE_VAL;
@@ -314,26 +352,17 @@ float8in(PG_FUNCTION_ARGS)
                                         errmsg("invalid input syntax for type double precision: \"%s\"",
                                                        num)));
        }
-       else
-       {
-               if (errno == ERANGE)
-                       ereport(ERROR,
-                                       (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
-                                        errmsg("\"%s\" is out of range for type double precision", num)));
-       }
 
-       /*
-        * In releases prior to 7.5, we accepted an empty string as valid
-        * input (yielding a float8 of 0). In 7.5, we accept empty
-        * strings, but emit a warning noting that the feature is
-        * deprecated. In 7.6+, the warning should be replaced by an error.
-        */
-       if (num == endptr)
-               ereport(WARNING,
-                               (errcode(ERRCODE_WARNING_DEPRECATED_FEATURE),
-                                errmsg("deprecated input syntax for type double precision: \"\""),
-                                errdetail("This input will be rejected in "
-                                                  "a future release of PostgreSQL.")));
+       /* skip trailing whitespace */
+       while (*endptr != '\0' && isspace(*endptr))
+               endptr++;
+
+       /* if there is any junk left at the end of the string, bail out */
+       if (*endptr != '\0')
+               ereport(ERROR,
+                               (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+                                errmsg("invalid input syntax for type double precision: \"%s\"",
+                                               num)));
 
        CheckFloat8Val(val);
 
index 200876e7989573a866de2a150bbc25d193f356a8..8667e53680a1f03dad387863cc154363e6365ab3 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/adt/int8.c,v 1.51 2004/02/03 08:29:56 joe Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/adt/int8.c,v 1.52 2004/03/11 02:11:13 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -113,8 +113,11 @@ scanint8(const char *str, bool errorOK, int64 *result)
                tmp = newtmp;
        }
 
-       /* trailing junk? */
-       if (*ptr)
+       /* allow trailing whitespace, but not other trailing chars */
+       while (*ptr != '\0' && isspace(*ptr))
+               ptr++;
+
+       if (*ptr != '\0')
        {
                if (errorOK)
                        return false;
index 20227884ed171b190e525dfbfef1325ef09d9d1e..17961017fafef0096c83394f51e8d415acfe5dc8 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/adt/numutils.c,v 1.61 2004/02/18 00:01:33 neilc Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/adt/numutils.c,v 1.62 2004/03/11 02:11:13 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -19,6 +19,7 @@
 #include <errno.h>
 #include <math.h>
 #include <limits.h>
+#include <ctype.h>
 
 #include "utils/builtins.h"
 
 /*
  * pg_atoi: convert string to integer
  *
- * size is the sizeof() the desired integral result (1, 2, or 4 bytes).
+ * 'size' is the sizeof() the desired integral result (1, 2, or 4 bytes).
  *
- * c, if not 0, is the terminator character that may appear after the
- * integer.  If 0, the string must end after the integer.
+ * allows any number of leading or trailing whitespace characters.
+ *
+ * 'c' is the character that terminates the input string (after any
+ * number of whitespace characters).
  *
  * Unlike plain atoi(), this will throw ereport() upon bad input format or
  * overflow.
@@ -57,7 +60,7 @@ int32
 pg_atoi(char *s, int size, int c)
 {
        long            l;
-       char       *badp = NULL;
+       char       *badp;
 
        /*
         * Some versions of strtol treat the empty string as an error, but
@@ -74,17 +77,21 @@ pg_atoi(char *s, int size, int c)
        errno = 0;
        l = strtol(s, &badp, 10);
 
-       /*
-        * strtol() normally only sets ERANGE.  On some systems it also may
-        * set EINVAL, which simply means it couldn't parse the input string.
-        * This is handled by the second "if" consistent across platforms.
-        */
-       if (errno && errno != ERANGE && errno != EINVAL)
+       /* We made no progress parsing the string, so bail out */
+       if (s == badp)
                ereport(ERROR,
                                (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                                 errmsg("invalid input syntax for integer: \"%s\"",
                                                s)));
-       if (badp && *badp && *badp != c)
+
+       /*
+        * Skip any trailing whitespace; if anything but whitespace
+        * remains before the terminating character, bail out
+        */
+       while (*badp != c && isspace(*badp))
+               badp++;
+
+       if (*badp != c)
                ereport(ERROR,
                                (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                                 errmsg("invalid input syntax for integer: \"%s\"",
index 2119936d39fccb5cf077d7fc4303a4d363dccac4..7ff6c6a27c1a74ab8ff1d605486f2d498df15486 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/adt/oid.c,v 1.55 2004/03/04 21:47:18 neilc Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/adt/oid.c,v 1.56 2004/03/11 02:11:13 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -33,6 +33,19 @@ oidin_subr(const char *funcname, const char *s, char **endloc)
        char       *endptr;
        Oid                     result;
 
+       /*
+        * In releases prior to 7.5, we accepted an empty string as valid
+        * input (yielding an OID of 0). In 7.5, we accept empty strings,
+        * but emit a warning noting that the feature is deprecated. In
+        * 7.6+, the warning should be replaced by an error.
+        */
+       if (*s == '\0')
+               ereport(WARNING,
+                               (errcode(ERRCODE_WARNING_DEPRECATED_FEATURE),
+                                errmsg("deprecated input syntax for type oid: \"\""),
+                                errdetail("This input will be rejected in "
+                                                  "a future release of PostgreSQL.")));
+
        errno = 0;
        cvt = strtoul(s, &endptr, 10);
 
@@ -47,20 +60,7 @@ oidin_subr(const char *funcname, const char *s, char **endloc)
                                 errmsg("invalid input syntax for type oid: \"%s\"",
                                                s)));
 
-       /*
-        * In releases prior to 7.5, we accepted an empty string as valid
-        * input (yielding an OID of 0). In 7.5, we accept empty strings,
-        * but emit a warning noting that the feature is deprecated. In
-        * 7.6+, the warning should be replaced by an error.
-        */
-       if (*s == '\0')
-               ereport(WARNING,
-                               (errcode(ERRCODE_WARNING_DEPRECATED_FEATURE),
-                                errmsg("deprecated input syntax for type oid: \"\""),
-                                errdetail("This input will be rejected in "
-                                                  "a future release of PostgreSQL.")));
-
-       if (endptr == s && *s)
+       if (endptr == s && *s != '\0')
                ereport(ERROR,
                                (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                                 errmsg("invalid input syntax for type oid: \"%s\"",
index 118a3fb66cc2e48380390c6346b1f9ee9c81a9ad..124b7c378c69fdf78c0c0fd7ea601a4412bd6a3c 100644 (file)
@@ -2,9 +2,9 @@
 -- FLOAT4
 --
 CREATE TABLE FLOAT4_TBL (f1  float4);
-INSERT INTO FLOAT4_TBL(f1) VALUES ('0.0');
-INSERT INTO FLOAT4_TBL(f1) VALUES ('1004.30');
-INSERT INTO FLOAT4_TBL(f1) VALUES ('-34.84');
+INSERT INTO FLOAT4_TBL(f1) VALUES ('    0.0');
+INSERT INTO FLOAT4_TBL(f1) VALUES ('1004.30   ');
+INSERT INTO FLOAT4_TBL(f1) VALUES ('     -34.84    ');
 INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e+20');
 INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e-20');
 -- test for over and under flow 
@@ -16,6 +16,43 @@ INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-40');
 ERROR:  type "real" value out of range: underflow
 INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-40');
 ERROR:  type "real" value out of range: underflow
+-- bad input
+INSERT INTO FLOAT4_TBL(f1) VALUES ('       ');
+ERROR:  invalid input syntax for type real: "       "
+INSERT INTO FLOAT4_TBL(f1) VALUES ('xyz');
+ERROR:  invalid input syntax for type real: "xyz"
+INSERT INTO FLOAT4_TBL(f1) VALUES ('5.0.0');
+ERROR:  invalid input syntax for type real: "5.0.0"
+INSERT INTO FLOAT4_TBL(f1) VALUES ('5 . 0');
+ERROR:  invalid input syntax for type real: "5 . 0"
+INSERT INTO FLOAT4_TBL(f1) VALUES ('5.   0');
+ERROR:  invalid input syntax for type real: "5.   0"
+INSERT INTO FLOAT4_TBL(f1) VALUES ('     - 3.0');
+ERROR:  invalid input syntax for type real: "     - 3.0"
+INSERT INTO FLOAT4_TBL(f1) VALUES ('123            5');
+ERROR:  invalid input syntax for type real: "123            5"
+-- special inputs
+SELECT 'NaN'::float4;
+ float4 
+--------
+    NaN
+(1 row)
+
+SELECT 'nan'::float4;
+ float4 
+--------
+    NaN
+(1 row)
+
+SELECT '   NAN  '::float4;
+ float4 
+--------
+    NaN
+(1 row)
+
+-- bad special inputs
+SELECT 'N A N'::float4;
+ERROR:  invalid input syntax for type real: "N A N"
 SELECT '' AS five, FLOAT4_TBL.*;
  five |     f1      
 ------+-------------
index 3d8bc7710b2b47bb8b272f722bbdb0da1b9d26cd..89e2bbf90256977c90487c92669a29d9f476ee81 100644 (file)
@@ -2,11 +2,57 @@
 -- FLOAT8
 --
 CREATE TABLE FLOAT8_TBL(f1 float8);
-INSERT INTO FLOAT8_TBL(f1) VALUES ('0.0');
-INSERT INTO FLOAT8_TBL(f1) VALUES ('1004.30');
-INSERT INTO FLOAT8_TBL(f1) VALUES ('-34.84');
+INSERT INTO FLOAT8_TBL(f1) VALUES ('    0.0   ');
+INSERT INTO FLOAT8_TBL(f1) VALUES ('1004.30  ');
+INSERT INTO FLOAT8_TBL(f1) VALUES ('   -34.84');
 INSERT INTO FLOAT8_TBL(f1) VALUES ('1.2345678901234e+200');
 INSERT INTO FLOAT8_TBL(f1) VALUES ('1.2345678901234e-200');
+-- test for underflow and overflow
+INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400');
+ERROR:  "10e400" is out of range for type double precision
+INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e400');
+ERROR:  "-10e400" is out of range for type double precision
+INSERT INTO FLOAT8_TBL(f1) VALUES ('10e-400');
+ERROR:  "10e-400" is out of range for type double precision
+INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e-400');
+ERROR:  "-10e-400" is out of range for type double precision
+-- bad input
+INSERT INTO FLOAT8_TBL(f1) VALUES ('     ');
+ERROR:  invalid input syntax for type double precision: "     "
+INSERT INTO FLOAT8_TBL(f1) VALUES ('xyz');
+ERROR:  invalid input syntax for type double precision: "xyz"
+INSERT INTO FLOAT8_TBL(f1) VALUES ('5.0.0');
+ERROR:  invalid input syntax for type double precision: "5.0.0"
+INSERT INTO FLOAT8_TBL(f1) VALUES ('5 . 0');
+ERROR:  invalid input syntax for type double precision: "5 . 0"
+INSERT INTO FLOAT8_TBL(f1) VALUES ('5.   0');
+ERROR:  invalid input syntax for type double precision: "5.   0"
+INSERT INTO FLOAT8_TBL(f1) VALUES ('    - 3');
+ERROR:  invalid input syntax for type double precision: "    - 3"
+INSERT INTO FLOAT8_TBL(f1) VALUES ('123           5');
+ERROR:  invalid input syntax for type double precision: "123           5"
+-- special inputs
+SELECT 'NaN'::float8;
+ float8 
+--------
+    NaN
+(1 row)
+
+SELECT 'nan'::float8;
+ float8 
+--------
+    NaN
+(1 row)
+
+SELECT '   NAN  '::float8;
+ float8 
+--------
+    NaN
+(1 row)
+
+-- bad special inputs
+SELECT 'N A N'::float8;
+ERROR:  invalid input syntax for type double precision: "N A N"
 SELECT '' AS five, FLOAT8_TBL.*;
  five |          f1          
 ------+----------------------
index 6da403c3e7a6feb3348a73148106024892811786..64e5bf58a8c2e198510e889f37f838f1f393a7f2 100644 (file)
@@ -4,19 +4,29 @@
 -- Some of these answers are consequently numerically incorrect.
 --
 CREATE TABLE INT2_TBL(f1 int2);
-INSERT INTO INT2_TBL(f1) VALUES ('0');
-INSERT INTO INT2_TBL(f1) VALUES ('1234');
-INSERT INTO INT2_TBL(f1) VALUES ('-1234');
+INSERT INTO INT2_TBL(f1) VALUES ('0   ');
+INSERT INTO INT2_TBL(f1) VALUES ('  1234 ');
+INSERT INTO INT2_TBL(f1) VALUES ('    -1234');
 INSERT INTO INT2_TBL(f1) VALUES ('34.5');
 ERROR:  invalid input syntax for integer: "34.5"
--- largest and smallest values 
+-- largest and smallest values
 INSERT INTO INT2_TBL(f1) VALUES ('32767');
 INSERT INTO INT2_TBL(f1) VALUES ('-32767');
--- bad input values -- should give warnings 
+-- bad input values -- should give errors
 INSERT INTO INT2_TBL(f1) VALUES ('100000');
 ERROR:  value "100000" is out of range for type shortint
 INSERT INTO INT2_TBL(f1) VALUES ('asdf');
 ERROR:  invalid input syntax for integer: "asdf"
+INSERT INTO INT2_TBL(f1) VALUES ('    ');
+ERROR:  invalid input syntax for integer: "    "
+INSERT INTO INT2_TBL(f1) VALUES ('- 1234');
+ERROR:  invalid input syntax for integer: "- 1234"
+INSERT INTO INT2_TBL(f1) VALUES ('4 444');
+ERROR:  invalid input syntax for integer: "4 444"
+INSERT INTO INT2_TBL(f1) VALUES ('123 dt');
+ERROR:  invalid input syntax for integer: "123 dt"
+INSERT INTO INT2_TBL(f1) VALUES ('');
+ERROR:  invalid input syntax for integer: ""
 SELECT '' AS five, INT2_TBL.*;
  five |   f1   
 ------+--------
index 633eb578d51aba6a891417d032422c4c9acf6643..e5d930e31e071b93198576ca0677a46f68643486 100644 (file)
@@ -4,19 +4,29 @@
 -- Some of these answers are consequently numerically incorrect.
 --
 CREATE TABLE INT4_TBL(f1 int4);
-INSERT INTO INT4_TBL(f1) VALUES ('0');
-INSERT INTO INT4_TBL(f1) VALUES ('123456');
-INSERT INTO INT4_TBL(f1) VALUES ('-123456');
+INSERT INTO INT4_TBL(f1) VALUES ('   0  ');
+INSERT INTO INT4_TBL(f1) VALUES ('123456     ');
+INSERT INTO INT4_TBL(f1) VALUES ('    -123456');
 INSERT INTO INT4_TBL(f1) VALUES ('34.5');
 ERROR:  invalid input syntax for integer: "34.5"
--- largest and smallest values 
+-- largest and smallest values
 INSERT INTO INT4_TBL(f1) VALUES ('2147483647');
 INSERT INTO INT4_TBL(f1) VALUES ('-2147483647');
--- bad input values -- should give warnings 
+-- bad input values -- should give errors
 INSERT INTO INT4_TBL(f1) VALUES ('1000000000000');
 ERROR:  value "1000000000000" is out of range for type integer
 INSERT INTO INT4_TBL(f1) VALUES ('asdf');
 ERROR:  invalid input syntax for integer: "asdf"
+INSERT INTO INT4_TBL(f1) VALUES ('     ');
+ERROR:  invalid input syntax for integer: "     "
+INSERT INTO INT4_TBL(f1) VALUES ('   asdf   ');
+ERROR:  invalid input syntax for integer: "   asdf   "
+INSERT INTO INT4_TBL(f1) VALUES ('- 1234');
+ERROR:  invalid input syntax for integer: "- 1234"
+INSERT INTO INT4_TBL(f1) VALUES ('123       5');
+ERROR:  invalid input syntax for integer: "123       5"
+INSERT INTO INT4_TBL(f1) VALUES ('');
+ERROR:  invalid input syntax for integer: ""
 SELECT '' AS five, INT4_TBL.*;
  five |     f1      
 ------+-------------
@@ -117,14 +127,14 @@ SELECT '' AS three, i.* FROM INT4_TBL i WHERE i.f1 >= int4 '0';
        | 2147483647
 (3 rows)
 
--- positive odds 
+-- positive odds
 SELECT '' AS one, i.* FROM INT4_TBL i WHERE (i.f1 % int2 '2') = int2 '1';
  one |     f1     
 -----+------------
      | 2147483647
 (1 row)
 
--- any evens 
+-- any evens
 SELECT '' AS three, i.* FROM INT4_TBL i WHERE (i.f1 % int4 '2') = int2 '0';
  three |   f1    
 -------+---------
index 931889c4ad96595a6481987532799736fe40639f..7172cc1071a5bb3e97c685fde6ff787bfde54f96 100644 (file)
@@ -3,11 +3,26 @@
 -- Test int8 64-bit integers.
 --
 CREATE TABLE INT8_TBL(q1 int8, q2 int8);
-INSERT INTO INT8_TBL VALUES('123','456');
-INSERT INTO INT8_TBL VALUES('123','4567890123456789');
+INSERT INTO INT8_TBL VALUES('  123   ','  456');
+INSERT INTO INT8_TBL VALUES('123   ','4567890123456789');
 INSERT INTO INT8_TBL VALUES('4567890123456789','123');
 INSERT INTO INT8_TBL VALUES('4567890123456789','4567890123456789');
 INSERT INTO INT8_TBL VALUES('4567890123456789','-4567890123456789');
+-- bad inputs
+INSERT INTO INT8_TBL(q1) VALUES ('      ');
+ERROR:  invalid input syntax for type bigint: "      "
+INSERT INTO INT8_TBL(q1) VALUES ('xxx');
+ERROR:  invalid input syntax for type bigint: "xxx"
+INSERT INTO INT8_TBL(q1) VALUES ('3908203590239580293850293850329485');
+ERROR:  integer out of range
+INSERT INTO INT8_TBL(q1) VALUES ('-1204982019841029840928340329840934');
+ERROR:  integer out of range
+INSERT INTO INT8_TBL(q1) VALUES ('- 123');
+ERROR:  invalid input syntax for type bigint: "- 123"
+INSERT INTO INT8_TBL(q1) VALUES ('  345     5');
+ERROR:  invalid input syntax for type bigint: "  345     5"
+INSERT INTO INT8_TBL(q1) VALUES ('');
+ERROR:  invalid input syntax for type bigint: ""
 SELECT * FROM INT8_TBL;
         q1        |        q2         
 ------------------+-------------------
index e1c7361b64a1092cce03c1714964e2fb733fe1fd..bf3bb441afc24db40e1c0f6f913893e580afd482 100644 (file)
@@ -670,6 +670,18 @@ SELECT AVG(val) FROM num_data;
  -13430913.592242320700
 (1 row)
 
+SELECT STDDEV(val) FROM num_data;
+            stddev             
+-------------------------------
+ 27791203.28758835329805617386
+(1 row)
+
+SELECT VARIANCE(val) FROM num_data;
+               variance               
+--------------------------------------
+ 772350980172061.69659105821915863601
+(1 row)
+
 -- Check for appropriate rounding and overflow
 CREATE TABLE fract_only (id int, val numeric(4,4));
 INSERT INTO fract_only VALUES (1, '0.0');
@@ -1112,3 +1124,44 @@ SELECT '' AS to_number_13, to_number(' . 0 1 -', ' 9 9 . 9 9 S');
               |     -0.01
 (1 row)
 
+--
+-- Input syntax
+--
+CREATE TABLE num_input_test (n1 numeric);
+-- good inputs
+INSERT INTO num_input_test(n1) VALUES (' 123');
+INSERT INTO num_input_test(n1) VALUES ('   3245874    ');
+INSERT INTO num_input_test(n1) VALUES ('  -93853');
+INSERT INTO num_input_test(n1) VALUES ('555.50');
+INSERT INTO num_input_test(n1) VALUES ('-555.50');
+INSERT INTO num_input_test(n1) VALUES ('NaN ');
+ERROR:  invalid input syntax for type numeric: "NaN "
+INSERT INTO num_input_test(n1) VALUES ('        nan');
+ERROR:  invalid input syntax for type numeric: "        nan"
+-- bad inputs
+INSERT INTO num_input_test(n1) VALUES ('     ');
+ERROR:  invalid input syntax for type numeric: "     "
+INSERT INTO num_input_test(n1) VALUES ('   1234   %');
+ERROR:  invalid input syntax for type numeric: "   1234   %"
+INSERT INTO num_input_test(n1) VALUES ('xyz');
+ERROR:  invalid input syntax for type numeric: "xyz"
+INSERT INTO num_input_test(n1) VALUES ('- 1234');
+ERROR:  invalid input syntax for type numeric: "- 1234"
+INSERT INTO num_input_test(n1) VALUES ('5 . 0');
+ERROR:  invalid input syntax for type numeric: "5 . 0"
+INSERT INTO num_input_test(n1) VALUES ('5. 0   ');
+ERROR:  invalid input syntax for type numeric: "5. 0   "
+INSERT INTO num_input_test(n1) VALUES ('');
+ERROR:  invalid input syntax for type numeric: ""
+INSERT INTO num_input_test(n1) VALUES (' N aN ');
+ERROR:  invalid input syntax for type numeric: " N aN "
+SELECT * FROM num_input_test;
+   n1    
+---------
+     123
+ 3245874
+  -93853
+  555.50
+ -555.50
+(5 rows)
+
index 570a4c77b36db712d00b69fb1cc556ea07f79898..092c9b1cfaf35ce9e5c5edb4d1d1fdf3bc8046f9 100644 (file)
@@ -7,11 +7,29 @@ INSERT INTO OID_TBL(f1) VALUES ('1235');
 INSERT INTO OID_TBL(f1) VALUES ('987');
 INSERT INTO OID_TBL(f1) VALUES ('-1040');
 INSERT INTO OID_TBL(f1) VALUES ('99999999');
+INSERT INTO OID_TBL(f1) VALUES ('5     ');
+INSERT INTO OID_TBL(f1) VALUES ('   10  ');
+-- leading/trailing hard tab is also allowed
+INSERT INTO OID_TBL(f1) VALUES ('        15      ');
 -- bad inputs 
 INSERT INTO OID_TBL(f1) VALUES ('asdfasd');
 ERROR:  invalid input syntax for type oid: "asdfasd"
 INSERT INTO OID_TBL(f1) VALUES ('99asdfasd');
 ERROR:  invalid input syntax for type oid: "99asdfasd"
+INSERT INTO OID_TBL(f1) VALUES ('5    d');
+ERROR:  invalid input syntax for type oid: "5    d"
+INSERT INTO OID_TBL(f1) VALUES ('    5d');
+ERROR:  invalid input syntax for type oid: "    5d"
+INSERT INTO OID_TBL(f1) VALUES ('5    5');
+ERROR:  invalid input syntax for type oid: "5    5"
+INSERT INTO OID_TBL(f1) VALUES ('    ');
+ERROR:  invalid input syntax for type oid: "    "
+INSERT INTO OID_TBL(f1) VALUES (' - 500');
+ERROR:  invalid input syntax for type oid: " - 500"
+INSERT INTO OID_TBL(f1) VALUES ('32958209582039852935');
+ERROR:  value "32958209582039852935" is out of range for type oid
+INSERT INTO OID_TBL(f1) VALUES ('-23582358720398502385');
+ERROR:  value "-23582358720398502385" is out of range for type oid
 SELECT '' AS six, OID_TBL.*;
  six |     f1     
 -----+------------
@@ -20,7 +38,10 @@ SELECT '' AS six, OID_TBL.*;
      |        987
      | 4294966256
      |   99999999
-(5 rows)
+     |          5
+     |         10
+     |         15
+(8 rows)
 
 SELECT '' AS one, o.* FROM OID_TBL o WHERE o.f1 = 1234;
  one |  f1  
@@ -35,20 +56,29 @@ SELECT '' AS five, o.* FROM OID_TBL o WHERE o.f1 <> '1234';
       |        987
       | 4294966256
       |   99999999
-(4 rows)
+      |          5
+      |         10
+      |         15
+(7 rows)
 
 SELECT '' AS three, o.* FROM OID_TBL o WHERE o.f1 <= '1234';
  three |  f1  
 -------+------
        | 1234
        |  987
-(2 rows)
+       |    5
+       |   10
+       |   15
+(5 rows)
 
 SELECT '' AS two, o.* FROM OID_TBL o WHERE o.f1 < '1234';
  two | f1  
 -----+-----
      | 987
-(1 row)
+     |   5
+     |  10
+     |  15
+(4 rows)
 
 SELECT '' AS four, o.* FROM OID_TBL o WHERE o.f1 >= '1234';
  four |     f1     
index 557c0f5f9d9142ea92ca817e99f138d89fe9f85c..c478dd71897478f69a07400f216369dd297b1683 100644 (file)
@@ -631,6 +631,7 @@ SELECT user_relns() AS user_relns
  num_exp_power_10_ln
  num_exp_sqrt
  num_exp_sub
+ num_input_test
  num_result
  onek
  onek2
@@ -660,7 +661,7 @@ SELECT user_relns() AS user_relns
  toyemp
  varchar_tbl
  xacttest
-(96 rows)
+(97 rows)
 
 --SELECT name(equipment(hobby_construct(text 'skywalking', text 'mer'))) AS equip_name;
 SELECT hobbies_by_name('basketball');
index 28c12c6fa4507513b16d34d45f7198d1ed454978..b7b64f2e50ea835730442634864beed4ed0064c3 100644 (file)
@@ -4,25 +4,33 @@
 
 CREATE TABLE FLOAT4_TBL (f1  float4);
 
-INSERT INTO FLOAT4_TBL(f1) VALUES ('0.0');
-
-INSERT INTO FLOAT4_TBL(f1) VALUES ('1004.30');
-
-INSERT INTO FLOAT4_TBL(f1) VALUES ('-34.84');
-
+INSERT INTO FLOAT4_TBL(f1) VALUES ('    0.0');
+INSERT INTO FLOAT4_TBL(f1) VALUES ('1004.30   ');
+INSERT INTO FLOAT4_TBL(f1) VALUES ('     -34.84    ');
 INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e+20');
-
 INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e-20');
 
 -- test for over and under flow 
 INSERT INTO FLOAT4_TBL(f1) VALUES ('10e40');
-
 INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e40');
-
 INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-40');
-
 INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-40');
 
+-- bad input
+INSERT INTO FLOAT4_TBL(f1) VALUES ('       ');
+INSERT INTO FLOAT4_TBL(f1) VALUES ('xyz');
+INSERT INTO FLOAT4_TBL(f1) VALUES ('5.0.0');
+INSERT INTO FLOAT4_TBL(f1) VALUES ('5 . 0');
+INSERT INTO FLOAT4_TBL(f1) VALUES ('5.   0');
+INSERT INTO FLOAT4_TBL(f1) VALUES ('     - 3.0');
+INSERT INTO FLOAT4_TBL(f1) VALUES ('123            5');
+
+-- special inputs
+SELECT 'NaN'::float4;
+SELECT 'nan'::float4;
+SELECT '   NAN  '::float4;
+-- bad special inputs
+SELECT 'N A N'::float4;
 
 SELECT '' AS five, FLOAT4_TBL.*;
 
index 2cdb64a75a98f796fac68636be92737538732964..1e5e8ad4302278b66f7c0ae4c3332e79bee61c0d 100644 (file)
@@ -4,16 +4,33 @@
 
 CREATE TABLE FLOAT8_TBL(f1 float8);
 
-INSERT INTO FLOAT8_TBL(f1) VALUES ('0.0');
-
-INSERT INTO FLOAT8_TBL(f1) VALUES ('1004.30');
-
-INSERT INTO FLOAT8_TBL(f1) VALUES ('-34.84');
-
+INSERT INTO FLOAT8_TBL(f1) VALUES ('    0.0   ');
+INSERT INTO FLOAT8_TBL(f1) VALUES ('1004.30  ');
+INSERT INTO FLOAT8_TBL(f1) VALUES ('   -34.84');
 INSERT INTO FLOAT8_TBL(f1) VALUES ('1.2345678901234e+200');
-
 INSERT INTO FLOAT8_TBL(f1) VALUES ('1.2345678901234e-200');
 
+-- test for underflow and overflow
+INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400');
+INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e400');
+INSERT INTO FLOAT8_TBL(f1) VALUES ('10e-400');
+INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e-400');
+
+-- bad input
+INSERT INTO FLOAT8_TBL(f1) VALUES ('     ');
+INSERT INTO FLOAT8_TBL(f1) VALUES ('xyz');
+INSERT INTO FLOAT8_TBL(f1) VALUES ('5.0.0');
+INSERT INTO FLOAT8_TBL(f1) VALUES ('5 . 0');
+INSERT INTO FLOAT8_TBL(f1) VALUES ('5.   0');
+INSERT INTO FLOAT8_TBL(f1) VALUES ('    - 3');
+INSERT INTO FLOAT8_TBL(f1) VALUES ('123           5');
+
+-- special inputs
+SELECT 'NaN'::float8;
+SELECT 'nan'::float8;
+SELECT '   NAN  '::float8;
+-- bad special inputs
+SELECT 'N A N'::float8;
 
 SELECT '' AS five, FLOAT8_TBL.*;
 
index 56cbb4c7c9c2cd3ca824c4a5224d1b9cca229041..e42b4236fdcfda2f9d799c8653e558fba82c67b9 100644 (file)
@@ -6,23 +6,27 @@
 
 CREATE TABLE INT2_TBL(f1 int2);
 
-INSERT INTO INT2_TBL(f1) VALUES ('0');
+INSERT INTO INT2_TBL(f1) VALUES ('0   ');
 
-INSERT INTO INT2_TBL(f1) VALUES ('1234');
+INSERT INTO INT2_TBL(f1) VALUES ('  1234 ');
 
-INSERT INTO INT2_TBL(f1) VALUES ('-1234');
+INSERT INTO INT2_TBL(f1) VALUES ('    -1234');
 
 INSERT INTO INT2_TBL(f1) VALUES ('34.5');
 
--- largest and smallest values 
+-- largest and smallest values
 INSERT INTO INT2_TBL(f1) VALUES ('32767');
 
 INSERT INTO INT2_TBL(f1) VALUES ('-32767');
 
--- bad input values -- should give warnings 
+-- bad input values -- should give errors
 INSERT INTO INT2_TBL(f1) VALUES ('100000');
-
 INSERT INTO INT2_TBL(f1) VALUES ('asdf');
+INSERT INTO INT2_TBL(f1) VALUES ('    ');
+INSERT INTO INT2_TBL(f1) VALUES ('- 1234');
+INSERT INTO INT2_TBL(f1) VALUES ('4 444');
+INSERT INTO INT2_TBL(f1) VALUES ('123 dt');
+INSERT INTO INT2_TBL(f1) VALUES ('');
 
 
 SELECT '' AS five, INT2_TBL.*;
index 8663e284fbf9b8317b58795a1bd9e5da3dd75181..85b22ccd0ab2c0b3ae5ae07424866ba91c781365 100644 (file)
@@ -6,23 +6,27 @@
 
 CREATE TABLE INT4_TBL(f1 int4);
 
-INSERT INTO INT4_TBL(f1) VALUES ('0');
+INSERT INTO INT4_TBL(f1) VALUES ('   0  ');
 
-INSERT INTO INT4_TBL(f1) VALUES ('123456');
+INSERT INTO INT4_TBL(f1) VALUES ('123456     ');
 
-INSERT INTO INT4_TBL(f1) VALUES ('-123456');
+INSERT INTO INT4_TBL(f1) VALUES ('    -123456');
 
 INSERT INTO INT4_TBL(f1) VALUES ('34.5');
 
--- largest and smallest values 
+-- largest and smallest values
 INSERT INTO INT4_TBL(f1) VALUES ('2147483647');
 
 INSERT INTO INT4_TBL(f1) VALUES ('-2147483647');
 
--- bad input values -- should give warnings 
+-- bad input values -- should give errors
 INSERT INTO INT4_TBL(f1) VALUES ('1000000000000');
-
 INSERT INTO INT4_TBL(f1) VALUES ('asdf');
+INSERT INTO INT4_TBL(f1) VALUES ('     ');
+INSERT INTO INT4_TBL(f1) VALUES ('   asdf   ');
+INSERT INTO INT4_TBL(f1) VALUES ('- 1234');
+INSERT INTO INT4_TBL(f1) VALUES ('123       5');
+INSERT INTO INT4_TBL(f1) VALUES ('');
 
 
 SELECT '' AS five, INT4_TBL.*;
@@ -51,10 +55,10 @@ SELECT '' AS three, i.* FROM INT4_TBL i WHERE i.f1 >= int2 '0';
 
 SELECT '' AS three, i.* FROM INT4_TBL i WHERE i.f1 >= int4 '0';
 
--- positive odds 
+-- positive odds
 SELECT '' AS one, i.* FROM INT4_TBL i WHERE (i.f1 % int2 '2') = int2 '1';
 
--- any evens 
+-- any evens
 SELECT '' AS three, i.* FROM INT4_TBL i WHERE (i.f1 % int4 '2') = int2 '0';
 
 SELECT '' AS five, i.f1, i.f1 * int2 '2' AS x FROM INT4_TBL i;
index b5cb13480be743bfeb686fc0abb5db4e0bd299b7..98b1606430daa5f4d7606f81c456317bc9058745 100644 (file)
@@ -4,12 +4,21 @@
 --
 CREATE TABLE INT8_TBL(q1 int8, q2 int8);
 
-INSERT INTO INT8_TBL VALUES('123','456');
-INSERT INTO INT8_TBL VALUES('123','4567890123456789');
+INSERT INTO INT8_TBL VALUES('  123   ','  456');
+INSERT INTO INT8_TBL VALUES('123   ','4567890123456789');
 INSERT INTO INT8_TBL VALUES('4567890123456789','123');
 INSERT INTO INT8_TBL VALUES('4567890123456789','4567890123456789');
 INSERT INTO INT8_TBL VALUES('4567890123456789','-4567890123456789');
 
+-- bad inputs
+INSERT INTO INT8_TBL(q1) VALUES ('      ');
+INSERT INTO INT8_TBL(q1) VALUES ('xxx');
+INSERT INTO INT8_TBL(q1) VALUES ('3908203590239580293850293850329485');
+INSERT INTO INT8_TBL(q1) VALUES ('-1204982019841029840928340329840934');
+INSERT INTO INT8_TBL(q1) VALUES ('- 123');
+INSERT INTO INT8_TBL(q1) VALUES ('  345     5');
+INSERT INTO INT8_TBL(q1) VALUES ('');
+
 SELECT * FROM INT8_TBL;
 
 SELECT '' AS five, q1 AS plus, -q1 AS minus FROM INT8_TBL;
index 4ded6607bde8cffb271f7ac539602cc90d95aa92..b39003440279092782d69947fdc6ff6bc01fb805 100644 (file)
@@ -639,6 +639,8 @@ SELECT t1.id1, t1.result, t2.expected
 -- ******************************
 -- numeric AVG used to fail on some platforms
 SELECT AVG(val) FROM num_data;
+SELECT STDDEV(val) FROM num_data;
+SELECT VARIANCE(val) FROM num_data;
 
 -- Check for appropriate rounding and overflow
 CREATE TABLE fract_only (id int, val numeric(4,4));
@@ -701,3 +703,30 @@ SELECT '' AS to_number_10, to_number('0', '99.99');
 SELECT '' AS to_number_11, to_number('.-01', 'S99.99');
 SELECT '' AS to_number_12, to_number('.01-', '99.99S');
 SELECT '' AS to_number_13, to_number(' . 0 1 -', ' 9 9 . 9 9 S');
+
+--
+-- Input syntax
+--
+
+CREATE TABLE num_input_test (n1 numeric);
+
+-- good inputs
+INSERT INTO num_input_test(n1) VALUES (' 123');
+INSERT INTO num_input_test(n1) VALUES ('   3245874    ');
+INSERT INTO num_input_test(n1) VALUES ('  -93853');
+INSERT INTO num_input_test(n1) VALUES ('555.50');
+INSERT INTO num_input_test(n1) VALUES ('-555.50');
+INSERT INTO num_input_test(n1) VALUES ('NaN ');
+INSERT INTO num_input_test(n1) VALUES ('        nan');
+
+-- bad inputs
+INSERT INTO num_input_test(n1) VALUES ('     ');
+INSERT INTO num_input_test(n1) VALUES ('   1234   %');
+INSERT INTO num_input_test(n1) VALUES ('xyz');
+INSERT INTO num_input_test(n1) VALUES ('- 1234');
+INSERT INTO num_input_test(n1) VALUES ('5 . 0');
+INSERT INTO num_input_test(n1) VALUES ('5. 0   ');
+INSERT INTO num_input_test(n1) VALUES ('');
+INSERT INTO num_input_test(n1) VALUES (' N aN ');
+
+SELECT * FROM num_input_test;
index a19f8fe998f6d52f9c9382d7bcce51ce5ba1c4be..a3ed212b6addec97500ed881d630cc0d2ad80730 100644 (file)
@@ -5,19 +5,26 @@
 CREATE TABLE OID_TBL(f1 oid);
 
 INSERT INTO OID_TBL(f1) VALUES ('1234');
-
 INSERT INTO OID_TBL(f1) VALUES ('1235');
-
 INSERT INTO OID_TBL(f1) VALUES ('987');
-
 INSERT INTO OID_TBL(f1) VALUES ('-1040');
-
 INSERT INTO OID_TBL(f1) VALUES ('99999999');
+INSERT INTO OID_TBL(f1) VALUES ('5     ');
+INSERT INTO OID_TBL(f1) VALUES ('   10  ');
+-- leading/trailing hard tab is also allowed
+INSERT INTO OID_TBL(f1) VALUES ('        15      ');
 
 -- bad inputs 
 
 INSERT INTO OID_TBL(f1) VALUES ('asdfasd');
 INSERT INTO OID_TBL(f1) VALUES ('99asdfasd');
+INSERT INTO OID_TBL(f1) VALUES ('5    d');
+INSERT INTO OID_TBL(f1) VALUES ('    5d');
+INSERT INTO OID_TBL(f1) VALUES ('5    5');
+INSERT INTO OID_TBL(f1) VALUES ('    ');
+INSERT INTO OID_TBL(f1) VALUES (' - 500');
+INSERT INTO OID_TBL(f1) VALUES ('32958209582039852935');
+INSERT INTO OID_TBL(f1) VALUES ('-23582358720398502385');
 
 SELECT '' AS six, OID_TBL.*;