Skip to content

Commit 05cedcd

Browse files
Add support for OPENXML with WITH clause (#76)
OPENXML provides a rowset view over an XML document. Since OPENXML is a rowset provider and it returns a set of rows, we can use OPENXML in the FROM clause of a T-SQL statement just as we can use any other table, view, or table-valued function. The WITH clause in OPENXML provides a rowset format (and additional mapping information as required) by using either SchemaDeclaration or specifying an existing TableName. Currently Babelfish does not have support for openxml. So the primary objective is to add support for OPENXML with WITH clause. The syntax of openxml is as follows : OPENXML ( idoc int [ in ] , rowpattern nvarchar [ in ], [ flags byte [ in ] ] ) [ WITH ( SchemaDeclaration | TableName ) ] Arguments idoc The document handle of the internal representation of an XML document. The internal representation of an XML document is created by calling sp_xml_preparedocument. rowpattern The XPath pattern used to identify the nodes to be processed as rows. The nodes come from the XML document whose handle is passed in the idoc parameter. flags Indicates the mapping used between the XML data and the relational rowset, and how the spill-over column is filled. flags is an optional input parameter, and can be one of the following values. The WITH clause provides a rowset format (and additional mapping information as required) by using either SchemaDeclaration or specifying an existing TableName. If the optional WITH clause isn't specified, the results are returned in an edge table format. Edge tables represent the fine-grained XML document structure (such as element/attribute names, the document hierarchy, the namespaces, PIs, and so on) in a single table. BABEL-3635 Engine PR : amazon-aurora/postgresql_modified_for_babelfish#133 Signed-off-by: Harsh Dubey [email protected]
1 parent 7840f56 commit 05cedcd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+4065
-7
lines changed

contrib/babelfishpg_tsql/sql/sys_functions.sql

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4029,6 +4029,16 @@ CREATE OR REPLACE FUNCTION sys.openjson_with(json_string text, path text, VARIAD
40294029
RETURNS SETOF RECORD
40304030
AS 'babelfishpg_tsql', 'tsql_openjson_with' LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE;
40314031

4032+
CREATE OR REPLACE FUNCTION sys.tsql_openxml_get_xmldoc(int)
4033+
RETURNS xml
4034+
AS 'babelfishpg_tsql', 'tsql_openxml_get_xmldoc'
4035+
LANGUAGE C STRICT;
4036+
4037+
CREATE OR REPLACE FUNCTION sys.tsql_openxml_get_colpattern(text,int)
4038+
RETURNS sys.nvarchar
4039+
AS 'babelfishpg_tsql', 'tsql_openxml_get_colpattern'
4040+
LANGUAGE C STRICT;
4041+
40324042
CREATE OR REPLACE FUNCTION sys.sp_datatype_info_helper(
40334043
IN odbcVer smallint,
40344044
IN is_100 bool,

contrib/babelfishpg_tsql/sql/sys_procedures.sql

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,3 +333,20 @@ GRANT EXECUTE on PROCEDURE sys.sp_enum_oledb_providers() TO PUBLIC;
333333
CREATE OR REPLACE PROCEDURE sys.sp_reset_connection()
334334
AS 'babelfishpg_tsql', 'sp_reset_connection_internal' LANGUAGE C;
335335
GRANT EXECUTE ON PROCEDURE sys.sp_reset_connection() TO PUBLIC;
336+
337+
CREATE OR REPLACE PROCEDURE sys.sp_xml_preparedocument( INOUT "@hdoc" INTEGER,
338+
IN "@xmltext" sys.VARCHAR DEFAULT NULL,
339+
IN "@xpath_namespaces" sys.VARCHAR DEFAULT NULL )
340+
AS 'babelfishpg_tsql', 'sp_xml_preparedocument'
341+
LANGUAGE C;
342+
343+
GRANT EXECUTE ON PROCEDURE sys.sp_xml_preparedocument( INOUT "@hdoc" INTEGER,
344+
IN "@xmltext" sys.VARCHAR ,
345+
IN "@xpath_namespaces" sys.VARCHAR )
346+
TO PUBLIC;
347+
348+
CREATE OR REPLACE PROCEDURE sys.sp_xml_removedocument( IN "@hdoc" INTEGER )
349+
AS 'babelfishpg_tsql', 'sp_xml_removedocument'
350+
LANGUAGE C;
351+
352+
GRANT EXECUTE ON PROCEDURE sys.sp_xml_removedocument( IN INTEGER ) TO PUBLIC;

contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--5.2.0--5.3.0.sql

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,6 +1009,36 @@ STABLE;
10091009
-- Please have this be one of the last statements executed in this upgrade script.
10101010
DROP PROCEDURE sys.babelfish_drop_deprecated_object(varchar, varchar, varchar);
10111011

1012+
CREATE OR REPLACE PROCEDURE sys.sp_xml_preparedocument(
1013+
INOUT "@hdoc" INTEGER,
1014+
IN "@xmltext" sys.VARCHAR DEFAULT NULL,
1015+
IN "@xpath_namespaces" sys.VARCHAR DEFAULT NULL
1016+
)
1017+
AS 'babelfishpg_tsql', 'sp_xml_preparedocument'
1018+
LANGUAGE C;
1019+
GRANT EXECUTE ON PROCEDURE sys.sp_xml_preparedocument(
1020+
INOUT INTEGER, IN sys.varchar, IN sys.varchar
1021+
) TO PUBLIC;
1022+
1023+
CREATE OR REPLACE PROCEDURE sys.sp_xml_removedocument(
1024+
IN "@hdoc" INTEGER
1025+
)
1026+
AS 'babelfishpg_tsql', 'sp_xml_removedocument'
1027+
LANGUAGE C;
1028+
GRANT EXECUTE ON PROCEDURE sys.sp_xml_removedocument(
1029+
IN INTEGER
1030+
) TO PUBLIC;
1031+
1032+
CREATE OR REPLACE FUNCTION sys.tsql_openxml_get_xmldoc(int)
1033+
RETURNS xml
1034+
AS 'babelfishpg_tsql', 'tsql_openxml_get_xmldoc'
1035+
LANGUAGE C STRICT;
1036+
1037+
CREATE OR REPLACE FUNCTION sys.tsql_openxml_get_colpattern(text,int)
1038+
RETURNS sys.nvarchar
1039+
AS 'babelfishpg_tsql', 'tsql_openxml_get_colpattern'
1040+
LANGUAGE C STRICT;
1041+
10121042
-- After upgrade, always run analyze for all babelfish catalogs.
10131043
CALL sys.analyze_babelfish_catalogs();
10141044
-- Reset search_path to not affect any subsequent scripts

contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-decl.y

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@
4141
%type <list> openjson_col_defs
4242
%type <str> optional_path
4343
%type <boolean> optional_asJson
44+
%type <node> openxml_expr
45+
%type <list> openxml_column_list
46+
%type <node> openxml_column_el
4447

4548
%type <node> tsql_opt_arg_dflt
4649
%type <node> tsql_opt_null_keyword
@@ -117,7 +120,7 @@
117120
TSQL_NOCHECK TSQL_NOLOCK TSQL_READUNCOMMITTED TSQL_UPDLOCK TSQL_REPEATABLEREAD
118121
TSQL_READCOMMITTED TSQL_TABLOCK TSQL_TABLOCKX TSQL_PAGLOCK TSQL_ROWLOCK
119122
TSQL_TOP TSQL_PERCENT
120-
TSQL_AUTO TSQL_EXPLICIT TSQL_RAW TSQL_PATH TSQL_FOR TSQL_BASE64 TSQL_ROOT TSQL_READPAST TSQL_XLOCK TSQL_NOEXPAND OPENJSON JSON_MODIFY
123+
TSQL_AUTO TSQL_EXPLICIT TSQL_RAW TSQL_PATH TSQL_FOR TSQL_BASE64 TSQL_ROOT TSQL_READPAST TSQL_XLOCK TSQL_NOEXPAND OPENJSON OPENXML JSON_MODIFY
121124
TSQL_JSON TSQL_INCLUDE_NULL_VALUES TSQL_WITHOUT_ARRAY_WRAPPER
122125
TSQL_MEMBER TSQL_SERVER
123126
TSQL_WINDOWS TSQL_CERTIFICATE TSQL_DEFAULT_DATABASE TSQL_DEFAULT_LANGUAGE TSQL_HASHED
@@ -134,6 +137,6 @@
134137
* otherwise the parser cannot tell between 'WITH' and 'WITH (' and thus
135138
* lead to a shift/reduce conflict.
136139
*/
137-
%token WITH_paren TSQL_HINT_START_BRACKET UPDATE_paren
140+
%token WITH_paren TSQL_HINT_START_BRACKET UPDATE_paren WITH_table
138141

139142
%left TSQL_CROSS TSQL_OUTER TSQL_UNPIVOT

contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-rule.y

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1779,13 +1779,106 @@ table_ref: relation_expr tsql_table_hint_expr
17791779
*/
17801780
$$ = (Node *) $1;
17811781
}
1782+
| TSQL_APPLY openxml_expr
1783+
{
1784+
/*
1785+
* This case handles openxml cross/outer apply
1786+
*/
1787+
$$ = (Node *) $2;
1788+
}
1789+
| openxml_expr
1790+
{
1791+
/*
1792+
* Standard openxml case
1793+
*/
1794+
$$ = (Node *) $1;
1795+
}
17821796
| table_ref TSQL_UNPIVOT tsql_unpivot_clause alias_clause
17831797
{
17841798
List *unpivot_info = list_make3($1, (List *)$3, $4);
17851799
$$ = tsql_unpivot_transformation(unpivot_info, @1);
17861800
}
17871801
;
17881802

1803+
openxml_expr: OPENXML '(' a_expr ',' a_expr ')' WITH_table TABLE qualified_name opt_alias_clause
1804+
{
1805+
RangeTableFunc *n = makeNode(RangeTableFunc);
1806+
n->docexpr = NULL;
1807+
n->rowexpr = $5;
1808+
n->location = @1;
1809+
/* Default flag is 0 when not specified */
1810+
n->namespaces = list_make2((Node *)$3, makeIntConst(0, @1));
1811+
n->columns = list_make1($9);
1812+
n->alias = $10;
1813+
$$ = (Node *) n;
1814+
}
1815+
| OPENXML '(' a_expr ',' a_expr ',' a_expr ')' WITH_table TABLE qualified_name opt_alias_clause
1816+
{
1817+
RangeTableFunc *n = makeNode(RangeTableFunc);
1818+
n->docexpr = NULL;
1819+
n->rowexpr = $5;
1820+
n->location = @1;
1821+
n->namespaces = list_make2((Node *)$3, (Node *)$7);
1822+
n->columns = list_make1($11);
1823+
n->alias = $12;
1824+
$$ = (Node *) n;
1825+
}
1826+
| OPENXML '(' a_expr ',' a_expr ')' WITH_paren '(' openxml_column_list ')' opt_alias_clause
1827+
{
1828+
RangeTableFunc *n = makeNode(RangeTableFunc);
1829+
n->docexpr = NULL;
1830+
n->rowexpr = $5;
1831+
n->location = @1;
1832+
/* Default flag is 0 when not specified */
1833+
n->columns = $9;
1834+
n->namespaces = list_make2((Node *)$3, makeIntConst(0, @1));
1835+
n->alias = $11;
1836+
$$ = (Node *) n;
1837+
}
1838+
| OPENXML '(' a_expr ',' a_expr ',' a_expr ')' WITH_paren '(' openxml_column_list ')' opt_alias_clause
1839+
{
1840+
RangeTableFunc *n = makeNode(RangeTableFunc);
1841+
n->docexpr = NULL;
1842+
n->rowexpr = $5;
1843+
n->columns = $11;
1844+
n->location = @1;
1845+
n->namespaces = list_make2((Node *)$3, (Node *)$7);
1846+
n->alias = $13;
1847+
$$ = (Node *) n;
1848+
}
1849+
;
1850+
1851+
openxml_column_list: openxml_column_el { $$ = list_make1($1); }
1852+
| openxml_column_list ',' openxml_column_el { $$ = lappend($1, $3); }
1853+
;
1854+
1855+
openxml_column_el:
1856+
ColId Typename
1857+
{
1858+
RangeTableFuncCol *fc = makeNode(RangeTableFuncCol);
1859+
1860+
fc->colname = $1;
1861+
fc->typeName = $2;
1862+
fc->colexpr = NULL;
1863+
fc->coldefexpr = NULL;
1864+
fc->location = @1;
1865+
1866+
$$ = (Node *) fc;
1867+
}
1868+
| ColId Typename Sconst
1869+
{
1870+
RangeTableFuncCol *fc = makeNode(RangeTableFuncCol);
1871+
1872+
fc->colname = $1;
1873+
fc->typeName = $2;
1874+
fc->colexpr = (Node *) makeStringConst($3, @1);
1875+
fc->coldefexpr = NULL;
1876+
fc->location = @1;
1877+
1878+
$$ = (Node *) fc;
1879+
}
1880+
;
1881+
17891882
openjson_expr: OPENJSON '(' a_expr ')' opt_alias_clause
17901883
{
17911884
RangeFunction *n = makeNode(RangeFunction);

contrib/babelfishpg_tsql/src/backend_parser/kwlist.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ PG_KEYWORD("old_password", TSQL_OLD_PASSWORD, UNRESERVED_KEYWORD)
323323
PG_KEYWORD("on", ON, RESERVED_KEYWORD)
324324
PG_KEYWORD("only", ONLY, RESERVED_KEYWORD)
325325
PG_KEYWORD("openjson", OPENJSON, COL_NAME_KEYWORD)
326+
PG_KEYWORD("openxml", OPENXML, COL_NAME_KEYWORD)
326327
PG_KEYWORD("operator", OPERATOR, UNRESERVED_KEYWORD)
327328
PG_KEYWORD("option", OPTION, RESERVED_KEYWORD)
328329
PG_KEYWORD("options", OPTIONS, UNRESERVED_KEYWORD)

contrib/babelfishpg_tsql/src/backend_parser/parser.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,8 @@ pgtsql_base_yylex(YYSTYPE *lvalp, YYLTYPE * llocp, core_yyscan_t yyscanner)
266266
case '(':
267267
cur_token = WITH_paren;
268268
break;
269+
case TABLE:
270+
cur_token = WITH_table;
269271
}
270272
break;
271273
case '(':

contrib/babelfishpg_tsql/src/extendedproperty.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ static void init_scan_key(ScanKeyData *scanKey,
7171
static void sp_execextended_property(PG_FUNCTION_ARGS, ExtendedPropertyProc proc);
7272
static bool get_extended_property_from_tuple(Relation relation, HeapTuple tuple,
7373
Datum *values, bool *nulls, int len);
74-
static char* get_value_by_name_from_array(ArrayType *array, const char *name);
7574

7675
static void
7776
init_scan_key(ScanKeyData *scanKey,
@@ -923,7 +922,7 @@ fn_listextendedproperty(PG_FUNCTION_ARGS)
923922
extern const char *ATTOPTION_BBF_ORIGINAL_TABLE_NAME;
924923
extern const char *ATTOPTION_BBF_ORIGINAL_NAME;
925924

926-
static char*
925+
char*
927926
get_value_by_name_from_array(ArrayType *array, const char *name)
928927
{
929928
int i;

contrib/babelfishpg_tsql/src/extendedproperty.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ typedef enum ExtendedPropertyType
1616
} ExtendedPropertyType;
1717

1818
extern const char *const ExtendedPropertyTypeNames[];
19+
extern char *get_value_by_name_from_array(ArrayType *array, const char *name);
1920

2021
extern void delete_extended_property(int16 db_id,
2122
const char *type,

0 commit comments

Comments
 (0)