pg_proc.dat "proargmodes is not a 1-D char array"
Hi all
Random tip for future searchers. If you've modified pg_proc.dat and initdb
fails with "proargmodes is not a 1-D char array" - it could well actually
be that the length of proargmodes does not match the length of
proallargtypes given the test
ARR_DIMS(arr)[0] != numargs ||
in funcapi.c.
--
Craig Ringer http://www.2ndQuadrant.com/
2ndQuadrant - PostgreSQL Solutions for the Enterprise
On 2020-Sep-30, Craig Ringer wrote:
Hi all
Random tip for future searchers. If you've modified pg_proc.dat and initdb
fails with "proargmodes is not a 1-D char array" - it could well actually
be that the length of proargmodes does not match the length of
proallargtypes given the testARR_DIMS(arr)[0] != numargs ||
in funcapi.c.
Perhaps we can improve these error messages like below. (Or maybe just
keep it one message "proargmodes is not a 1-D char array of %d
elements"?) There are about 5 places to change I think.
diff --git a/src/backend/utils/fmgr/funcapi.c b/src/backend/utils/fmgr/funcapi.c
index b9efa77291..c76c16f799 100644
--- a/src/backend/utils/fmgr/funcapi.c
+++ b/src/backend/utils/fmgr/funcapi.c
@@ -1167,10 +1167,11 @@ get_func_arg_info(HeapTuple procTup,
{
arr = DatumGetArrayTypeP(proargmodes); /* ensure not toasted */
if (ARR_NDIM(arr) != 1 ||
- ARR_DIMS(arr)[0] != numargs ||
ARR_HASNULL(arr) ||
ARR_ELEMTYPE(arr) != CHAROID)
elog(ERROR, "proargmodes is not a 1-D char array");
+ if (ARR_DIMS(arr)[0] != numargs)
+ elog(ERROR, "proargmodes is not %d elements long", numargs);
*p_argmodes = (char *) palloc(numargs * sizeof(char));
memcpy(*p_argmodes, ARR_DATA_PTR(arr),
numargs * sizeof(char));
Alvaro Herrera <alvherre@alvh.no-ip.org> writes:
Perhaps we can improve these error messages like below. (Or maybe just
keep it one message "proargmodes is not a 1-D char array of %d
elements"?) There are about 5 places to change I think.
I doubt that it's really worth expending more code on this.
Certainly I see no reason why that particular test is more likely
to fail than the others, in the presence of corrupt data --- and
I don't want to add individual elog's for each one.
Adding the expected length to the error message might be OK though.
regards, tom lane
On Tue, Nov 17, 2020 at 10:32 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
Adding the expected length to the error message might be OK though.
Certainly seems like we should do at least that much. The current
message is just wrong, right?
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
Robert Haas <robertmhaas@gmail.com> writes:
On Tue, Nov 17, 2020 at 10:32 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
Adding the expected length to the error message might be OK though.
Certainly seems like we should do at least that much. The current
message is just wrong, right?
It's incomplete, for sure. Doesn't mention nulls either.
regards, tom lane
On 2020-Nov-17, Tom Lane wrote:
Robert Haas <robertmhaas@gmail.com> writes:
On Tue, Nov 17, 2020 at 10:32 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
Adding the expected length to the error message might be OK though.
Certainly seems like we should do at least that much. The current
message is just wrong, right?It's incomplete, for sure. Doesn't mention nulls either.
So let's go with this one.
Attachments:
arraylen.patchtext/x-diff; charset=us-asciiDownload
diff --git a/src/backend/utils/fmgr/funcapi.c b/src/backend/utils/fmgr/funcapi.c
index b9efa77291..9696c88f24 100644
--- a/src/backend/utils/fmgr/funcapi.c
+++ b/src/backend/utils/fmgr/funcapi.c
@@ -1123,7 +1123,7 @@ get_func_arg_info(HeapTuple procTup,
numargs < 0 ||
ARR_HASNULL(arr) ||
ARR_ELEMTYPE(arr) != OIDOID)
- elog(ERROR, "proallargtypes is not a 1-D Oid array");
+ elog(ERROR, "proallargtypes is not a 1-D Oid array or it contains nulls");
Assert(numargs >= procStruct->pronargs);
*p_argtypes = (Oid *) palloc(numargs * sizeof(Oid));
memcpy(*p_argtypes, ARR_DATA_PTR(arr),
@@ -1170,7 +1170,8 @@ get_func_arg_info(HeapTuple procTup,
ARR_DIMS(arr)[0] != numargs ||
ARR_HASNULL(arr) ||
ARR_ELEMTYPE(arr) != CHAROID)
- elog(ERROR, "proargmodes is not a 1-D char array");
+ elog(ERROR, "proargmodes is not a 1-D char array of length %d or it contains nulls",
+ numargs);
*p_argmodes = (char *) palloc(numargs * sizeof(char));
memcpy(*p_argmodes, ARR_DATA_PTR(arr),
numargs * sizeof(char));
@@ -1210,7 +1211,7 @@ get_func_trftypes(HeapTuple procTup,
nelems < 0 ||
ARR_HASNULL(arr) ||
ARR_ELEMTYPE(arr) != OIDOID)
- elog(ERROR, "protrftypes is not a 1-D Oid array");
+ elog(ERROR, "protrftypes is not a 1-D Oid array or it contains nulls");
Assert(nelems >= ((Form_pg_proc) GETSTRUCT(procTup))->pronargs);
*p_trftypes = (Oid *) palloc(nelems * sizeof(Oid));
memcpy(*p_trftypes, ARR_DATA_PTR(arr),
@@ -1261,7 +1262,7 @@ get_func_input_arg_names(char prokind,
if (ARR_NDIM(arr) != 1 ||
ARR_HASNULL(arr) ||
ARR_ELEMTYPE(arr) != TEXTOID)
- elog(ERROR, "proargnames is not a 1-D text array");
+ elog(ERROR, "proargnames is not a 1-D text array or it contains nulls");
deconstruct_array(arr, TEXTOID, -1, false, TYPALIGN_INT,
&argnames, NULL, &numargs);
if (proargmodes != PointerGetDatum(NULL))
@@ -1271,7 +1272,8 @@ get_func_input_arg_names(char prokind,
ARR_DIMS(arr)[0] != numargs ||
ARR_HASNULL(arr) ||
ARR_ELEMTYPE(arr) != CHAROID)
- elog(ERROR, "proargmodes is not a 1-D char array");
+ elog(ERROR, "proargmodes is not a 1-D char array of length %d or it contains nulls",
+ numargs);
argmodes = (char *) ARR_DATA_PTR(arr);
}
else
@@ -1368,14 +1370,15 @@ get_func_result_name(Oid functionId)
numargs < 0 ||
ARR_HASNULL(arr) ||
ARR_ELEMTYPE(arr) != CHAROID)
- elog(ERROR, "proargmodes is not a 1-D char array");
+ elog(ERROR, "proargmodes is not a 1-D char array or it contains nulls");
argmodes = (char *) ARR_DATA_PTR(arr);
arr = DatumGetArrayTypeP(proargnames); /* ensure not toasted */
if (ARR_NDIM(arr) != 1 ||
ARR_DIMS(arr)[0] != numargs ||
ARR_HASNULL(arr) ||
ARR_ELEMTYPE(arr) != TEXTOID)
- elog(ERROR, "proargnames is not a 1-D text array");
+ elog(ERROR, "proargnames is not a 1-D text array of length %d or it contains nulls",
+ numargs);
deconstruct_array(arr, TEXTOID, -1, false, TYPALIGN_INT,
&argnames, NULL, &nargnames);
Assert(nargnames == numargs);
@@ -1506,14 +1509,15 @@ build_function_result_tupdesc_d(char prokind,
numargs < 0 ||
ARR_HASNULL(arr) ||
ARR_ELEMTYPE(arr) != OIDOID)
- elog(ERROR, "proallargtypes is not a 1-D Oid array");
+ elog(ERROR, "proallargtypes is not a 1-D Oid array or it contains nulls");
argtypes = (Oid *) ARR_DATA_PTR(arr);
arr = DatumGetArrayTypeP(proargmodes); /* ensure not toasted */
if (ARR_NDIM(arr) != 1 ||
ARR_DIMS(arr)[0] != numargs ||
ARR_HASNULL(arr) ||
ARR_ELEMTYPE(arr) != CHAROID)
- elog(ERROR, "proargmodes is not a 1-D char array");
+ elog(ERROR, "proargmodes is not a 1-D char array of length %d or it contains nulls",
+ numargs);
argmodes = (char *) ARR_DATA_PTR(arr);
if (proargnames != PointerGetDatum(NULL))
{
@@ -1522,7 +1526,8 @@ build_function_result_tupdesc_d(char prokind,
ARR_DIMS(arr)[0] != numargs ||
ARR_HASNULL(arr) ||
ARR_ELEMTYPE(arr) != TEXTOID)
- elog(ERROR, "proargnames is not a 1-D text array");
+ elog(ERROR, "proargnames is not a 1-D text array of length %d or it contains nulls",
+ numargs);
deconstruct_array(arr, TEXTOID, -1, false, TYPALIGN_INT,
&argnames, NULL, &nargnames);
Assert(nargnames == numargs);
Alvaro Herrera <alvherre@alvh.no-ip.org> writes:
So let's go with this one.
WFM.
regards, tom lane