aboutsummaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorAmit Langote <amitlan@postgresql.org>2024-03-21 17:06:27 +0900
committerAmit Langote <amitlan@postgresql.org>2024-03-21 17:07:03 +0900
commit6185c9737cf48c9540782d88f12bd2912d6ca1cc (patch)
tree60b88a5d63fc61a1dbb11c5459ad83273f93db77 /src/include
parenta145f424d5248a09d766e8cb503b999290cb3b31 (diff)
downloadpostgresql-6185c9737cf48c9540782d88f12bd2912d6ca1cc.tar.gz
postgresql-6185c9737cf48c9540782d88f12bd2912d6ca1cc.zip
Add SQL/JSON query functions
This introduces the following SQL/JSON functions for querying JSON data using jsonpath expressions: JSON_EXISTS(), which can be used to apply a jsonpath expression to a JSON value to check if it yields any values. JSON_QUERY(), which can be used to to apply a jsonpath expression to a JSON value to get a JSON object, an array, or a string. There are various options to control whether multi-value result uses array wrappers and whether the singleton scalar strings are quoted or not. JSON_VALUE(), which can be used to apply a jsonpath expression to a JSON value to return a single scalar value, producing an error if it multiple values are matched. Both JSON_VALUE() and JSON_QUERY() functions have options for handling EMPTY and ERROR conditions, which can be used to specify the behavior when no values are matched and when an error occurs during jsonpath evaluation, respectively. Author: Nikita Glukhov <n.gluhov@postgrespro.ru> Author: Teodor Sigaev <teodor@sigaev.ru> Author: Oleg Bartunov <obartunov@gmail.com> Author: Alexander Korotkov <aekorotkov@gmail.com> Author: Andrew Dunstan <andrew@dunslane.net> Author: Amit Langote <amitlangote09@gmail.com> Author: Peter Eisentraut <peter@eisentraut.org> Author: Jian He <jian.universality@gmail.com> Reviewers have included (in no particular order): Andres Freund, Alexander Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu, Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby, Álvaro Herrera, Jian He, Anton A. Melnikov, Nikita Malakhov, Peter Eisentraut, Tomas Vondra Discussion: https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru Discussion: https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.de Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org Discussion: https://postgr.es/m/CA+HiwqHROpf9e644D8BRqYvaAPmgBZVup-xKMDPk-nd4EpgzHw@mail.gmail.com Discussion: https://postgr.es/m/CA+HiwqE4XTdfb1nW=Ojoy_tQSRhYt-q_kb6i5d4xcKyrLC1Nbg@mail.gmail.com
Diffstat (limited to 'src/include')
-rw-r--r--src/include/executor/execExpr.h22
-rw-r--r--src/include/nodes/execnodes.h73
-rw-r--r--src/include/nodes/makefuncs.h2
-rw-r--r--src/include/nodes/parsenodes.h42
-rw-r--r--src/include/nodes/primnodes.h122
-rw-r--r--src/include/parser/kwlist.h11
-rw-r--r--src/include/utils/formatting.h1
-rw-r--r--src/include/utils/jsonb.h1
-rw-r--r--src/include/utils/jsonfuncs.h7
-rw-r--r--src/include/utils/jsonpath.h24
10 files changed, 305 insertions, 0 deletions
diff --git a/src/include/executor/execExpr.h b/src/include/executor/execExpr.h
index 8953d767387..64698202a56 100644
--- a/src/include/executor/execExpr.h
+++ b/src/include/executor/execExpr.h
@@ -240,6 +240,9 @@ typedef enum ExprEvalOp
EEOP_XMLEXPR,
EEOP_JSON_CONSTRUCTOR,
EEOP_IS_JSON,
+ EEOP_JSONEXPR_PATH,
+ EEOP_JSONEXPR_COERCION,
+ EEOP_JSONEXPR_COERCION_FINISH,
EEOP_AGGREF,
EEOP_GROUPING_FUNC,
EEOP_WINDOW_FUNC,
@@ -693,6 +696,20 @@ typedef struct ExprEvalStep
JsonIsPredicate *pred; /* original expression node */
} is_json;
+ /* for EEOP_JSONEXPR_PATH */
+ struct
+ {
+ struct JsonExprState *jsestate;
+ } jsonexpr;
+
+ /* for EEOP_JSONEXPR_COERCION */
+ struct
+ {
+ Oid targettype;
+ int32 targettypmod;
+ void *json_populate_type_cache;
+ ErrorSaveContext *escontext;
+ } jsonexpr_coercion;
} d;
} ExprEvalStep;
@@ -810,6 +827,11 @@ extern void ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op);
extern void ExecEvalJsonConstructor(ExprState *state, ExprEvalStep *op,
ExprContext *econtext);
extern void ExecEvalJsonIsPredicate(ExprState *state, ExprEvalStep *op);
+extern int ExecEvalJsonExprPath(ExprState *state, ExprEvalStep *op,
+ ExprContext *econtext);
+extern void ExecEvalJsonCoercion(ExprState *state, ExprEvalStep *op,
+ ExprContext *econtext);
+extern void ExecEvalJsonCoercionFinish(ExprState *state, ExprEvalStep *op);
extern void ExecEvalGroupingFunc(ExprState *state, ExprEvalStep *op);
extern void ExecEvalMergeSupportFunc(ExprState *state, ExprEvalStep *op,
ExprContext *econtext);
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 92593526725..1774c56ae31 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -1008,6 +1008,79 @@ typedef struct DomainConstraintState
ExprState *check_exprstate; /* check_expr's eval state, or NULL */
} DomainConstraintState;
+/*
+ * State for JsonExpr evaluation, too big to inline.
+ *
+ * This contains the information going into and coming out of the
+ * EEOP_JSONEXPR_PATH eval step.
+ */
+typedef struct JsonExprState
+{
+ /* original expression node */
+ JsonExpr *jsexpr;
+
+ /* value/isnull for formatted_expr */
+ NullableDatum formatted_expr;
+
+ /* value/isnull for pathspec */
+ NullableDatum pathspec;
+
+ /* JsonPathVariable entries for passing_values */
+ List *args;
+
+ /*
+ * Output variables that drive the EEOP_JUMP_IF_NOT_TRUE steps that are
+ * added for ON ERROR and ON EMPTY expressions, if any.
+ *
+ * Reset for each evaluation of EEOP_JSONEXPR_PATH.
+ */
+
+ /* Set to true if jsonpath evaluation cause an error. */
+ NullableDatum error;
+
+ /* Set to true if the jsonpath evaluation returned 0 items. */
+ NullableDatum empty;
+
+ /*
+ * Addresses of steps that implement the non-ERROR variant of ON EMPTY and
+ * ON ERROR behaviors, respectively.
+ */
+ int jump_empty;
+ int jump_error;
+
+ /*
+ * Address of the step to coerce the result value of jsonpath evaluation
+ * to the RETURNING type using JsonExpr.coercion_expr. -1 if no coercion
+ * is necessary or if either JsonExpr.use_io_coercion or
+ * JsonExpr.use_json_coercion is true.
+ */
+ int jump_eval_coercion;
+
+ /*
+ * Address to jump to when skipping all the steps after performing
+ * ExecEvalJsonExprPath() so as to return whatever the JsonPath* function
+ * returned as is, that is, in the cases where there's no error and no
+ * coercion is necessary.
+ */
+ int jump_end;
+
+ /*
+ * RETURNING type input function invocation info when
+ * JsonExpr.use_io_coercion is true.
+ */
+ FmgrInfo *input_finfo;
+ FunctionCallInfo input_fcinfo;
+
+ /*
+ * For error-safe evaluation of coercions. When the ON ERROR behavior is
+ * not ERROR, a pointer to this is passed to ExecInitExprRec() when
+ * initializing the coercion expressions or to ExecInitJsonCoercion().
+ *
+ * Reset for each evaluation of EEOP_JSONEXPR_PATH.
+ */
+ ErrorSaveContext escontext;
+} JsonExprState;
+
/* ----------------------------------------------------------------
* Executor State Trees
diff --git a/src/include/nodes/makefuncs.h b/src/include/nodes/makefuncs.h
index 2dc79648d2b..fdc78270e5b 100644
--- a/src/include/nodes/makefuncs.h
+++ b/src/include/nodes/makefuncs.h
@@ -116,5 +116,7 @@ extern Node *makeJsonKeyValue(Node *key, Node *value);
extern Node *makeJsonIsPredicate(Node *expr, JsonFormat *format,
JsonValueType item_type, bool unique_keys,
int location);
+extern JsonBehavior *makeJsonBehavior(JsonBehaviorType btype, Node *expr,
+ int location);
#endif /* MAKEFUNC_H */
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 1e2e898851f..9b709f03908 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -1716,6 +1716,48 @@ typedef struct JsonOutput
} JsonOutput;
/*
+ * JsonArgument -
+ * representation of argument from JSON PASSING clause
+ */
+typedef struct JsonArgument
+{
+ NodeTag type;
+ JsonValueExpr *val; /* argument value expression */
+ char *name; /* argument name */
+} JsonArgument;
+
+/*
+ * JsonQuotes -
+ * representation of [KEEP|OMIT] QUOTES clause for JSON_QUERY()
+ */
+typedef enum JsonQuotes
+{
+ JS_QUOTES_UNSPEC, /* unspecified */
+ JS_QUOTES_KEEP, /* KEEP QUOTES */
+ JS_QUOTES_OMIT, /* OMIT QUOTES */
+} JsonQuotes;
+
+/*
+ * JsonFuncExpr -
+ * untransformed representation of function expressions for
+ * SQL/JSON query functions
+ */
+typedef struct JsonFuncExpr
+{
+ NodeTag type;
+ JsonExprOp op; /* expression type */
+ JsonValueExpr *context_item; /* context item expression */
+ Node *pathspec; /* JSON path specification expression */
+ List *passing; /* list of PASSING clause arguments, if any */
+ JsonOutput *output; /* output clause, if specified */
+ JsonBehavior *on_empty; /* ON EMPTY behavior */
+ JsonBehavior *on_error; /* ON ERROR behavior */
+ JsonWrapper wrapper; /* array wrapper behavior (JSON_QUERY only) */
+ JsonQuotes quotes; /* omit or keep quotes? (JSON_QUERY only) */
+ int location; /* token location, or -1 if unknown */
+} JsonFuncExpr;
+
+/*
* JsonKeyValue -
* untransformed representation of JSON object key-value pair for
* JSON_OBJECT() and JSON_OBJECTAGG()
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index e57d69f72e2..376f67e6a5f 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -1691,6 +1691,128 @@ typedef struct JsonIsPredicate
ParseLoc location; /* token location, or -1 if unknown */
} JsonIsPredicate;
+/* Nodes used in SQL/JSON query functions */
+
+/*
+ * JsonWrapper -
+ * representation of WRAPPER clause for JSON_QUERY()
+ */
+typedef enum JsonWrapper
+{
+ JSW_UNSPEC,
+ JSW_NONE,
+ JSW_CONDITIONAL,
+ JSW_UNCONDITIONAL,
+} JsonWrapper;
+
+/*
+ * JsonBehaviorType -
+ * enumeration of behavior types used in SQL/JSON ON ERROR/EMPTY clauses
+ *
+ * If enum members are reordered, get_json_behavior() from ruleutils.c
+ * must be updated accordingly.
+ */
+typedef enum JsonBehaviorType
+{
+ JSON_BEHAVIOR_NULL = 0,
+ JSON_BEHAVIOR_ERROR,
+ JSON_BEHAVIOR_EMPTY,
+ JSON_BEHAVIOR_TRUE,
+ JSON_BEHAVIOR_FALSE,
+ JSON_BEHAVIOR_UNKNOWN,
+ JSON_BEHAVIOR_EMPTY_ARRAY,
+ JSON_BEHAVIOR_EMPTY_OBJECT,
+ JSON_BEHAVIOR_DEFAULT,
+} JsonBehaviorType;
+
+/*
+ * JsonBehavior
+ * Specifications for ON ERROR / ON EMPTY behaviors of SQL/JSON
+ * query functions specified by a JsonExpr
+ *
+ * 'expr' is the expression to emit when a given behavior (EMPTY or ERROR)
+ * occurs on evaluating the SQL/JSON query function. 'coerce' is set to true
+ * if 'expr' isn't already of the expected target type given by
+ * JsonExpr.returning.
+ */
+typedef struct JsonBehavior
+{
+ NodeTag type;
+
+ JsonBehaviorType btype;
+ Node *expr;
+ bool coerce;
+ int location; /* token location, or -1 if unknown */
+} JsonBehavior;
+
+/*
+ * JsonExprOp -
+ * enumeration of SQL/JSON query function types
+ */
+typedef enum JsonExprOp
+{
+ JSON_EXISTS_OP, /* JSON_EXISTS() */
+ JSON_QUERY_OP, /* JSON_QUERY() */
+ JSON_VALUE_OP, /* JSON_VALUE() */
+} JsonExprOp;
+
+/*
+ * JsonExpr -
+ * Transformed representation of JSON_VALUE(), JSON_QUERY(), and
+ * JSON_EXISTS()
+ */
+typedef struct JsonExpr
+{
+ Expr xpr;
+
+ JsonExprOp op;
+
+ /* jsonb-valued expression to query */
+ Node *formatted_expr;
+
+ /* Format of the above expression needed by ruleutils.c */
+ JsonFormat *format;
+
+ /* jsopath-valued expression containing the query pattern */
+ Node *path_spec;
+
+ /* Expected type/format of the output. */
+ JsonReturning *returning;
+
+ /* Information about the PASSING argument expressions */
+ List *passing_names;
+ List *passing_values;
+
+ /* User-specified or default ON EMPTY and ON ERROR behaviors */
+ JsonBehavior *on_empty;
+ JsonBehavior *on_error;
+
+ /*
+ * Information about converting the result of jsonpath functions
+ * JsonPathQuery() and JsonPathValue() to the RETURNING type.
+ *
+ * coercion_expr is a cast expression if the parser can find it for the
+ * source and the target type. If not, either use_io_coercion or
+ * use_json_coercion is set to determine the coercion method to use at
+ * runtime; see coerceJsonExprOutput() and ExecInitJsonExpr().
+ */
+ Node *coercion_expr;
+ bool use_io_coercion;
+ bool use_json_coercion;
+
+ /* WRAPPER specification for JSON_QUERY */
+ JsonWrapper wrapper;
+
+ /* KEEP or OMIT QUOTES for singleton scalars returned by JSON_QUERY() */
+ bool omit_quotes;
+
+ /* JsonExpr's collation, if coercion_expr is NULL. */
+ Oid collation;
+
+ /* Original JsonFuncExpr's location */
+ int location;
+} JsonExpr;
+
/* ----------------
* NullTest
*
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index 099353469b5..3941ef18d01 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -93,6 +93,7 @@ PG_KEYWORD("commit", COMMIT, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("committed", COMMITTED, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("compression", COMPRESSION, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("concurrently", CONCURRENTLY, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL)
+PG_KEYWORD("conditional", CONDITIONAL, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("configuration", CONFIGURATION, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("conflict", CONFLICT, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("connection", CONNECTION, UNRESERVED_KEYWORD, BARE_LABEL)
@@ -147,11 +148,13 @@ PG_KEYWORD("double", DOUBLE_P, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("drop", DROP, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("each", EACH, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("else", ELSE, RESERVED_KEYWORD, BARE_LABEL)
+PG_KEYWORD("empty", EMPTY_P, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("enable", ENABLE_P, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("encoding", ENCODING, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("encrypted", ENCRYPTED, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("end", END_P, RESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("enum", ENUM_P, UNRESERVED_KEYWORD, BARE_LABEL)
+PG_KEYWORD("error", ERROR_P, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("escape", ESCAPE, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("event", EVENT, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("except", EXCEPT, RESERVED_KEYWORD, AS_LABEL)
@@ -233,10 +236,14 @@ PG_KEYWORD("join", JOIN, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("json", JSON, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("json_array", JSON_ARRAY, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("json_arrayagg", JSON_ARRAYAGG, COL_NAME_KEYWORD, BARE_LABEL)
+PG_KEYWORD("json_exists", JSON_EXISTS, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("json_object", JSON_OBJECT, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("json_objectagg", JSON_OBJECTAGG, COL_NAME_KEYWORD, BARE_LABEL)
+PG_KEYWORD("json_query", JSON_QUERY, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("json_scalar", JSON_SCALAR, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("json_serialize", JSON_SERIALIZE, COL_NAME_KEYWORD, BARE_LABEL)
+PG_KEYWORD("json_value", JSON_VALUE, COL_NAME_KEYWORD, BARE_LABEL)
+PG_KEYWORD("keep", KEEP, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("key", KEY, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("keys", KEYS, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("label", LABEL, UNRESERVED_KEYWORD, BARE_LABEL)
@@ -303,6 +310,7 @@ PG_KEYWORD("off", OFF, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("offset", OFFSET, RESERVED_KEYWORD, AS_LABEL)
PG_KEYWORD("oids", OIDS, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("old", OLD, UNRESERVED_KEYWORD, BARE_LABEL)
+PG_KEYWORD("omit", OMIT, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("on", ON, RESERVED_KEYWORD, AS_LABEL)
PG_KEYWORD("only", ONLY, RESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("operator", OPERATOR, UNRESERVED_KEYWORD, BARE_LABEL)
@@ -345,6 +353,7 @@ PG_KEYWORD("procedures", PROCEDURES, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("program", PROGRAM, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("publication", PUBLICATION, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("quote", QUOTE, UNRESERVED_KEYWORD, BARE_LABEL)
+PG_KEYWORD("quotes", QUOTES, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("range", RANGE, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("read", READ, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("real", REAL, COL_NAME_KEYWORD, BARE_LABEL)
@@ -415,6 +424,7 @@ PG_KEYWORD("stdout", STDOUT, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("storage", STORAGE, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("stored", STORED, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("strict", STRICT_P, UNRESERVED_KEYWORD, BARE_LABEL)
+PG_KEYWORD("string", STRING_P, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("strip", STRIP_P, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("subscription", SUBSCRIPTION, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("substring", SUBSTRING, COL_NAME_KEYWORD, BARE_LABEL)
@@ -450,6 +460,7 @@ PG_KEYWORD("types", TYPES_P, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("uescape", UESCAPE, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("unbounded", UNBOUNDED, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("uncommitted", UNCOMMITTED, UNRESERVED_KEYWORD, BARE_LABEL)
+PG_KEYWORD("unconditional", UNCONDITIONAL, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("unencrypted", UNENCRYPTED, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("union", UNION, RESERVED_KEYWORD, AS_LABEL)
PG_KEYWORD("unique", UNIQUE, RESERVED_KEYWORD, BARE_LABEL)
diff --git a/src/include/utils/formatting.h b/src/include/utils/formatting.h
index 7ea1a70f712..cde030414ee 100644
--- a/src/include/utils/formatting.h
+++ b/src/include/utils/formatting.h
@@ -29,5 +29,6 @@ extern char *asc_initcap(const char *buff, size_t nbytes);
extern Datum parse_datetime(text *date_txt, text *fmt, Oid collid, bool strict,
Oid *typid, int32 *typmod, int *tz,
struct Node *escontext);
+extern bool datetime_format_has_tz(const char *fmt_str);
#endif
diff --git a/src/include/utils/jsonb.h b/src/include/utils/jsonb.h
index e38dfd4901f..d589ace5a21 100644
--- a/src/include/utils/jsonb.h
+++ b/src/include/utils/jsonb.h
@@ -422,6 +422,7 @@ extern char *JsonbToCString(StringInfo out, JsonbContainer *in,
int estimated_len);
extern char *JsonbToCStringIndent(StringInfo out, JsonbContainer *in,
int estimated_len);
+extern char *JsonbUnquote(Jsonb *jb);
extern bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res);
extern const char *JsonbTypeName(JsonbValue *val);
diff --git a/src/include/utils/jsonfuncs.h b/src/include/utils/jsonfuncs.h
index 31c1ae47676..190e13284b2 100644
--- a/src/include/utils/jsonfuncs.h
+++ b/src/include/utils/jsonfuncs.h
@@ -15,6 +15,7 @@
#define JSONFUNCS_H
#include "common/jsonapi.h"
+#include "nodes/nodes.h"
#include "utils/jsonb.h"
/*
@@ -88,4 +89,10 @@ extern Datum datum_to_jsonb(Datum val, JsonTypeCategory tcategory,
Oid outfuncoid);
extern Datum jsonb_from_text(text *js, bool unique_keys);
+extern Datum json_populate_type(Datum json_val, Oid json_type,
+ Oid typid, int32 typmod,
+ void **cache, MemoryContext mcxt,
+ bool *isnull,
+ Node *escontext);
+
#endif
diff --git a/src/include/utils/jsonpath.h b/src/include/utils/jsonpath.h
index 0f0e126e03e..0f4b1ebc9f6 100644
--- a/src/include/utils/jsonpath.h
+++ b/src/include/utils/jsonpath.h
@@ -16,6 +16,7 @@
#include "fmgr.h"
#include "nodes/pg_list.h"
+#include "nodes/primnodes.h"
#include "utils/jsonb.h"
typedef struct
@@ -202,6 +203,7 @@ extern bool jspGetBool(JsonPathItem *v);
extern char *jspGetString(JsonPathItem *v, int32 *len);
extern bool jspGetArraySubscript(JsonPathItem *v, JsonPathItem *from,
JsonPathItem *to, int i);
+extern bool jspIsMutable(JsonPath *path, List *varnames, List *varexprs);
extern const char *jspOperationName(JsonPathItemType type);
@@ -279,4 +281,26 @@ extern bool jspConvertRegexFlags(uint32 xflags, int *result,
struct Node *escontext);
+/*
+ * Evaluation of jsonpath
+ */
+
+/* External variable passed into jsonpath. */
+typedef struct JsonPathVariable
+{
+ char *name;
+ Oid typid;
+ int32 typmod;
+ Datum value;
+ bool isnull;
+} JsonPathVariable;
+
+
+/* SQL/JSON item */
+extern bool JsonPathExists(Datum jb, JsonPath *path, bool *error, List *vars);
+extern Datum JsonPathQuery(Datum jb, JsonPath *jp, JsonWrapper wrapper,
+ bool *empty, bool *error, List *vars);
+extern JsonbValue *JsonPathValue(Datum jb, JsonPath *jp, bool *empty,
+ bool *error, List *vars);
+
#endif