Thread: fix oid casting inconsistency

fix oid casting inconsistency

From
Neil Conway
Date:
This patch fixes a minor error message inconsistency. When rejecting
input to the oid type, the following error message is emitted:

nconway=# select 'd'::oid;
ERROR:  invalid input syntax for type "oid": "d"

This patch removes the quotes from "oid", to make this error message
consistent with the error messages for rejected input to most other
types.

While I suppose it's possible that some applications might be
examining this error message string, (a) this particular error message
isn't very likely be used for that (b) we have error codes now.

I also took the liberty of removing some long-unused code from
src/backend/utils/adt/numutils.c

Unless anyone objects, I'll apply this within 24 hours.

-Neil

Index: src/backend/utils/adt/numutils.c
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/backend/utils/adt/numutils.c,v
retrieving revision 1.60
diff -c -r1.60 numutils.c
*** a/src/backend/utils/adt/numutils.c    7 Jan 2004 18:56:28 -0000    1.60
--- b/src/backend/utils/adt/numutils.c    17 Feb 2004 02:06:52 -0000
***************
*** 3,10 ****
   * numutils.c
   *      utility functions for I/O of built-in numeric types.
   *
!  *        integer:                pg_itoa, pg_ltoa
!  *        floating point:            ftoa, atof1
   *
   * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
   * Portions Copyright (c) 1994, Regents of the University of California
--- 3,9 ----
   * numutils.c
   *      utility functions for I/O of built-in numeric types.
   *
!  *        integer:                pg_atoi, pg_itoa, pg_ltoa
   *
   * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
   * Portions Copyright (c) 1994, Regents of the University of California
***************
*** 147,480 ****
  {
      sprintf(a, "%d", l);
  }
