mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-29 22:49:41 +03:00 
			
		
		
		
	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:
		| @@ -142,11 +142,13 @@ int2vectorin(PG_FUNCTION_ARGS) | |||||||
| { | { | ||||||
| 	char	   *intString = PG_GETARG_CSTRING(0); | 	char	   *intString = PG_GETARG_CSTRING(0); | ||||||
| 	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; | ||||||
| @@ -156,6 +158,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); | ||||||
|  |  | ||||||
| @@ -175,17 +183,11 @@ int2vectorin(PG_FUNCTION_ARGS) | |||||||
| 			ereport(ERROR, | 			ereport(ERROR, | ||||||
| 					(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) |  | ||||||
| 		ereport(ERROR, |  | ||||||
| 				(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; | ||||||
| @@ -260,12 +262,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); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -195,24 +195,27 @@ oidvectorin(PG_FUNCTION_ARGS) | |||||||
| { | { | ||||||
| 	char	   *oidString = PG_GETARG_CSTRING(0); | 	char	   *oidString = PG_GETARG_CSTRING(0); | ||||||
| 	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] = oidin_subr(oidString, &oidString); | 		result->values[n] = oidin_subr(oidString, &oidString); | ||||||
| 	} | 	} | ||||||
| 	while (*oidString && isspace((unsigned char) *oidString)) |  | ||||||
| 		oidString++; |  | ||||||
| 	if (*oidString) |  | ||||||
| 		ereport(ERROR, |  | ||||||
| 				(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; | ||||||
| @@ -289,12 +292,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); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user