Skip to content

Commit 9a839db

Browse files
committed
Merge branch 'REL9_6_STABLE' into PGPRO9_6
2 parents 56ff954 + 37b4e0f commit 9a839db

File tree

32 files changed

+1038
-404
lines changed

32 files changed

+1038
-404
lines changed

src/backend/catalog/dependency.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1710,6 +1710,27 @@ find_expr_references_walker(Node *node,
17101710
/* Extra work needed here if we ever need this case */
17111711
elog(ERROR, "already-planned subqueries not supported");
17121712
}
1713+
else if (IsA(node, FieldSelect))
1714+
{
1715+
FieldSelect *fselect = (FieldSelect *) node;
1716+
1717+
/* result type might not appear anywhere else in expression */
1718+
add_object_address(OCLASS_TYPE, fselect->resulttype, 0,
1719+
context->addrs);
1720+
/* the collation might not be referenced anywhere else, either */
1721+
if (OidIsValid(fselect->resultcollid) &&
1722+
fselect->resultcollid != DEFAULT_COLLATION_OID)
1723+
add_object_address(OCLASS_COLLATION, fselect->resultcollid, 0,
1724+
context->addrs);
1725+
}
1726+
else if (IsA(node, FieldStore))
1727+
{
1728+
FieldStore *fstore = (FieldStore *) node;
1729+
1730+
/* result type might not appear anywhere else in expression */
1731+
add_object_address(OCLASS_TYPE, fstore->resulttype, 0,
1732+
context->addrs);
1733+
}
17131734
else if (IsA(node, RelabelType))
17141735
{
17151736
RelabelType *relab = (RelabelType *) node;
@@ -1730,6 +1751,11 @@ find_expr_references_walker(Node *node,
17301751
/* since there is no exposed function, need to depend on type */
17311752
add_object_address(OCLASS_TYPE, iocoerce->resulttype, 0,
17321753
context->addrs);
1754+
/* the collation might not be referenced anywhere else, either */
1755+
if (OidIsValid(iocoerce->resultcollid) &&
1756+
iocoerce->resultcollid != DEFAULT_COLLATION_OID)
1757+
add_object_address(OCLASS_COLLATION, iocoerce->resultcollid, 0,
1758+
context->addrs);
17331759
}
17341760
else if (IsA(node, ArrayCoerceExpr))
17351761
{

src/backend/optimizer/plan/setrefs.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1687,8 +1687,8 @@ set_upper_references(PlannerInfo *root, Plan *plan, int rtoffset)
16871687
TargetEntry *tle = (TargetEntry *) lfirst(l);
16881688
Node *newexpr;
16891689

1690-
/* If it's a non-Var sort/group item, first try to match by sortref */
1691-
if (tle->ressortgroupref != 0 && !IsA(tle->expr, Var))
1690+
/* If it's a sort/group item, first try to match by sortref */
1691+
if (tle->ressortgroupref != 0)
16921692
{
16931693
newexpr = (Node *)
16941694
search_indexed_tlist_for_sortgroupref((Node *) tle->expr,
@@ -2049,7 +2049,6 @@ search_indexed_tlist_for_non_var(Node *node,
20492049

20502050
/*
20512051
* search_indexed_tlist_for_sortgroupref --- find a sort/group expression
2052-
* (which is assumed not to be just a Var)
20532052
*
20542053
* If a match is found, return a Var constructed to reference the tlist item.
20552054
* If no match, return NULL.

src/backend/utils/adt/json.c

Lines changed: 24 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "access/transam.h"
1818
#include "catalog/pg_type.h"
1919
#include "executor/spi.h"
20+
#include "funcapi.h"
2021
#include "lib/stringinfo.h"
2122
#include "libpq/pqformat.h"
2223
#include "mb/pg_wchar.h"
@@ -2106,10 +2107,17 @@ json_build_object(PG_FUNCTION_ARGS)
21062107
{
21072108
int nargs = PG_NARGS();
21082109
int i;
2109-
Datum arg;
21102110
const char *sep = "";
21112111
StringInfo result;
2112-
Oid val_type;
2112+
Datum *args;
2113+
bool *nulls;
2114+
Oid *types;
2115+
2116+
/* fetch argument values to build the object */
2117+
nargs = extract_variadic_args(fcinfo, 0, false, &args, &types, &nulls);
2118+
2119+
if (nargs < 0)
2120+
PG_RETURN_NULL();
21132121

21142122
if (nargs % 2 != 0)
21152123
ereport(ERROR,
@@ -2123,52 +2131,22 @@ json_build_object(PG_FUNCTION_ARGS)
21232131

21242132
for (i = 0; i < nargs; i += 2)
21252133
{
2126-
/*
2127-
* Note: since json_build_object() is declared as taking type "any",
2128-
* the parser will not do any type conversion on unknown-type literals
2129-
* (that is, undecorated strings or NULLs). Such values will arrive
2130-
* here as type UNKNOWN, which fortunately does not matter to us,
2131-
* since unknownout() works fine.
2132-
*/
21332134
appendStringInfoString(result, sep);
21342135
sep = ", ";
21352136

21362137
/* process key */
2137-
val_type = get_fn_expr_argtype(fcinfo->flinfo, i);
2138-
2139-
if (val_type == InvalidOid)
2140-
ereport(ERROR,
2141-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2142-
errmsg("could not determine data type for argument %d",
2143-
i + 1)));
2144-
2145-
if (PG_ARGISNULL(i))
2138+
if (nulls[i])
21462139
ereport(ERROR,
21472140
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
21482141
errmsg("argument %d cannot be null", i + 1),
21492142
errhint("Object keys should be text.")));
21502143

2151-
arg = PG_GETARG_DATUM(i);
2152-
2153-
add_json(arg, false, result, val_type, true);
2144+
add_json(args[i], false, result, types[i], true);
21542145

21552146
appendStringInfoString(result, " : ");
21562147

21572148
/* process value */
2158-
val_type = get_fn_expr_argtype(fcinfo->flinfo, i + 1);
2159-
2160-
if (val_type == InvalidOid)
2161-
ereport(ERROR,
2162-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2163-
errmsg("could not determine data type for argument %d",
2164-
i + 2)));
2165-
2166-
if (PG_ARGISNULL(i + 1))
2167-
arg = (Datum) 0;
2168-
else
2169-
arg = PG_GETARG_DATUM(i + 1);
2170-
2171-
add_json(arg, PG_ARGISNULL(i + 1), result, val_type, false);
2149+
add_json(args[i + 1], nulls[i + 1], result, types[i + 1], false);
21722150
}
21732151

21742152
appendStringInfoChar(result, '}');
@@ -2191,43 +2169,29 @@ json_build_object_noargs(PG_FUNCTION_ARGS)
21912169
Datum
21922170
json_build_array(PG_FUNCTION_ARGS)
21932171
{
2194-
int nargs = PG_NARGS();
2172+
int nargs;
21952173
int i;
2196-
Datum arg;
21972174
const char *sep = "";
21982175
StringInfo result;
2199-
Oid val_type;
2176+
Datum *args;
2177+
bool *nulls;
2178+
Oid *types;
2179+
2180+
/* fetch argument values to build the array */
2181+
nargs = extract_variadic_args(fcinfo, 0, false, &args, &types, &nulls);
2182+
2183+
if (nargs < 0)
2184+
PG_RETURN_NULL();
22002185

22012186
result = makeStringInfo();
22022187

22032188
appendStringInfoChar(result, '[');
22042189

22052190
for (i = 0; i < nargs; i++)
22062191
{
2207-
/*
2208-
* Note: since json_build_array() is declared as taking type "any",
2209-
* the parser will not do any type conversion on unknown-type literals
2210-
* (that is, undecorated strings or NULLs). Such values will arrive
2211-
* here as type UNKNOWN, which fortunately does not matter to us,
2212-
* since unknownout() works fine.
2213-
*/
22142192
appendStringInfoString(result, sep);
22152193
sep = ", ";
2216-
2217-
val_type = get_fn_expr_argtype(fcinfo->flinfo, i);
2218-
2219-
if (val_type == InvalidOid)
2220-
ereport(ERROR,
2221-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2222-
errmsg("could not determine data type for argument %d",
2223-
i + 1)));
2224-
2225-
if (PG_ARGISNULL(i))
2226-
arg = (Datum) 0;
2227-
else
2228-
arg = PG_GETARG_DATUM(i);
2229-
2230-
add_json(arg, PG_ARGISNULL(i), result, val_type, false);
2194+
add_json(args[i], nulls[i], result, types[i], false);
22312195
}
22322196

22332197
appendStringInfoChar(result, ']');

src/backend/utils/adt/jsonb.c

Lines changed: 27 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "access/htup_details.h"
1717
#include "access/transam.h"
1818
#include "catalog/pg_type.h"
19+
#include "funcapi.h"
1920
#include "libpq/pqformat.h"
2021
#include "parser/parse_coerce.h"
2122
#include "utils/builtins.h"
@@ -1170,16 +1171,24 @@ to_jsonb(PG_FUNCTION_ARGS)
11701171
Datum
11711172
jsonb_build_object(PG_FUNCTION_ARGS)
11721173
{
1173-
int nargs = PG_NARGS();
1174+
int nargs;
11741175
int i;
1175-
Datum arg;
1176-
Oid val_type;
11771176
JsonbInState result;
1177+
Datum *args;
1178+
bool *nulls;
1179+
Oid *types;
1180+
1181+
/* build argument values to build the object */
1182+
nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);
1183+
1184+
if (nargs < 0)
1185+
PG_RETURN_NULL();
11781186

11791187
if (nargs % 2 != 0)
11801188
ereport(ERROR,
11811189
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1182-
errmsg("invalid number of arguments: object must be matched key value pairs")));
1190+
errmsg("argument list must have even number of elements"),
1191+
errhint("The arguments of jsonb_build_object() must consist of alternating keys and values.")));
11831192