-
- /*
-  **  ftoa        - FLOATING POINT TO ASCII CONVERSION
-  **
-  **        CODE derived from ingres, ~ingres/source/gutil/ftoa.c
-  **
-  **        'Value' is converted to an ascii character string and stored
-  **        into 'ascii'.  Ascii should have room for at least 'width' + 1
-  **        characters.  'Width' is the width of the output field (max).
-  **        'Prec' is the number of characters to put after the decimal
-  **        point.    The format of the output string is controlled by
-  **        'format'.
-  **
-  **        'Format' can be:
-  **                e or E: "E" format output
-  **                f or F:  "F" format output
-  **                g or G:  "F" format output if it will fit, otherwise
-  **                        use "E" format.
-  **                n or N:  same as G, but decimal points will not always
-  **                        be aligned.
-  **
-  **        If 'format' is upper case, the "E" comes out in upper case;
-  **        otherwise it comes out in lower case.
-  **
-  **        When the field width is not big enough, it fills the field with
-  **        stars ("*****") and returns zero.  Normal return is the width
-  **        of the output field (sometimes shorter than 'width').
-  */
- #ifdef NOT_USED
- int
- ftoa(double value, char *ascii, int width, int prec1, char format)
- {
- #ifndef HAVE_FCVT
-     char        out[256];
-     char        fmt[256];
-     int            ret;
-
-     sprintf(fmt, "%%%d.%d%c", width, prec1, format);
-     sprintf(out, fmt, value);
-     if ((ret = strlen(out)) > width)
-     {
-         MemSet(ascii, '*', width - 2);
-         ascii[width] = 0;
-         return 0;
-     }
-     strcpy(ascii, out);
-     return ret;
- #else
-     auto int    expon;
-     auto int    sign;
-     int            avail = 0;
-     char       *a = NULL;
-     char       *p = NULL;
-     char        mode;
-     int            lowercase;
-     int            prec;
-
- /*      extern char        *ecvt(), *fcvt();*/
-
-     prec = prec1;
-     mode = format;
-     lowercase = 'a' - 'A';
-     if (mode >= 'a')
-         mode -= 'a' - 'A';
-     else
-         lowercase = 0;
-
-     if (mode != 'E')
-     {
-         /* try 'F' style output */
-         p = fcvt(value, prec, &expon, &sign);
-         avail = width;
-         a = ascii;
-
-         /* output sign */
-         if (sign)
-         {
-             avail--;
-             *a++ = '-';
-         }
-
-         /* output '0' before the decimal point */
-         if (expon <= 0)
-         {
-             *a++ = '0';
-             avail--;
-         }
-
-         /* compute space length left after dec pt and fraction */
-         avail -= prec + 1;
-         if (mode == 'G')
-             avail -= 4;
-
-         if (avail >= expon)
-         {
-
-             /* it fits.  output */
-             while (expon > 0)
-             {
-                 /* output left of dp */
-                 expon--;
-                 if (*p)
-                     *a++ = *p++;
-                 else
-                     *a++ = '0';
-             }
-
-             /* output fraction (right of dec pt) */
-             avail = expon;
-             goto frac_out;
-         }
-         /* won't fit; let's hope for G format */
-     }
-
-     if (mode != 'F')
-     {
-         /* try to do E style output */
-         p = ecvt(value, prec + 1, &expon, &sign);
-         avail = width - 5;
-         a = ascii;
-
-         /* output the sign */
-         if (sign)
-         {
-             *a++ = '-';
-             avail--;
-         }
-     }
-
-     /* check for field too small */
-     if (mode == 'F' || avail < prec)
-     {
-         /* sorry joker, you lose */
-         a = ascii;
-         for (avail = width; avail > 0; avail--)
-             *a++ = '*';
-         *a = 0;
-         return 0;
-     }
-
-     /* it fits; output the number */
-     mode = 'E';
-
-     /* output the LHS single digit */
-     *a++ = *p++;
-     expon--;
-
-     /* output the rhs */
-     avail = 1;
-
- frac_out:
-     *a++ = '.';
-     while (prec > 0)
-     {
-         prec--;
-         if (avail < 0)
-         {
-             avail++;
-             *a++ = '0';
-         }
-         else
-         {
-             if (*p)
-                 *a++ = *p++;
-             else
-                 *a++ = '0';
-         }
-     }
-
-     /* output the exponent */
-     if (mode == 'E')
-     {
-         *a++ = 'E' + lowercase;
-         if (expon < 0)
-         {
-             *a++ = '-';
-             expon = -expon;
-         }
-         else
-             *a++ = '+';
-         *a++ = (expon / 10) % 10 + '0';
-         *a++ = expon % 10 + '0';
-     }
-
-     /* output spaces on the end in G format */
-     if (mode == 'G')
-     {
-         *a++ = ' ';
-         *a++ = ' ';
-         *a++ = ' ';
-         *a++ = ' ';
-     }
-
-     /* finally, we can return */
-     *a = 0;
-     avail = a - ascii;
-     return avail;
- #endif
- }
- #endif
-
- /*
-  **   atof1        - ASCII TO FLOATING CONVERSION
-  **
-  **        CODE derived from ~ingres/source/gutil/atof.c
-  **
-  **        Converts the string 'str' to floating point and stores the
-  **        result into the cell pointed to by 'val'.
-  **
-  **        The syntax which it accepts is pretty much what you would
-  **        expect.  Basically, it is:
-  **                {<sp>} [+|-] {<sp>} {<digit>} [.{digit}] {<sp>} [<exp>]
-  **        where <exp> is "e" or "E" followed by an integer, <sp> is a
-  **        space character, <digit> is zero through nine, [] is zero or
-  **        one, and {} is zero or more.
-  **
-  **        Parameters:
-  **                str -- string to convert.
-  **                val -- pointer to place to put the result (which
-  **                        must be type double).
-  **
-  **        Returns:
-  **                zero -- ok.
-  **                -1 -- syntax error.
-  **                +1 -- overflow (not implemented).
-  **
-  **        Side Effects:
-  **                clobbers *val.
-  */
- #ifdef NOT_USED
- int
- atof1(char *str, double *val)
- {
-     char       *p;
-     double        v;
-     double        fact;
-     int            minus;
-     char        c;
-     int            expon;
-     int            gotmant;
-
-     v = 0.0;
-     p = str;
-     minus = 0;
-
-     /* skip leading blanks */
-     while ((c = *p) != '\0')
-     {
-         if (c != ' ')
-             break;
-         p++;
-     }
-
-     /* handle possible sign */
-     switch (c)
-     {
-         case '-':
-             minus++;
-
-         case '+':
-             p++;
-     }
-
-     /* skip blanks after sign */
-     while ((c = *p) != '\0')
-     {
-         if (c != ' ')
-             break;
-         p++;
-     }
-
-     /* start collecting the number to the decimal point */
-     gotmant = 0;
-     for (;;)
-     {
-         c = *p;
-         if (c < '0' || c > '9')
-             break;
-         v = v * 10.0 + (c - '0');
-         gotmant++;
-         p++;
-     }
-
-     /* check for fractional part */
-     if (c == '.')
-     {
-         fact = 1.0;
-         for (;;)
-         {
-             c = *++p;
-             if (c < '0' || c > '9')
-                 break;
-             fact *= 0.1;
-             v += (c - '0') * fact;
-             gotmant++;
-         }
-     }
-
-     /* skip blanks before possible exponent */
-     while ((c = *p) != '\0')
-     {
-         if (c != ' ')
-             break;
-         p++;
-     }
-
-     /* test for exponent */
-     if (c == 'e' || c == 'E')
-     {
-         p++;
-         expon = pg_atoi(p, sizeof(expon), '\0');
-         if (!gotmant)
-             v = 1.0;
-         fact = expon;
-         v *= pow(10.0, fact);
-     }
-     else
-     {
-         /* if no exponent, then nothing */
-         if (c != 0)
-             return -1;
-     }
-
-     /* store the result and exit */
-     if (minus)
-         v = -v;
-     *val = v;
-     return 0;
- }
-
- #endif
--- 146,148 ----
Index: src/backend/utils/adt/oid.c
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/backend/utils/adt/oid.c,v
retrieving revision 1.53
diff -c -r1.53 oid.c
*** a/src/backend/utils/adt/oid.c    29 Nov 2003 19:51:59 -0000    1.53
--- b/src/backend/utils/adt/oid.c    17 Feb 2004 02:03:26 -0000
***************
*** 46,63 ****
      if (errno && errno != ERANGE && errno != EINVAL)
          ereport(ERROR,
                  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
!                  errmsg("invalid input syntax for type \"oid\": \"%s\"",
                          s)));
      if (endptr == s && *endptr)
          ereport(ERROR,
                  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
!                  errmsg("invalid input syntax for type \"oid\": \"%s\"",
                          s)));

      if (errno == ERANGE)
          ereport(ERROR,
                  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
!                  errmsg("value \"%s\" is out of range for type \"oid\"", s)));

      if (endloc)
      {
--- 46,63 ----
      if (errno && errno != ERANGE && errno != EINVAL)
          ereport(ERROR,
                  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
!                  errmsg("invalid input syntax for type oid: \"%s\"",
                          s)));
      if (endptr == s && *endptr)
          ereport(ERROR,
                  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
!                  errmsg("invalid input syntax for type oid: \"%s\"",
                          s)));

      if (errno == ERANGE)
          ereport(ERROR,
                  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
!                  errmsg("value \"%s\" is out of range for type oid", s)));

      if (endloc)
      {
***************
*** 72,78 ****
          if (*endptr)
              ereport(ERROR,
                      (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
!                      errmsg("invalid input syntax for type \"oid\": \"%s\"",
                              s)));
      }

