Re: logrep stuck with 'ERROR: int2vector has too many elements'

Поиск
Список
Период
Сортировка
От Tom Lane
Тема Re: logrep stuck with 'ERROR: int2vector has too many elements'
Дата
Msg-id 1688010.1673813836@sss.pgh.pa.us
обсуждение исходный текст
Ответ на Re: logrep stuck with 'ERROR: int2vector has too many elements'  (Andres Freund <andres@anarazel.de>)
Ответы Re: logrep stuck with 'ERROR: int2vector has too many elements'  (Andres Freund <andres@anarazel.de>)
Список pgsql-hackers
Andres Freund <andres@anarazel.de> writes:
> On 2023-01-15 14:39:41 -0500, Tom Lane wrote:
>> But I suppose we are stuck with that, seeing that this datatype choice
>> is effectively part of the logrep protocol now.  I think the only
>> reasonable solution is to get rid of the FUNC_MAX_ARGS restriction
>> in int2vectorin.  We probably ought to back-patch that as far as
>> pg_publication_rel.prattrs exists, too.

> Are you thinking of introducing another, or just "rely" on too long arrays to
> trigger errors when forming tuples?

There's enough protections already, eg repalloc will complain if you
try to go past 1GB.  I'm thinking of the attached for HEAD (it'll
take minor mods to back-patch).

            regards, tom lane

diff --git a/src/backend/utils/adt/int.c b/src/backend/utils/adt/int.c
index e47c15a54f..44d1c7ad0c 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);
 }
 
diff --git a/src/backend/utils/adt/oid.c b/src/backend/utils/adt/oid.c
index 697588313d..3f7af5b3a0 100644
--- a/src/backend/utils/adt/oid.c
+++ b/src/backend/utils/adt/oid.c
@@ -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);
 }


В списке pgsql-hackers по дате отправления:

Предыдущее
От: Andrey Chudnovsky
Дата:
Сообщение: Re: [PoC] Federated Authn/z with OAUTHBEARER
Следующее
От: Andres Freund
Дата:
Сообщение: Re: Sampling-based timing for EXPLAIN ANALYZE