0002_assign_ndims_to_record_function_result_types_v03.patch
text/x-patch
Filename: 0002_assign_ndims_to_record_function_result_types_v03.patch
Type: text/x-patch
Part: 1
Patch
Format: unified
Series: patch v3
| File | + | − |
|---|---|---|
| src/backend/access/common/tupdesc.c | 11 | 3 |
| src/backend/executor/nodeFunctionscan.c | 2 | 1 |
| src/backend/nodes/copyfuncs.c | 1 | 0 |
| src/backend/nodes/equalfuncs.c | 1 | 0 |
| src/backend/nodes/outfuncs.c | 1 | 0 |
| src/backend/nodes/readfuncs.c | 1 | 0 |
| src/backend/parser/parse_relation.c | 6 | 1 |
| src/include/access/tupdesc.h | 2 | 1 |
| src/include/nodes/parsenodes.h | 3 | 1 |
| src/test/regress/expected/jsonb.out | 2 | 10 |
| src/test/regress/expected/json.out | 2 | 10 |
diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c
index b56d0e3..60510c3 100644
--- a/src/backend/access/common/tupdesc.c
+++ b/src/backend/access/common/tupdesc.c
@@ -673,7 +673,7 @@ BuildDescForRelation(List *schema)
* BuildDescFromLists
*
* Build a TupleDesc given lists of column names (as String nodes),
- * column type OIDs, typmods, and collation OIDs.
+ * column type OIDs, typmods, collation OIDs and ndims.
*
* No constraints are generated.
*
@@ -681,7 +681,8 @@ BuildDescForRelation(List *schema)
* with functions returning RECORD.
*/
TupleDesc
-BuildDescFromLists(List *names, List *types, List *typmods, List *collations)
+BuildDescFromLists(List *names, List *types, List *typmods, List *collations,
+ List *ndims)
{
int natts;
AttrNumber attnum;
@@ -689,12 +690,14 @@ BuildDescFromLists(List *names, List *types, List *typmods, List *collations)
ListCell *l2;
ListCell *l3;
ListCell *l4;
+ ListCell *l5;
TupleDesc desc;
natts = list_length(names);
Assert(natts == list_length(types));
Assert(natts == list_length(typmods));
Assert(natts == list_length(collations));
+ Assert(natts == list_length(ndims));
/*
* allocate a new tuple descriptor
@@ -706,12 +709,15 @@ BuildDescFromLists(List *names, List *types, List *typmods, List *collations)
l2 = list_head(types);
l3 = list_head(typmods);
l4 = list_head(collations);
+ l5 = list_head(ndims);
+
foreach(l1, names)
{
char *attname = strVal(lfirst(l1));
Oid atttypid;
int32 atttypmod;
Oid attcollation;
+ int32 attndims;
atttypid = lfirst_oid(l2);
l2 = lnext(l2);
@@ -719,10 +725,12 @@ BuildDescFromLists(List *names, List *types, List *typmods, List *collations)
l3 = lnext(l3);
attcollation = lfirst_oid(l4);
l4 = lnext(l4);
+ attndims = lfirst_oid(l5);
+ l5 = lnext(l5);
attnum++;
- TupleDescInitEntry(desc, attnum, attname, atttypid, atttypmod, 0);
+ TupleDescInitEntry(desc, attnum, attname, atttypid, atttypmod, attndims);
TupleDescInitEntryCollation(desc, attnum, attcollation);
}
diff --git a/src/backend/executor/nodeFunctionscan.c b/src/backend/executor/nodeFunctionscan.c
index 5a0f324..6d93cb3 100644
--- a/src/backend/executor/nodeFunctionscan.c
+++ b/src/backend/executor/nodeFunctionscan.c
@@ -410,7 +410,8 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags)
tupdesc = BuildDescFromLists(rtfunc->funccolnames,
rtfunc->funccoltypes,
rtfunc->funccoltypmods,
- rtfunc->funccolcollations);
+ rtfunc->funccolcollations,
+ rtfunc->funccolndims);
/*
* For RECORD results, make sure a typmod has been assigned. (The
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 6955298..6ca0c91 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -2181,6 +2181,7 @@ _copyRangeTblFunction(const RangeTblFunction *from)
COPY_NODE_FIELD(funccoltypes);
COPY_NODE_FIELD(funccoltypmods);
COPY_NODE_FIELD(funccolcollations);
+ COPY_NODE_FIELD(funccolndims);
COPY_BITMAPSET_FIELD(funcparams);
return newnode;
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 548a2aa..b0e0851 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -2490,6 +2490,7 @@ _equalRangeTblFunction(const RangeTblFunction *a, const RangeTblFunction *b)
COMPARE_NODE_FIELD(funccoltypes);
COMPARE_NODE_FIELD(funccoltypmods);
COMPARE_NODE_FIELD(funccolcollations);
+ COMPARE_NODE_FIELD(funccolndims);
COMPARE_BITMAPSET_FIELD(funcparams);
return true;
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 9fe9873..3b9439c 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -2880,6 +2880,7 @@ _outRangeTblFunction(StringInfo str, const RangeTblFunction *node)
WRITE_NODE_FIELD(funccoltypes);
WRITE_NODE_FIELD(funccoltypmods);
WRITE_NODE_FIELD(funccolcollations);
+ WRITE_NODE_FIELD(funccolndims);
WRITE_BITMAPSET_FIELD(funcparams);
}
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index 63f6336..4525298 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -1359,6 +1359,7 @@ _readRangeTblFunction(void)
READ_NODE_FIELD(funccoltypes);
READ_NODE_FIELD(funccoltypmods);
READ_NODE_FIELD(funccolcollations);
+ READ_NODE_FIELD(funccolndims);
READ_BITMAPSET_FIELD(funcparams);
READ_DONE();
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
index 58f7050..19f5fe2 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -1444,6 +1444,7 @@ addRangeTableEntryForFunction(ParseState *pstate,
rtfunc->funccoltypes = NIL;
rtfunc->funccoltypmods = NIL;
rtfunc->funccolcollations = NIL;
+ rtfunc->funccolndims = NIL;
rtfunc->funcparams = NULL; /* not set until planning */
/*
@@ -1509,6 +1510,7 @@ addRangeTableEntryForFunction(ParseState *pstate,
Oid attrtype;
int32 attrtypmod;
Oid attrcollation;
+ int32 attrndims;
attrname = n->colname;
if (n->typeName->setof)
@@ -1520,12 +1522,13 @@ addRangeTableEntryForFunction(ParseState *pstate,
typenameTypeIdAndMod(pstate, n->typeName,
&attrtype, &attrtypmod);
attrcollation = GetColumnDefCollation(pstate, n, attrtype);
+ attrndims = list_length(n->typeName->arrayBounds);
TupleDescInitEntry(tupdesc,
(AttrNumber) i,
attrname,
attrtype,
attrtypmod,
- 0);
+ attrndims);
TupleDescInitEntryCollation(tupdesc,
(AttrNumber) i,
attrcollation);
@@ -1537,6 +1540,8 @@ addRangeTableEntryForFunction(ParseState *pstate,
attrtypmod);
rtfunc->funccolcollations = lappend_oid(rtfunc->funccolcollations,
attrcollation);
+ rtfunc->funccolndims = lappend_int(rtfunc->funccolndims,
+ attrndims);
i++;
}
diff --git a/src/include/access/tupdesc.h b/src/include/access/tupdesc.h
index de18f74..9ed44fd 100644
--- a/src/include/access/tupdesc.h
+++ b/src/include/access/tupdesc.h
@@ -125,6 +125,7 @@ extern void TupleDescInitEntryCollation(TupleDesc desc,
extern TupleDesc BuildDescForRelation(List *schema);
-extern TupleDesc BuildDescFromLists(List *names, List *types, List *typmods, List *collations);
+extern TupleDesc BuildDescFromLists(List *names, List *types, List *typmods,
+ List *collations, List *ndims);
#endif /* TUPDESC_H */
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index fc532fb..d27db6e 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -969,7 +969,8 @@ typedef struct RangeTblEntry
* If the function had a column definition list (required for an
* otherwise-unspecified RECORD result), funccolnames lists the names given
* in the definition list, funccoltypes lists their declared column types,
- * funccoltypmods lists their typmods, funccolcollations their collations.
+ * funccoltypmods lists their typmods, funccolcollations their collations,
+ * funccolndims lists their numbers of array dimensions.
* Otherwise, those fields are NIL.
*
* Notice we don't attempt to store info about the results of functions
@@ -989,6 +990,7 @@ typedef struct RangeTblFunction
List *funccoltypes; /* OID list of column type OIDs */
List *funccoltypmods; /* integer list of column typmods */
List *funccolcollations; /* OID list of column collation OIDs */
+ List *funccolndims; /* integer list of column array ndims */
/* This is set during planning for use by the executor: */
Bitmapset *funcparams; /* PARAM_EXEC Param IDs affecting this func */
} RangeTblFunction;
diff --git a/src/test/regress/expected/json.out b/src/test/regress/expected/json.out
index a7de8ef..696aa9c 100644
--- a/src/test/regress/expected/json.out
+++ b/src/test/regress/expected/json.out
@@ -2009,11 +2009,7 @@ select * from json_to_record('{"ia": [[1], [2, 3]]}') as x(ia _int4);
ERROR: malformed json array: "[[1], [2, 3]]"
DETAIL: Multidimensional arrays must have sub-arrays with matching dimensions.
select * from json_to_record('{"ia2": [1, 2, 3]}') as x(ia2 int[][]);
- ia2
----------
- {1,2,3}
-(1 row)
-
+ERROR: expected json array in array element [0] of key "ia2"
select * from json_to_record('{"ia2": [[1, 2], [3, 4]]}') as x(ia2 int4[][]);
ia2
---------------
@@ -2021,11 +2017,7 @@ select * from json_to_record('{"ia2": [[1, 2], [3, 4]]}') as x(ia2 int4[][]);
(1 row)
select * from json_to_record('{"ia2": [[[1], [2], [3]]]}') as x(ia2 int4[][]);
- ia2
------------------
- {{{1},{2},{3}}}
-(1 row)
-
+ERROR: invalid input syntax for integer: "[1]"
-- json_strip_nulls
select json_strip_nulls(null);
json_strip_nulls
diff --git a/src/test/regress/expected/jsonb.out b/src/test/regress/expected/jsonb.out
index 758adb2..28c994f 100644
--- a/src/test/regress/expected/jsonb.out
+++ b/src/test/regress/expected/jsonb.out
@@ -2389,11 +2389,7 @@ select * from jsonb_to_record('{"ia": [[1], [2, 3]]}') as x(ia _int4);
ERROR: malformed json array: "[[1], [2, 3]]"
DETAIL: Multidimensional arrays must have sub-arrays with matching dimensions.
select * from jsonb_to_record('{"ia2": [1, 2, 3]}') as x(ia2 int[][]);
- ia2
----------
- {1,2,3}
-(1 row)
-
+ERROR: expected json array in array element [0] of key "ia2"
select * from jsonb_to_record('{"ia2": [[1, 2], [3, 4]]}') as x(ia2 int4[][]);
ia2
---------------
@@ -2401,11 +2397,7 @@ select * from jsonb_to_record('{"ia2": [[1, 2], [3, 4]]}') as x(ia2 int4[][]);
(1 row)
select * from jsonb_to_record('{"ia2": [[[1], [2], [3]]]}') as x(ia2 int4[][]);
- ia2
------------------
- {{{1},{2},{3}}}
-(1 row)
-
+ERROR: invalid input syntax for integer: "[1]"
-- test type info caching in jsonb_populate_record()
CREATE TEMP TABLE jsbpoptest (js jsonb);
INSERT INTO jsbpoptest