Hi,

On 2023-01-15 15:17:16 -0500, Tom Lane wrote:
> Andres Freund <and...@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.

We'll practically error out at a much lower limit than that, due to, due to
reaching the max length of a row and int2vector not being toastable. So I'm
just wondering if we want to set the limit to something that'll commonly avoid
erroring out out with something like
  ERROR:  54000: row is too big: size 10048, maximum size 8160

For the purpose here a limit of MaxTupleAttributeNumber or such instead of
FUNC_MAX_ARGS would do the trick, I think?


> 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));
> +             }

Should this be repalloc0? I don't know if the palloc0 above was just used with
the goal of initializing the "header" fields, or also to avoid trailing
uninitialized bytes?

Greetings,

Andres Freund


Reply via email to