mirror of
https://github.com/postgres/postgres.git
synced 2025-07-02 09:02:37 +03:00
Support XMLTABLE query expression
XMLTABLE is defined by the SQL/XML standard as a feature that allows turning XML-formatted data into relational form, so that it can be used as a <table primary> in the FROM clause of a query. This new construct provides significant simplicity and performance benefit for XML data processing; what in a client-side custom implementation was reported to take 20 minutes can be executed in 400ms using XMLTABLE. (The same functionality was said to take 10 seconds using nested PostgreSQL XPath function calls, and 5 seconds using XMLReader under PL/Python). The implemented syntax deviates slightly from what the standard requires. First, the standard indicates that the PASSING clause is optional and that multiple XML input documents may be given to it; we make it mandatory and accept a single document only. Second, we don't currently support a default namespace to be specified. This implementation relies on a new executor node based on a hardcoded method table. (Because the grammar is fixed, there is no extensibility in the current approach; further constructs can be implemented on top of this such as JSON_TABLE, but they require changes to core code.) Author: Pavel Stehule, Álvaro Herrera Extensively reviewed by: Craig Ringer Discussion: https://postgr.es/m/CAFj8pRAgfzMD-LoSmnMGybD0WsEznLHWap8DO79+-GTRAPR4qA@mail.gmail.com
This commit is contained in:
@ -69,17 +69,19 @@ create_upper_paths_hook_type create_upper_paths_hook = NULL;
|
||||
|
||||
|
||||
/* Expression kind codes for preprocess_expression */
|
||||
#define EXPRKIND_QUAL 0
|
||||
#define EXPRKIND_TARGET 1
|
||||
#define EXPRKIND_RTFUNC 2
|
||||
#define EXPRKIND_RTFUNC_LATERAL 3
|
||||
#define EXPRKIND_VALUES 4
|
||||
#define EXPRKIND_VALUES_LATERAL 5
|
||||
#define EXPRKIND_LIMIT 6
|
||||
#define EXPRKIND_APPINFO 7
|
||||
#define EXPRKIND_PHV 8
|
||||
#define EXPRKIND_TABLESAMPLE 9
|
||||
#define EXPRKIND_ARBITER_ELEM 10
|
||||
#define EXPRKIND_QUAL 0
|
||||
#define EXPRKIND_TARGET 1
|
||||
#define EXPRKIND_RTFUNC 2
|
||||
#define EXPRKIND_RTFUNC_LATERAL 3
|
||||
#define EXPRKIND_VALUES 4
|
||||
#define EXPRKIND_VALUES_LATERAL 5
|
||||
#define EXPRKIND_LIMIT 6
|
||||
#define EXPRKIND_APPINFO 7
|
||||
#define EXPRKIND_PHV 8
|
||||
#define EXPRKIND_TABLESAMPLE 9
|
||||
#define EXPRKIND_ARBITER_ELEM 10
|
||||
#define EXPRKIND_TABLEFUNC 11
|
||||
#define EXPRKIND_TABLEFUNC_LATERAL 12
|
||||
|
||||
/* Passthrough data for standard_qp_callback */
|
||||
typedef struct
|
||||
@ -685,7 +687,15 @@ subquery_planner(PlannerGlobal *glob, Query *parse,
|
||||
{
|
||||
/* Preprocess the function expression(s) fully */
|
||||
kind = rte->lateral ? EXPRKIND_RTFUNC_LATERAL : EXPRKIND_RTFUNC;
|
||||
rte->functions = (List *) preprocess_expression(root, (Node *) rte->functions, kind);
|
||||
rte->functions = (List *)
|
||||
preprocess_expression(root, (Node *) rte->functions, kind);
|
||||
}
|
||||
else if (rte->rtekind == RTE_TABLEFUNC)
|
||||
{
|
||||
/* Preprocess the function expression(s) fully */
|
||||
kind = rte->lateral ? EXPRKIND_TABLEFUNC_LATERAL : EXPRKIND_TABLEFUNC;
|
||||
rte->tablefunc = (TableFunc *)
|
||||
preprocess_expression(root, (Node *) rte->tablefunc, kind);
|
||||
}
|
||||
else if (rte->rtekind == RTE_VALUES)
|
||||
{
|
||||
@ -844,7 +854,8 @@ preprocess_expression(PlannerInfo *root, Node *expr, int kind)
|
||||
if (root->hasJoinRTEs &&
|
||||
!(kind == EXPRKIND_RTFUNC ||
|
||||
kind == EXPRKIND_VALUES ||
|
||||
kind == EXPRKIND_TABLESAMPLE))
|
||||
kind == EXPRKIND_TABLESAMPLE ||
|
||||
kind == EXPRKIND_TABLEFUNC))
|
||||
expr = flatten_join_alias_vars(root, expr);
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user