]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Remove arbitrary FUNC_MAX_ARGS limit in int2vectorin and oidvectorin.
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 15 Jan 2023 22:32:09 +0000 (17:32 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 15 Jan 2023 22:32:09 +0000 (17:32 -0500)
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

src/backend/utils/adt/int.c
src/backend/utils/adt/oid.c

index e47c15a54f605e2a64d186bf6f4f2b628ec577db..44d1c7ad0c4d770acc33f35bb57080bac7670e5c 100644 (file)
@@ -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);
 }
 
index 697588313da6600cce9483277e1bb9ddd300a76d..3f7af5b3a066148a7b8bfbae3eaa3a338e527a6e 100644 (file)
@@ -115,27 +115,30 @@ oidvectorin(PG_FUNCTION_ARGS)
        char       *oidString = PG_GETARG_CSTRING(0);
        Node       *escontext = fcinfo->context;
        oidvector  *result;
+       int                     nalloc;
        int                     n;
 
-       result = (oidvector *) palloc0(OidVectorSize(FUNC_MAX_ARGS));
+       nalloc = 32;                            /* arbitrary initial size guess */
+       result = (oidvector *) palloc0(OidVectorSize(nalloc));
 
-       for (n = 0; n < FUNC_MAX_ARGS; n++)
+       for (n = 0;; n++)
        {
                while (*oidString && isspace((unsigned char) *oidString))
                        oidString++;
                if (*oidString == '\0')
                        break;
+
+               if (n >= nalloc)
+               {
+                       nalloc *= 2;
+                       result = (oidvector *) repalloc(result, OidVectorSize(nalloc));
+               }
+
                result->values[n] = uint32in_subr(oidString, &oidString,
                                                                                  "oid", escontext);
                if (SOFT_ERROR_OCCURRED(escontext))
                        PG_RETURN_NULL();
        }
-       while (*oidString && isspace((unsigned char) *oidString))
-               oidString++;
-       if (*oidString)
-               ereturn(escontext, (Datum) 0,
-                               (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                                errmsg("oidvector has too many elements")));
 
        SET_VARSIZE(result, OidVectorSize(n));
        result->ndim = 1;
@@ -212,12 +215,6 @@ oidvectorrecv(PG_FUNCTION_ARGS)
                                (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
                                 errmsg("invalid oidvector data")));
 
-       /* check length for consistency with oidvectorin() */
-       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);
 }