mirror of
https://github.com/postgres/postgres.git
synced 2025-05-06 19:59:18 +03:00
Improve the consistency of the error message emitted when rejecting
invalid input to the oid type. Also, remove some long-unused code from adt/numutils.c
This commit is contained in:
parent
afcc6fbb60
commit
4553e1d80f
@ -3,15 +3,14 @@
|
|||||||
* numutils.c
|
* numutils.c
|
||||||
* utility functions for I/O of built-in numeric types.
|
* utility functions for I/O of built-in numeric types.
|
||||||
*
|
*
|
||||||
* integer: pg_itoa, pg_ltoa
|
* integer: pg_atoi, pg_itoa, pg_ltoa
|
||||||
* floating point: ftoa, atof1
|
|
||||||
*
|
*
|
||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/numutils.c,v 1.60 2004/01/07 18:56:28 neilc Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/numutils.c,v 1.61 2004/02/18 00:01:33 neilc Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -147,334 +146,3 @@ pg_ltoa(int32 l, char *a)
|
|||||||
{
|
{
|
||||||
sprintf(a, "%d", l);
|
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
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/oid.c,v 1.53 2003/11/29 19:51:59 pgsql Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/oid.c,v 1.54 2004/02/18 00:01:34 neilc Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -46,18 +46,18 @@ oidin_subr(const char *funcname, const char *s, char **endloc)
|
|||||||
if (errno && errno != ERANGE && errno != EINVAL)
|
if (errno && errno != ERANGE && errno != EINVAL)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||||
errmsg("invalid input syntax for type \"oid\": \"%s\"",
|
errmsg("invalid input syntax for type oid: \"%s\"",
|
||||||
s)));
|
s)));
|
||||||
if (endptr == s && *endptr)
|
if (endptr == s && *endptr)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||||
errmsg("invalid input syntax for type \"oid\": \"%s\"",
|
errmsg("invalid input syntax for type oid: \"%s\"",
|
||||||
s)));
|
s)));
|
||||||
|
|
||||||
if (errno == ERANGE)
|
if (errno == ERANGE)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||||
errmsg("value \"%s\" is out of range for type \"oid\"", s)));
|
errmsg("value \"%s\" is out of range for type oid", s)));
|
||||||
|
|
||||||
if (endloc)
|
if (endloc)
|
||||||
{
|
{
|
||||||
@ -72,7 +72,7 @@ oidin_subr(const char *funcname, const char *s, char **endloc)
|
|||||||
if (*endptr)
|
if (*endptr)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||||
errmsg("invalid input syntax for type \"oid\": \"%s\"",
|
errmsg("invalid input syntax for type oid: \"%s\"",
|
||||||
s)));
|
s)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ oidin_subr(const char *funcname, const char *s, char **endloc)
|
|||||||
cvt != (unsigned long) ((int) result))
|
cvt != (unsigned long) ((int) result))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||||
errmsg("value \"%s\" is out of range for type \"oid\"", s)));
|
errmsg("value \"%s\" is out of range for type oid", s)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -10,9 +10,9 @@ INSERT INTO OID_TBL(f1) VALUES ('99999999');
|
|||||||
INSERT INTO OID_TBL(f1) VALUES ('');
|
INSERT INTO OID_TBL(f1) VALUES ('');
|
||||||
-- bad inputs
|
-- bad inputs
|
||||||
INSERT INTO OID_TBL(f1) VALUES ('asdfasd');
|
INSERT INTO OID_TBL(f1) VALUES ('asdfasd');
|
||||||
ERROR: invalid input syntax for type "oid": "asdfasd"
|
ERROR: invalid input syntax for type oid: "asdfasd"
|
||||||
INSERT INTO OID_TBL(f1) VALUES ('99asdfasd');
|
INSERT INTO OID_TBL(f1) VALUES ('99asdfasd');
|
||||||
ERROR: invalid input syntax for type "oid": "99asdfasd"
|
ERROR: invalid input syntax for type oid: "99asdfasd"
|
||||||
SELECT '' AS six, OID_TBL.*;
|
SELECT '' AS six, OID_TBL.*;
|
||||||
six | f1
|
six | f1
|
||||||
-----+------------
|
-----+------------
|
||||||
|
Loading…
x
Reference in New Issue
Block a user