mirror of https://github.com/postgres/postgres
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
This commit is contained in:
parent
3f244d020f
commit
647fa50054
|
@ -143,11 +143,13 @@ int2vectorin(PG_FUNCTION_ARGS)
|
||||||
char *intString = PG_GETARG_CSTRING(0);
|
char *intString = PG_GETARG_CSTRING(0);
|
||||||
Node *escontext = fcinfo->context;
|
Node *escontext = fcinfo->context;
|
||||||
int2vector *result;
|
int2vector *result;
|
||||||
|
int nalloc;
|
||||||
int n;
|
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;
|
long l;
|
||||||
char *endp;
|
char *endp;
|
||||||
|
@ -157,6 +159,12 @@ int2vectorin(PG_FUNCTION_ARGS)
|
||||||
if (*intString == '\0')
|
if (*intString == '\0')
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (n >= nalloc)
|
||||||
|
{
|
||||||
|
nalloc *= 2;
|
||||||
|
result = (int2vector *) repalloc(result, Int2VectorSize(nalloc));
|
||||||
|
}
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
l = strtol(intString, &endp, 10);
|
l = strtol(intString, &endp, 10);
|
||||||
|
|
||||||
|
@ -176,17 +184,11 @@ int2vectorin(PG_FUNCTION_ARGS)
|
||||||
ereturn(escontext, (Datum) 0,
|
ereturn(escontext, (Datum) 0,
|
||||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||||
errmsg("invalid input syntax for type %s: \"%s\"",
|
errmsg("invalid input syntax for type %s: \"%s\"",
|
||||||
"integer", intString)));
|
"smallint", intString)));
|
||||||
|
|
||||||
result->values[n] = l;
|
result->values[n] = l;
|
||||||
intString = endp;
|
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));
|
SET_VARSIZE(result, Int2VectorSize(n));
|
||||||
result->ndim = 1;
|
result->ndim = 1;
|
||||||
|
@ -261,12 +263,6 @@ int2vectorrecv(PG_FUNCTION_ARGS)
|
||||||
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
|
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
|
||||||
errmsg("invalid int2vector data")));
|
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);
|
PG_RETURN_POINTER(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -115,27 +115,30 @@ oidvectorin(PG_FUNCTION_ARGS)
|
||||||
char *oidString = PG_GETARG_CSTRING(0);
|
char *oidString = PG_GETARG_CSTRING(0);
|
||||||
Node *escontext = fcinfo->context;
|
Node *escontext = fcinfo->context;
|
||||||
oidvector *result;
|
oidvector *result;
|
||||||
|
int nalloc;
|
||||||
int n;
|
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))
|
while (*oidString && isspace((unsigned char) *oidString))
|
||||||
oidString++;
|
oidString++;
|
||||||
if (*oidString == '\0')
|
if (*oidString == '\0')
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (n >= nalloc)
|
||||||
|
{
|
||||||
|
nalloc *= 2;
|
||||||
|
result = (oidvector *) repalloc(result, OidVectorSize(nalloc));
|
||||||
|
}
|
||||||
|
|
||||||
result->values[n] = uint32in_subr(oidString, &oidString,
|
result->values[n] = uint32in_subr(oidString, &oidString,
|
||||||
"oid", escontext);
|
"oid", escontext);
|
||||||
if (SOFT_ERROR_OCCURRED(escontext))
|
if (SOFT_ERROR_OCCURRED(escontext))
|
||||||
PG_RETURN_NULL();
|
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));
|
SET_VARSIZE(result, OidVectorSize(n));
|
||||||
result->ndim = 1;
|
result->ndim = 1;
|
||||||
|
@ -212,12 +215,6 @@ oidvectorrecv(PG_FUNCTION_ARGS)
|
||||||
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
|
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
|
||||||
errmsg("invalid oidvector data")));
|
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);
|
PG_RETURN_POINTER(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue