float8in(PG_FUNCTION_ARGS)
{
char *num = PG_GETARG_CSTRING(0);
- char *orig_num;
+
+ PG_RETURN_FLOAT8(float8in_internal(num, NULL, "double precision", num));
+}
+
+/*
+ * float8in_internal - guts of float8in()
+ *
+ * This is exposed for use by functions that want a reasonably
+ * platform-independent way of inputting doubles. The behavior is
+ * essentially like strtod + ereport on error, but note the following
+ * differences:
+ * 1. Both leading and trailing whitespace are skipped.
+ * 2. If endptr_p is NULL, we throw error if there's trailing junk.
+ * Otherwise, it's up to the caller to complain about trailing junk.
+ * 3. In event of a syntax error, the report mentions the given type_name
+ * and prints orig_string as the input; this is meant to support use of
+ * this function with types such as "box" and "point", where what we are
+ * parsing here is just a substring of orig_string.
+ *
+ * "num" could validly be declared "const char *", but that results in an
+ * unreasonable amount of extra casting both here and in callers, so we don't.
+ */
+double
+float8in_internal(char *num, char **endptr_p,
+ const char *type_name, const char *orig_string)
+{
double val;
char *endptr;
- /*
- * endptr points to the first character _after_ the sequence we recognized
- * as a valid floating point number. orig_num points to the original input
- * string.
- */
- orig_num = num;
-
/* skip leading whitespace */
while (*num != '\0' && isspace((unsigned char) *num))
num++;
if (*num == '\0')
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid input syntax for type double precision: \"%s\"",
- orig_num)));
+ errmsg("invalid input syntax for type %s: \"%s\"",
+ type_name, orig_string)));
errno = 0;
val = strtod(num, &endptr);
* precision). We'd prefer not to throw error for that, so try to
* detect whether it's a "real" out-of-range condition by checking
* to see if the result is zero or huge.
+ *
+ * On error, we intentionally complain about double precision not
+ * the given type name, and we print only the part of the string
+ * that is the current number.
*/
if (val == 0.0 || val >= HUGE_VAL || val <= -HUGE_VAL)
+ {
+ char *errnumber = pstrdup(num);
+
+ errnumber[endptr - num] = '\0';
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("\"%s\" is out of range for type double precision",
- orig_num)));
+ errnumber)));
+ }
}
else
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid input syntax for type double precision: \"%s\"",
- orig_num)));
+ errmsg("invalid input syntax for type %s: \"%s\"",
+ type_name, orig_string)));
}
#ifdef HAVE_BUGGY_SOLARIS_STRTOD
else
while (*endptr != '\0' && isspace((unsigned char) *endptr))
endptr++;
- /* if there is any junk left at the end of the string, bail out */
- if (*endptr != '\0')
+ /* report stopping point if wanted, else complain if not end of string */
+ if (endptr_p)
+ *endptr_p = endptr;
+ else if (*endptr != '\0')
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid input syntax for type double precision: \"%s\"",
- orig_num)));
+ errmsg("invalid input syntax for type %s: \"%s\"",
+ type_name, orig_string)));
- CHECKFLOATVAL(val, true, true);
-
- PG_RETURN_FLOAT8(val);
+ return val;
}
/*
float8out(PG_FUNCTION_ARGS)
{
float8 num = PG_GETARG_FLOAT8(0);
+
+ PG_RETURN_CSTRING(float8out_internal(num));
+}
+
+/*
+ * float8out_internal - guts of float8out()
+ *
+ * This is exposed for use by functions that want a reasonably
+ * platform-independent way of outputting doubles.
+ * The result is always palloc'd.
+ */
+char *
+float8out_internal(double num)
+{
char *ascii = (char *) palloc(MAXDOUBLEWIDTH + 1);
if (isnan(num))
- PG_RETURN_CSTRING(strcpy(ascii, "NaN"));
+ return strcpy(ascii, "NaN");
switch (is_infinite(num))
{
}
}
- PG_RETURN_CSTRING(ascii);
+ return ascii;
}
/*
static bool plist_same(int npts, Point *p1, Point *p2);
static Point *point_construct(double x, double y);
static Point *point_copy(Point *pt);
-static int single_decode(char *str, float8 *x, char **ss);
-static int single_encode(float8 x, char *str);
-static int pair_decode(char *str, float8 *x, float8 *y, char **s);
-static int pair_encode(float8 x, float8 y, char *str);
+static double single_decode(char *num, char **endptr_p,
+ const char *type_name, const char *orig_string);
+static void single_encode(float8 x, StringInfo str);
+static void pair_decode(char *str, double *x, double *y, char **endptr_p,
+ const char *type_name, const char *orig_string);
+static void pair_encode(float8 x, float8 y, StringInfo str);
static int pair_count(char *s, char delim);
-static int path_decode(int opentype, int npts, char *str, int *isopen, char **ss, Point *p);
+static void path_decode(char *str, bool opentype, int npts, Point *p,
+ bool *isopen, char **endptr_p,
+ const char *type_name, const char *orig_string);
static char *path_encode(enum path_delim path_delim, int npts, Point *pt);
static void statlseg_construct(LSEG *lseg, Point *pt1, Point *pt2);
static double box_ar(BOX *box);
#define LDELIM_C '<'
#define RDELIM_C '>'
-/* Maximum number of characters printed by pair_encode() */
-/* ...+3+7 : 3 accounts for extra_float_digits max value */
-#define P_MAXLEN (2*(DBL_DIG+3+7)+1)
-
/*
* Geometric data types are composed of points.
* and restore that order for text output - tgl 97/01/16
*/
-static int
-single_decode(char *str, float8 *x, char **s)
+static double
+single_decode(char *num, char **endptr_p,
+ const char *type_name, const char *orig_string)
{
- char *cp;
-
- if (!PointerIsValid(str))
- return FALSE;
-
- *x = strtod(str, &cp);
-
-#ifdef GEODEBUG
- printf("single_decode- decoded first %d chars of \"%s\" to %g\n",
- (int) (cp - str), str, *x);
-#endif
-
- if (s != NULL)
- {
- while (isspace((unsigned char) *cp))
- cp++;
- *s = cp;
- }
-
- return TRUE;
+ return float8in_internal(num, endptr_p, type_name, orig_string);
} /* single_decode() */
-static int
-single_encode(float8 x, char *str)
+static void
+single_encode(float8 x, StringInfo str)
{
- int ndig = DBL_DIG + extra_float_digits;
+ char *xstr = float8out_internal(x);
- if (ndig < 1)
- ndig = 1;
-
- sprintf(str, "%.*g", ndig, x);
- return TRUE;
+ appendStringInfoString(str, xstr);
+ pfree(xstr);
} /* single_encode() */
-static int
-pair_decode(char *str, float8 *x, float8 *y, char **s)
+static void
+pair_decode(char *str, double *x, double *y, char **endptr_p,
+ const char *type_name, const char *orig_string)
{
- int has_delim;
- char *cp;
-
- if (!PointerIsValid(str))
- return FALSE;
+ bool has_delim;
while (isspace((unsigned char) *str))
str++;
if ((has_delim = (*str == LDELIM)))
str++;
- while (isspace((unsigned char) *str))
- str++;
- *x = strtod(str, &cp);
- if (cp <= str)
- return FALSE;
- while (isspace((unsigned char) *cp))
- cp++;
- if (*cp++ != DELIM)
- return FALSE;
- while (isspace((unsigned char) *cp))
- cp++;
- *y = strtod(cp, &str);
- if (str <= cp)
- return FALSE;
- while (isspace((unsigned char) *str))
- str++;
+ *x = float8in_internal(str, &str, type_name, orig_string);
+
+ if (*str++ != DELIM)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+ errmsg("invalid input syntax for type %s: \"%s\"",
+ type_name, orig_string)));
+
+ *y = float8in_internal(str, &str, type_name, orig_string);
+
if (has_delim)
{
- if (*str != RDELIM)
- return FALSE;
- str++;
+ if (*str++ != RDELIM)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+ errmsg("invalid input syntax for type %s: \"%s\"",
+ type_name, orig_string)));
while (isspace((unsigned char) *str))
str++;
}
- if (s != NULL)
- *s = str;
- return TRUE;
+ /* report stopping point if wanted, else complain if not end of string */
+ if (endptr_p)
+ *endptr_p = str;
+ else if (*str != '\0')
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+ errmsg("invalid input syntax for type %s: \"%s\"",
+ type_name, orig_string)));
}
-static int
-pair_encode(float8 x, float8 y, char *str)
+static void
+pair_encode(float8 x, float8 y, StringInfo str)
{
- int ndig = DBL_DIG + extra_float_digits;
+ char *xstr = float8out_internal(x);
+ char *ystr = float8out_internal(y);
- if (ndig < 1)
- ndig = 1;
-
- sprintf(str, "%.*g,%.*g", ndig, x, ndig, y);
- return TRUE;
+ appendStringInfo(str, "%s,%s", xstr, ystr);
+ pfree(xstr);
+ pfree(ystr);
}
-static int
-path_decode(int opentype, int npts, char *str, int *isopen, char **ss, Point *p)
+static void
+path_decode(char *str, bool opentype, int npts, Point *p,
+ bool *isopen, char **endptr_p,
+ const char *type_name, const char *orig_string)
{
int depth = 0;
- char *s,
- *cp;
+ char *cp;
int i;
- s = str;
- while (isspace((unsigned char) *s))
- s++;
- if ((*isopen = (*s == LDELIM_EP)))
+ while (isspace((unsigned char) *str))
+ str++;
+ if ((*isopen = (*str == LDELIM_EP)))
{
/* no open delimiter allowed? */
if (!opentype)
- return FALSE;
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+ errmsg("invalid input syntax for type %s: \"%s\"",
+ type_name, orig_string)));
depth++;
- s++;
- while (isspace((unsigned char) *s))
- s++;
-
+ str++;
}
- else if (*s == LDELIM)
+ else if (*str == LDELIM)
{
- cp = (s + 1);
+ cp = (str + 1);
while (isspace((unsigned char) *cp))
cp++;
if (*cp == LDELIM)
{
-#ifdef NOT_USED
- /* nested delimiters with only one point? */
- if (npts <= 1)
- return FALSE;
-#endif
depth++;
- s = cp;
+ str = cp;
}
- else if (strrchr(s, LDELIM) == s)
+ else if (strrchr(str, LDELIM) == str)
{
depth++;
- s = cp;
+ str = cp;
}
}
for (i = 0; i < npts; i++)
{
- if (!pair_decode(s, &(p->x), &(p->y), &s))
- return FALSE;
-
- if (*s == DELIM)
- s++;
+ pair_decode(str, &(p->x), &(p->y), &str, type_name, orig_string);
+ if (*str == DELIM)
+ str++;
p++;
}
+ while (isspace((unsigned char) *str))
+ str++;
while (depth > 0)
{
- if ((*s == RDELIM)
- || ((*s == RDELIM_EP) && (*isopen) && (depth == 1)))
+ if ((*str == RDELIM)
+ || ((*str == RDELIM_EP) && (*isopen) && (depth == 1)))
{
depth--;
- s++;
- while (isspace((unsigned char) *s))
- s++;
+ str++;
+ while (isspace((unsigned char) *str))
+ str++;
}
else
- return FALSE;
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+ errmsg("invalid input syntax for type %s: \"%s\"",
+ type_name, orig_string)));
}
- *ss = s;
- return TRUE;
+ /* report stopping point if wanted, else complain if not end of string */
+ if (endptr_p)
+ *endptr_p = str;
+ else if (*str != '\0')
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+ errmsg("invalid input syntax for type %s: \"%s\"",
+ type_name, orig_string)));
} /* path_decode() */
static char *
path_encode(enum path_delim path_delim, int npts, Point *pt)
{
- int size = npts * (P_MAXLEN + 3) + 2;
- char *result;
- char *cp;
+ StringInfoData str;
int i;
- /* Check for integer overflow */
- if ((size - 2) / npts != (P_MAXLEN + 3))
- ereport(ERROR,
- (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
- errmsg("too many points requested")));
-
- result = palloc(size);
+ initStringInfo(&str);
- cp = result;
switch (path_delim)
{
case PATH_CLOSED:
- *cp++ = LDELIM;
+ appendStringInfoChar(&str, LDELIM);
break;
case PATH_OPEN:
- *cp++ = LDELIM_EP;
+ appendStringInfoChar(&str, LDELIM_EP);
break;
case PATH_NONE:
break;
for (i = 0; i < npts; i++)
{
- *cp++ = LDELIM;
- if (!pair_encode(pt->x, pt->y, cp))
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("could not format \"path\" value")));
-
- cp += strlen(cp);
- *cp++ = RDELIM;
- *cp++ = DELIM;
+ if (i > 0)
+ appendStringInfoChar(&str, DELIM);
+ appendStringInfoChar(&str, LDELIM);
+ pair_encode(pt->x, pt->y, &str);
+ appendStringInfoChar(&str, RDELIM);
pt++;
}
- cp--;
+
switch (path_delim)
{
case PATH_CLOSED:
- *cp++ = RDELIM;
+ appendStringInfoChar(&str, RDELIM);
break;
case PATH_OPEN:
- *cp++ = RDELIM_EP;
+ appendStringInfoChar(&str, RDELIM_EP);
break;
case PATH_NONE:
break;
}
- *cp = '\0';
- return result;
+ return str.data;
} /* path_encode() */
/*-------------------------------------------------------------
{
char *str = PG_GETARG_CSTRING(0);
BOX *box = (BOX *) palloc(sizeof(BOX));
- int isopen;
- char *s;
+ bool isopen;
double x,
y;
- if ((!path_decode(FALSE, 2, str, &isopen, &s, &(box->high)))
- || (*s != '\0'))
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid input syntax for type box: \"%s\"", str)));
+ path_decode(str, false, 2, &(box->high), &isopen, NULL, "box", str);
/* reorder corners if necessary... */
if (box->high.x < box->low.x)
***********************************************************************/
static bool
-line_decode(const char *str, LINE *line)
+line_decode(char *s, const char *str, LINE *line)
{
- char *tail;
-
- while (isspace((unsigned char) *str))
- str++;
- if (*str++ != '{')
- return false;
- line->A = strtod(str, &tail);
- if (tail <= str)
- return false;
- str = tail;
- while (isspace((unsigned char) *str))
- str++;
- if (*str++ != DELIM)
- return false;
- line->B = strtod(str, &tail);
- if (tail <= str)
+ /* s was already advanced over leading '{' */
+ line->A = single_decode(s, &s, "line", str);
+ if (*s++ != DELIM)
return false;
- str = tail;
- while (isspace((unsigned char) *str))
- str++;
- if (*str++ != DELIM)
+ line->B = single_decode(s, &s, "line", str);
+ if (*s++ != DELIM)
return false;
- line->C = strtod(str, &tail);
- if (tail <= str)
- return false;
- str = tail;
- while (isspace((unsigned char) *str))
- str++;
- if (*str++ != '}')
+ line->C = single_decode(s, &s, "line", str);
+ if (*s++ != '}')
return false;
- while (isspace((unsigned char) *str))
- str++;
- if (*str)
+ while (isspace((unsigned char) *s))
+ s++;
+ if (*s != '\0')
return false;
-
return true;
}
line_in(PG_FUNCTION_ARGS)
{
char *str = PG_GETARG_CSTRING(0);
- LINE *line;
+ LINE *line = (LINE *) palloc(sizeof(LINE));
LSEG lseg;
- int isopen;
+ bool isopen;
char *s;
- line = (LINE *) palloc(sizeof(LINE));
-
- if (path_decode(TRUE, 2, str, &isopen, &s, &(lseg.p[0])) && *s == '\0')
+ s = str;
+ while (isspace((unsigned char) *s))
+ s++;
+ if (*s == '{')
{
- if (FPeq(lseg.p[0].x, lseg.p[1].x) && FPeq(lseg.p[0].y, lseg.p[1].y))
+ if (!line_decode(s + 1, str, line))
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid line specification: must be two distinct points")));
-
- line_construct_pts(line, &lseg.p[0], &lseg.p[1]);
- }
- else if (line_decode(str, line))
- {
+ errmsg("invalid input syntax for type %s: \"%s\"",
+ "line", str)));
if (FPzero(line->A) && FPzero(line->B))
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid line specification: A and B cannot both be zero")));
}
else
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid input syntax for type line: \"%s\"", str)));
+ {
+ path_decode(s, true, 2, &(lseg.p[0]), &isopen, NULL, "line", str);
+ if (FPeq(lseg.p[0].x, lseg.p[1].x) && FPeq(lseg.p[0].y, lseg.p[1].y))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+ errmsg("invalid line specification: must be two distinct points")));
+ line_construct_pts(line, &lseg.p[0], &lseg.p[1]);
+ }
PG_RETURN_LINE_P(line);
}
line_out(PG_FUNCTION_ARGS)
{
LINE *line = PG_GETARG_LINE_P(0);
- int ndig = DBL_DIG + extra_float_digits;
+ char *astr = float8out_internal(line->A);
+ char *bstr = float8out_internal(line->B);
+ char *cstr = float8out_internal(line->C);
- if (ndig < 1)
- ndig = 1;
-
- PG_RETURN_CSTRING(psprintf("{%.*g,%.*g,%.*g}", ndig, line->A, ndig, line->B, ndig, line->C));
+ PG_RETURN_CSTRING(psprintf("{%s,%s,%s}", astr, bstr, cstr));
}
/*
{
char *str = PG_GETARG_CSTRING(0);
PATH *path;
- int isopen;
+ bool isopen;
char *s;
int npts;
int size;
if ((npts = pair_count(str, ',')) <= 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid input syntax for type path: \"%s\"", str)));
+ errmsg("invalid input syntax for type %s: \"%s\"",
+ "path", str)));
s = str;
while (isspace((unsigned char) *s))
SET_VARSIZE(path, size);
path->npts = npts;
- if ((!path_decode(TRUE, npts, s, &isopen, &s, &(path->p[0])))
- && (!((depth == 0) && (*s == '\0'))) && !((depth >= 1) && (*s == RDELIM)))
+ path_decode(s, true, npts, &(path->p[0]), &isopen, &s, "path", str);
+
+ if (depth >= 1)
+ {
+ if (*s++ != RDELIM)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+ errmsg("invalid input syntax for type %s: \"%s\"",
+ "path", str)));
+ while (isspace((unsigned char) *s))
+ s++;
+ }
+ if (*s != '\0')
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid input syntax for type path: \"%s\"", str)));
+ errmsg("invalid input syntax for type %s: \"%s\"",
+ "path", str)));
path->closed = (!isopen);
/* prevent instability in unused pad bytes */
point_in(PG_FUNCTION_ARGS)
{
char *str = PG_GETARG_CSTRING(0);
- Point *point;
- double x,
- y;
- char *s;
-
- if (!pair_decode(str, &x, &y, &s) || (*s != '\0'))
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid input syntax for type point: \"%s\"", str)));
-
- point = (Point *) palloc(sizeof(Point));
-
- point->x = x;
- point->y = y;
+ Point *point = (Point *) palloc(sizeof(Point));
+ pair_decode(str, &point->x, &point->y, NULL, "point", str);
PG_RETURN_POINT_P(point);
}
lseg_in(PG_FUNCTION_ARGS)
{
char *str = PG_GETARG_CSTRING(0);
- LSEG *lseg;
- int isopen;
- char *s;
-
- lseg = (LSEG *) palloc(sizeof(LSEG));
-
- if ((!path_decode(TRUE, 2, str, &isopen, &s, &(lseg->p[0])))
- || (*s != '\0'))
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid input syntax for type lseg: \"%s\"", str)));
+ LSEG *lseg = (LSEG *) palloc(sizeof(LSEG));
+ bool isopen;
+ path_decode(str, true, 2, &(lseg->p[0]), &isopen, NULL, "lseg", str);
PG_RETURN_LSEG_P(lseg);
}
int npts;
int size;
int base_size;
- int isopen;
- char *s;
+ bool isopen;
if ((npts = pair_count(str, ',')) <= 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid input syntax for type polygon: \"%s\"", str)));
+ errmsg("invalid input syntax for type %s: \"%s\"",
+ "polygon", str)));
base_size = sizeof(poly->p[0]) * npts;
size = offsetof(POLYGON, p) +base_size;
SET_VARSIZE(poly, size);
poly->npts = npts;
- if ((!path_decode(FALSE, npts, str, &isopen, &s, &(poly->p[0])))
- || (*s != '\0'))
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid input syntax for type polygon: \"%s\"", str)));
+ path_decode(str, false, npts, &(poly->p[0]), &isopen, NULL, "polygon", str);
make_bound_box(poly);
circle_in(PG_FUNCTION_ARGS)
{
char *str = PG_GETARG_CSTRING(0);
- CIRCLE *circle;
+ CIRCLE *circle = (CIRCLE *) palloc(sizeof(CIRCLE));
char *s,
*cp;
int depth = 0;
- circle = (CIRCLE *) palloc(sizeof(CIRCLE));
-
s = str;
while (isspace((unsigned char) *s))
s++;
s = cp;
}
- if (!pair_decode(s, &circle->center.x, &circle->center.y, &s))
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid input syntax for type circle: \"%s\"", str)));
+ pair_decode(s, &circle->center.x, &circle->center.y, &s, "circle", str);
if (*s == DELIM)
s++;
- while (isspace((unsigned char) *s))
- s++;
- if ((!single_decode(s, &circle->radius, &s)) || (circle->radius < 0))
+ circle->radius = single_decode(s, &s, "circle", str);
+ if (circle->radius < 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid input syntax for type circle: \"%s\"", str)));
+ errmsg("invalid input syntax for type %s: \"%s\"",
+ "circle", str)));
while (depth > 0)
{
else
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid input syntax for type circle: \"%s\"", str)));
+ errmsg("invalid input syntax for type %s: \"%s\"",
+ "circle", str)));
}
if (*s != '\0')
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid input syntax for type circle: \"%s\"", str)));
+ errmsg("invalid input syntax for type %s: \"%s\"",
+ "circle", str)));
PG_RETURN_CIRCLE_P(circle);
}
circle_out(PG_FUNCTION_ARGS)
{
CIRCLE *circle = PG_GETARG_CIRCLE_P(0);
- char *result;
- char *cp;
-
- result = palloc(2 * P_MAXLEN + 6);
+ StringInfoData str;
- cp = result;
- *cp++ = LDELIM_C;
- *cp++ = LDELIM;
- if (!pair_encode(circle->center.x, circle->center.y, cp))
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("could not format \"circle\" value")));
-
- cp += strlen(cp);
- *cp++ = RDELIM;
- *cp++ = DELIM;
- if (!single_encode(circle->radius, cp))
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("could not format \"circle\" value")));
+ initStringInfo(&str);
- cp += strlen(cp);
- *cp++ = RDELIM_C;
- *cp = '\0';
+ appendStringInfoChar(&str, LDELIM_C);
+ appendStringInfoChar(&str, LDELIM);
+ pair_encode(circle->center.x, circle->center.y, &str);
+ appendStringInfoChar(&str, RDELIM);
+ appendStringInfoChar(&str, DELIM);
+ single_encode(circle->radius, &str);
+ appendStringInfoChar(&str, RDELIM_C);
- PG_RETURN_CSTRING(result);
+ PG_RETURN_CSTRING(str.data);
}
/*