--- 72,78 ----
          if (*endptr)
              ereport(ERROR,
                      (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
!                      errmsg("invalid input syntax for type oid: \"%s\"",
                              s)));
      }

***************
*** 95,101 ****
          cvt != (unsigned long) ((int) result))
          ereport(ERROR,
                  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
!                  errmsg("value \"%s\" is out of range for type \"oid\"", s)));
  #endif

      return result;
--- 95,101 ----
          cvt != (unsigned long) ((int) result))
          ereport(ERROR,
                  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
!                  errmsg("value \"%s\" is out of range for type oid", s)));
  #endif

      return result;
Index: src/test/regress/expected/oid.out
===================================================================
RCS file: /var/lib/cvs/pgsql-server/src/test/regress/expected/oid.out,v
retrieving revision 1.7
diff -c -r1.7 oid.out
*** a/src/test/regress/expected/oid.out    25 Sep 2003 06:58:06 -0000    1.7
--- b/src/test/regress/expected/oid.out    17 Feb 2004 02:16:58 -0000
***************
*** 10,18 ****
  INSERT INTO OID_TBL(f1) VALUES ('');
  -- 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"
  SELECT '' AS six, OID_TBL.*;
   six |     f1
  -----+------------
--- 10,18 ----
  INSERT INTO OID_TBL(f1) VALUES ('');
  -- 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"
  SELECT '' AS six, OID_TBL.*;
   six |     f1
  -----+------------

Re: fix oid casting inconsistency

From
Alvaro Herrera
Date:
On Mon, Feb 16, 2004 at 10:00:49PM -0500, Neil Conway wrote:

> This patch removes the quotes from "oid", to make this error message
> consistent with the error messages for rejected input to most other
> types.
>
> While I suppose it's possible that some applications might be
> examining this error message string, (a) this particular error message
> isn't very likely be used for that (b) we have error codes now.

This kind of error message consistency enhancement has been applied
liberally in the past.

--
Alvaro Herrera (<alvherre[a]dcc.uchile.cl>)
"If you have nothing to say, maybe you need just the right tool to help you
not say it."                   (New York Times, about Microsoft PowerPoint)