aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/int.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2023-01-15 17:32:09 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2023-01-15 17:32:09 -0500
commit647fa500547fdf2a967412633a9f6f21ba69e144 (patch)
treeb895eec537674d20058d3c757f942217d28475db /src/backend/utils/adt/int.c
parent3f244d020fbf0b4f01d71e1b7620930be4bf9dc5 (diff)
downloadpostgresql-647fa500547fdf2a967412633a9f6f21ba69e144.tar.gz
postgresql-647fa500547fdf2a967412633a9f6f21ba69e144.zip
Remove arbitrary FUNC_MAX_ARGS limit in int2vectorin and oidvectorin.
int2vectorin limited the number of array elements it'd take to FUNC_MAX_ARGS, which is probably fine for the traditional use-cases. But now that pg_publication_rel.prattrs is an int2vector, it's not fine at all: it's easy to construct cases where that can have up to about MaxTupleAttributeNumber entries. Trying to replicate such tables leads to logical-replication failures. As long as we have to touch this code anyway, let's just remove the a-priori limit altogether, and let it accept any size that'll be allowed by repalloc. (Note that since int2vector isn't toastable, we cannot store arrays longer than about BLCKSZ/2; but there is no good excuse for letting int2vectorin depend on that. Perhaps we will lift the no-toast restriction someday.) While at it, also improve the equivalent logic in oidvectorin. I don't know of any practical use-case for long oidvectors right now, but doing it right actually makes the code shorter. Per report from Erik Rijkers. Back-patch to v15 where pg_publication_rel.prattrs was added. Discussion: https://postgr.es/m/668ba539-33c5-8190-ca11-def2913cb94b@xs4all.nl
Diffstat (limited to 'src/backend/utils/adt/int.c')
-rw-r--r--src/backend/utils/adt/int.c26
1 files changed, 11 insertions, 15 deletions
diff --git a/src/backend/utils/adt/int.c b/src/backend/utils/adt/int.c
index e47c15a54f6..44d1c7ad0c4 100644
--- a/src/backend/utils/adt/int.c
+++ b/src/backend/utils/adt/int.c
@@ -143,11 +143,13 @@ int2vectorin(PG_FUNCTION_ARGS)
char *intString = PG_GETARG_CSTRING(0);
Node *escontext = fcinfo->context;
int2vector *result;
+ int nalloc;
int n;
- result = (int2vector *) palloc0(Int2VectorSize(FUNC_MAX_ARGS));
+ nalloc = 32; /* arbitrary initial size guess */
+ result = (int2vector *) palloc0(Int2VectorSize(nalloc));
- for (n = 0; n < FUNC_MAX_ARGS; n++)
+ for (n = 0;; n++)
{
long l;
char *endp;
@@ -157,6 +159,12 @@ int2vectorin(PG_FUNCTION_ARGS)
if (*intString == '\0')
break;
+ if (n >= nalloc)
+ {
+ nalloc *= 2;
+ result = (int2vector *) repalloc(result, Int2VectorSize(nalloc));
+ }
+
errno = 0;
l = strtol(intString, &endp, 10);
@@ -176,17 +184,11 @@ int2vectorin(PG_FUNCTION_ARGS)
ereturn(escontext, (Datum) 0,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for type %s: \"%s\"",
- "integer", intString)));
+ "smallint", intString)));
result->values[n] = l;
intString = endp;
}
- while (*intString && isspace((unsigned char) *intString))
- intString++;
- if (*intString)
- ereturn(escontext, (Datum) 0,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("int2vector has too many elements")));
SET_VARSIZE(result, Int2VectorSize(n));
result->ndim = 1;
@@ -261,12 +263,6 @@ int2vectorrecv(PG_FUNCTION_ARGS)
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
errmsg("invalid int2vector data")));
- /* check length for consistency with int2vectorin() */
- if (ARR_DIMS(result)[0] > FUNC_MAX_ARGS)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("oidvector has too many elements")));
-
PG_RETURN_POINTER(result);
}