11841193
memset(&result, 0, sizeof(JsonbInState));
11851194

@@ -1188,54 +1197,15 @@ jsonb_build_object(PG_FUNCTION_ARGS)
11881197
for (i = 0; i < nargs; i += 2)
11891198
{
11901199
/* process key */
1191-
1192-
if (PG_ARGISNULL(i))
1200+
if (nulls[i])
11931201
ereport(ERROR,
11941202
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
11951203
errmsg("argument %d: key must not be null", i + 1)));
1196-
val_type = get_fn_expr_argtype(fcinfo->flinfo, i);
1197-
1198-
/*
1199-
* turn a constant (more or less literal) value that's of unknown type
1200-
* into text. Unknowns come in as a cstring pointer.
1201-
*/
1202-
if (val_type == UNKNOWNOID && get_fn_expr_arg_stable(fcinfo->flinfo, i))
1203-
{
1204-
val_type = TEXTOID;
1205-
arg = CStringGetTextDatum(PG_GETARG_POINTER(i));
1206-
}
1207-
else
1208-
{
1209-
arg = PG_GETARG_DATUM(i);
1210-
}
1211-
if (val_type == InvalidOid || val_type == UNKNOWNOID)
1212-
ereport(ERROR,
1213-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1214-
errmsg("could not determine data type for argument %d", i + 1)));
12151204

