Skip to content

Commit 647fa50

Browse files
committed
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
1 parent 3f244d0 commit 647fa50

File tree

2 files changed

+22
-29
lines changed

2 files changed

+22
-29
lines changed

src/backend/utils/adt/int.c

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,13 @@ int2vectorin(PG_FUNCTION_ARGS)
143143
char *intString = PG_GETARG_CSTRING(0);
144144
Node *escontext = fcinfo->context;
145145
int2vector *result;
146+
int nalloc;
146147
int n;
147148

148-
result = (int2vector *) palloc0(Int2VectorSize(FUNC_MAX_ARGS));
149+
nalloc = 32; /* arbitrary initial size guess */
150+
result = (int2vector *) palloc0(Int2VectorSize(nalloc));
149151

150-
for (n = 0; n < FUNC_MAX_ARGS; n++)
152+
for (n = 0;; n++)
151153
{
152154
long l;
153155
char *endp;
@@ -157,6 +159,12 @@ int2vectorin(PG_FUNCTION_ARGS)
157159
if (*intString == '\0')
158160
break;
159161

162+
if (n >= nalloc)
163+
{
164+
nalloc *= 2;
165+
result = (int2vector *) repalloc(result, Int2VectorSize(nalloc));
166+
}
167+
160168
errno = 0;
161169
l = strtol(intString, &endp, 10);
162170

@@ -176,17 +184,11 @@ int2vectorin(PG_FUNCTION_ARGS)
176184
ereturn(escontext, (Datum) 0,
177185
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
178186
errmsg("invalid input syntax for type %s: \"%s\"",
179-
"integer", intString)));
187+
"smallint", intString)));
180188

181189
result->values[n] = l;
182190
intString = endp;
183191
}
184-
while (*intString && isspace((unsigned char) *intString))
185-
intString++;
186-
if (*intString)
187-
ereturn(escontext, (Datum) 0,
188-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
189-
errmsg("int2vector has too many elements")));
190192

191193
SET_VARSIZE(result, Int2VectorSize(n));
192194
result->ndim = 1;
@@ -261,12 +263,6 @@ int2vectorrecv(PG_FUNCTION_ARGS)
261263
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
262264
errmsg("invalid int2vector data")));
263265

264-
/* check length for consistency with int2vectorin() */
265-
if (ARR_DIMS(result)[0] > FUNC_MAX_ARGS)
266-
ereport(ERROR,
267-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
268-
errmsg("oidvector has too many elements")));
269-
270266
PG_RETURN_POINTER(result);
271267
}
272268

src/backend/utils/adt/oid.c

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -115,27 +115,30 @@ oidvectorin(PG_FUNCTION_ARGS)
115115
char *oidString = PG_GETARG_CSTRING(0);
116116
Node *escontext = fcinfo->context;
117117
oidvector *result;
118+
int nalloc;
118119
int n;
119120

120-
result = (oidvector *) palloc0(OidVectorSize(FUNC_MAX_ARGS));
121+
nalloc = 32; /* arbitrary initial size guess */
122+
result = (oidvector *) palloc0(OidVectorSize(nalloc));
121123

122-
for (n = 0; n < FUNC_MAX_ARGS; n++)
124+
for (n = 0;; n++)
123125
{
124126
while (*oidString && isspace((unsigned char) *oidString))
125127
oidString++;
126128
if (*oidString == '\0')
127129
break;
130+
131+
if (n >= nalloc)
132+
{
133+
nalloc *= 2;
134+
result = (oidvector *) repalloc(result, OidVectorSize(nalloc));
135+
}
136+
128137
result->values[n] = uint32in_subr(oidString, &oidString,
129138
"oid", escontext);
130139
if (SOFT_ERROR_OCCURRED(escontext))
131140
PG_RETURN_NULL();
132141
}
133-
while (*oidString && isspace((unsigned char) *oidString))
134-
oidString++;
135-
if (*oidString)
136-
ereturn(escontext, (Datum) 0,
137-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
138-
errmsg("oidvector has too many elements")));
139142

140143
SET_VARSIZE(result, OidVectorSize(n));
141144
result->ndim = 1;
@@ -212,12 +215,6 @@ oidvectorrecv(PG_FUNCTION_ARGS)
212215
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
213216
errmsg("invalid oidvector data")));
214217

215-
/* check length for consistency with oidvectorin() */
216-
if (ARR_DIMS(result)[0] > FUNC_MAX_ARGS)
217-
ereport(ERROR,
218-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
219-
errmsg("oidvector has too many elements")));
220-
221218
PG_RETURN_POINTER(result);
222219
}
223220

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy