diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2023-01-15 17:32:09 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2023-01-15 17:32:09 -0500 |
commit | db9127c58cbaa748d00055ce10c6bf50a7fbcc1e (patch) | |
tree | 82ddf52ae2f160758557a9b34550113f77c62a09 /src/backend/utils/adt/int.c | |
parent | a8f7687a0b8645697b48cc40fd1a73d455d0c1fc (diff) | |
download | postgresql-db9127c58cbaa748d00055ce10c6bf50a7fbcc1e.tar.gz postgresql-db9127c58cbaa748d00055ce10c6bf50a7fbcc1e.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.c | 26 |
1 files changed, 11 insertions, 15 deletions
diff --git a/src/backend/utils/adt/int.c b/src/backend/utils/adt/int.c index 42ddae99ef4..ff1f46e2b42 100644 --- a/src/backend/utils/adt/int.c +++ b/src/backend/utils/adt/int.c @@ -142,11 +142,13 @@ int2vectorin(PG_FUNCTION_ARGS) { char *intString = PG_GETARG_CSTRING(0); 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; @@ -156,6 +158,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); @@ -175,17 +183,11 @@ int2vectorin(PG_FUNCTION_ARGS) ereport(ERROR, (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) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("int2vector has too many elements"))); SET_VARSIZE(result, Int2VectorSize(n)); result->ndim = 1; @@ -260,12 +262,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); } |