1216-
add_jsonb(arg, false, &result, val_type, true);
1205+
add_jsonb(args[i], false, &result, types[i], true);
12171206

12181207
/* process value */
1219-
1220-
val_type = get_fn_expr_argtype(fcinfo->flinfo, i + 1);
1221-
/* see comments above */
1222-
if (val_type == UNKNOWNOID && get_fn_expr_arg_stable(fcinfo->flinfo, i + 1))
1223-
{
1224-
val_type = TEXTOID;
1225-
if (PG_ARGISNULL(i + 1))
1226-
arg = (Datum) 0;
1227-
else
1228-
arg = CStringGetTextDatum(PG_GETARG_POINTER(i + 1));
1229-
}
1230-
else
1231-
{
1232-
arg = PG_GETARG_DATUM(i + 1);
1233-
}
1234-
if (val_type == InvalidOid || val_type == UNKNOWNOID)
1235-
ereport(ERROR,
1236-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1237-
errmsg("could not determine data type for argument %d", i + 2)));
1238-
add_jsonb(arg, PG_ARGISNULL(i + 1), &result, val_type, false);
1208+
add_jsonb(args[i + 1], nulls[i + 1], &result, types[i + 1], false);
12391209
}
12401210

12411211
result.res = pushJsonbValue(&result.parseState, WJB_END_OBJECT, NULL);
@@ -1265,38 +1235,25 @@ jsonb_build_object_noargs(PG_FUNCTION_ARGS)
12651235
Datum
12661236
jsonb_build_array(PG_FUNCTION_ARGS)
12671237
{
1268-
int nargs = PG_NARGS();
1238+
int nargs;
12691239
int i;
1270-
Datum arg;
1271-
Oid val_type;
12721240
JsonbInState result;
1241+
Datum *args;
1242+
bool *nulls;
1243+
Oid *types;
1244+
1245+
/* build argument values to build the array */
1246+
nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);
1247+
1248+
if (nargs < 0)
1249+
PG_RETURN_NULL();
12731250

12741251
memset(&result, 0, sizeof(JsonbInState));
12751252

12761253
result.res = pushJsonbValue(&result.parseState, WJB_BEGIN_ARRAY, NULL);
12771254

12781255
for (i = 0; i < nargs; i++)
1279-
{
1280-
val_type = get_fn_expr_argtype(fcinfo->flinfo, i);
1281-
/* see comments in jsonb_build_object above */
1282-
if (val_type == UNKNOWNOID && get_fn_expr_arg_stable(fcinfo->flinfo, i))
1283-
{
1284-
val_type = TEXTOID;
1285-
if (PG_ARGISNULL(i))
1286-
arg = (Datum) 0;
1287-
else
1288-
arg = CStringGetTextDatum(PG_GETARG_POINTER(i));
1289-
}
1290-
else
1291-
{
1292-
arg = PG_GETARG_DATUM(i);
1293-
}
1294-
if (val_type == InvalidOid || val_type == UNKNOWNOID)
1295-
ereport(ERROR,
1296-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1297-
errmsg("could not determine data type for argument %d", i + 1)));
1298-
add_jsonb(arg, PG_ARGISNULL(i), &result, val_type, false);
1299-
}
1256+
add_jsonb(args[i], nulls[i], &result, types[i], false);
13001257

13011258
result.res = pushJsonbValue(&result.parseState, WJB_END_ARRAY, NULL);
13021259

0 commit comments

Comments
 (0)