提交 4553e1d8 编写于 作者: N Neil Conway

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
上级 afcc6fbb
......@@ -3,15 +3,14 @@
* numutils.c
* utility functions for I/O of built-in numeric types.
*
* integer: pg_itoa, pg_ltoa
* floating point: ftoa, atof1
* 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
*
*
* 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);
}
/*
** 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
* $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)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for type \"oid\": \"%s\"",
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\"",
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)));
errmsg("value \"%s\" is out of range for type oid", s)));
if (endloc)
{
......@@ -72,7 +72,7 @@ oidin_subr(const char *funcname, const char *s, char **endloc)
if (*endptr)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for type \"oid\": \"%s\"",
errmsg("invalid input syntax for type oid: \"%s\"",
s)));
}
......@@ -95,7 +95,7 @@ oidin_subr(const char *funcname, const char *s, char **endloc)
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)));
errmsg("value \"%s\" is out of range for type oid", s)));
#endif
return result;
......
......@@ -10,9 +10,9 @@ INSERT INTO OID_TBL(f1) VALUES ('99999999');
INSERT INTO OID_TBL(f1) VALUES ('');
-- bad inputs
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');
ERROR: invalid input syntax for type "oid": "99asdfasd"
ERROR: invalid input syntax for type oid: "99asdfasd"
SELECT '' AS six, OID_TBL.*;
six | f1
-----+------------
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册