Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2f8f76b

Browse files
committed
Add support for xmlval IS DOCUMENT expression.
1 parent62c0618 commit2f8f76b

File tree

11 files changed

+156
-11
lines changed

11 files changed

+156
-11
lines changed

‎src/backend/executor/execQual.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.206 2007/01/12 21:47:26 petere Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.207 2007/01/14 13:11:53 petere Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -2808,6 +2808,25 @@ ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
28082808
standalone));
28092809
}
28102810
break;
2811+
2812+
caseIS_DOCUMENT:
2813+
{
2814+
ExprState*e;
2815+
2816+
/* optional argument is known to be xml */
2817+
Assert(list_length(xmlExpr->args)==1);
2818+
2819+
e= (ExprState*)linitial(xmlExpr->args);
2820+
value=ExecEvalExpr(e,econtext,&isnull,NULL);
2821+
if (isnull)
2822+
return (Datum)0;
2823+
else
2824+
{
2825+
*isNull= false;
2826+
returnBoolGetDatum(xml_is_document(DatumGetXmlP(value)));
2827+
}
2828+
}
2829+
break;
28112830
}
28122831

28132832
if (*isNull)

‎src/backend/parser/gram.y

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.573 2007/01/09 02:14:14 tgl Exp $
14+
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.574 2007/01/14 13:11:53 petere Exp $
1515
*
1616
* HISTORY
1717
* AUTHORDATEMAJOR EVENT
@@ -7147,6 +7147,16 @@ a_expr:c_expr{ $$ = $1; }
71477147
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
71487148
errmsg("UNIQUE predicate is not yet implemented")));
71497149
}
7150+
| a_expr IS DOCUMENT_P%prec IS
7151+
{
7152+
$$ = makeXmlExpr(IS_DOCUMENT,NULL, NIL, list_make1($1));
7153+
}
7154+
| a_expr IS NOT DOCUMENT_P%prec IS
7155+
{
7156+
$$ = (Node *) makeA_Expr(AEXPR_NOT, NIL,NULL,
7157+
makeXmlExpr(IS_DOCUMENT,NULL, NIL, list_make1($1)),
7158+
@2);
7159+
}
71507160
;
71517161

71527162
/*
@@ -7207,6 +7217,16 @@ b_expr:c_expr
72077217
{
72087218
$$ = (Node *) makeSimpleA_Expr(AEXPR_OF,"<>",$1, (Node *)$6,@2);
72097219
}
7220+
| b_expr IS DOCUMENT_P%prec IS
7221+
{
7222+
$$ = makeXmlExpr(IS_DOCUMENT,NULL, NIL, list_make1($1));
7223+
}
7224+
| b_expr IS NOT DOCUMENT_P%prec IS
7225+
{
7226+
$$ = (Node *) makeA_Expr(AEXPR_NOT, NIL,NULL,
7227+
makeXmlExpr(IS_DOCUMENT,NULL, NIL, list_make1($1)),
7228+
@2);
7229+
}
72107230
;
72117231

72127232
/*

‎src/backend/parser/parse_expr.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.207 2007/01/12 22:09:49 petere Exp $
11+
* $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.208 2007/01/14 13:11:53 petere Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1483,6 +1483,10 @@ transformXmlExpr(ParseState *pstate, XmlExpr *x)
14831483
else
14841484
newe=coerce_to_boolean(pstate,newe,"XMLROOT");
14851485
break;
1486+
caseIS_DOCUMENT:
1487+
newe=coerce_to_specific_type(pstate,newe,XMLOID,
1488+
"IS DOCUMENT");
1489+
break;
14861490
}
14871491
newx->args=lappend(newx->args,newe);
14881492
i++;
@@ -1782,7 +1786,10 @@ exprType(Node *expr)
17821786
type= ((MinMaxExpr*)expr)->minmaxtype;
17831787
break;
17841788
caseT_XmlExpr:
1785-
type=XMLOID;
1789+
if (((XmlExpr*)expr)->op==IS_DOCUMENT)
1790+
type=BOOLOID;
1791+
else
1792+
type=XMLOID;
17861793
break;
17871794
caseT_NullIfExpr:
17881795
type=exprType((Node*)linitial(((NullIfExpr*)expr)->args));

‎src/backend/parser/parse_target.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.152 2007/01/05 22:19:34 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.153 2007/01/14 13:11:54 petere Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1337,6 +1337,9 @@ FigureColnameInternal(Node *node, char **name)
13371337
caseIS_XMLROOT:
13381338
*name="xmlroot";
13391339
return2;
1340+
caseIS_DOCUMENT:
1341+
/* nothing */
1342+
break;
13401343
}
13411344
break;
13421345
default:

‎src/backend/utils/adt/ruleutils.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* ruleutils.c- Functions to convert stored expressions/querytrees
33
*back to source text
44
*
5-
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.241 2007/01/09 02:14:14 tgl Exp $
5+
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.242 2007/01/14 13:11:54 petere Exp $
66
**********************************************************************/
77

88
#include"postgres.h"
@@ -3847,6 +3847,8 @@ get_rule_expr(Node *node, deparse_context *context,
38473847
caseIS_XMLROOT:
38483848
appendStringInfoString(buf,"XMLROOT(");
38493849
break;
3850+
caseIS_DOCUMENT:
3851+
break;
38503852
}
38513853
if (xexpr->name)
38523854
{
@@ -3888,6 +3890,7 @@ get_rule_expr(Node *node, deparse_context *context,
38883890
caseIS_XMLELEMENT:
38893891
caseIS_XMLFOREST:
38903892
caseIS_XMLPI:
3893+
caseIS_DOCUMENT:
38913894
/* no extra decoration needed */
38923895
get_rule_expr((Node*)xexpr->args,context, true);
38933896
break;
@@ -3943,7 +3946,10 @@ get_rule_expr(Node *node, deparse_context *context,
39433946
}
39443947

39453948
}
3946-
appendStringInfoChar(buf,')');
3949+
if (xexpr->op==IS_DOCUMENT)
3950+
appendStringInfoString(buf," IS DOCUMENT");
3951+
else
3952+
appendStringInfoChar(buf,')');
39473953
}
39483954
break;
39493955

‎src/backend/utils/adt/xml.c

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.16 2007/01/12 21:47:26 petere Exp $
10+
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.17 2007/01/14 13:11:54 petere Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -515,6 +515,50 @@ xmlvalidate(PG_FUNCTION_ARGS)
515515
}
516516

517517

518+
bool
519+
xml_is_document(xmltype*arg)
520+
{
521+
#ifdefUSE_LIBXML
522+
boolresult;
523+
xmlDocPtrdoc=NULL;
524+
MemoryContextccxt=CurrentMemoryContext;
525+
526+
PG_TRY();
527+
{
528+
doc=xml_parse((text*)arg, true, true);
529+
result= true;
530+
}
531+
PG_CATCH();
532+
{
533+
ErrorData*errdata;
534+
MemoryContextecxt;
535+
536+
ecxt=MemoryContextSwitchTo(ccxt);
537+
errdata=CopyErrorData();
538+
if (errdata->sqlerrcode==ERRCODE_INVALID_XML_DOCUMENT)
539+
{
540+
FlushErrorState();
541+
result= false;
542+
}
543+
else
544+
{
545+
MemoryContextSwitchTo(ecxt);
546+
PG_RE_THROW();
547+
}
548+
}
549+
PG_END_TRY();
550+
551+
if (doc)
552+
xmlFreeDoc(doc);
553+
554+
returnresult;
555+
#else/* not USE_LIBXML */
556+
NO_XML_SUPPORT();
557+
return false;
558+
#endif/* not USE_LIBXML */
559+
}
560+
561+
518562
#ifdefUSE_LIBXML
519563

520564
/*

‎src/include/nodes/primnodes.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
1111
* Portions Copyright (c) 1994, Regents of the University of California
1212
*
13-
* $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.122 2007/01/05 22:19:56 momjian Exp $
13+
* $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.123 2007/01/14 13:11:54 petere Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -725,7 +725,8 @@ typedef enum XmlExprOp
725725
IS_XMLFOREST,/* XMLFOREST(xml_attributes) */
726726
IS_XMLPARSE,/* XMLPARSE(text, is_doc, preserve_ws) */
727727
IS_XMLPI,/* XMLPI(name [, args]) */
728-
IS_XMLROOT/* XMLROOT(xml, version, standalone) */
728+
IS_XMLROOT,/* XMLROOT(xml, version, standalone) */
729+
IS_DOCUMENT/* xmlval IS DOCUMENT */
729730
}XmlExprOp;
730731

731732
typedefstructXmlExpr

‎src/include/utils/xml.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.9 2007/01/12 21:47:27 petere Exp $
10+
* $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.10 2007/01/14 13:11:54 petere Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -37,6 +37,7 @@ extern xmltype *xmlelement(XmlExprState *xmlExpr, ExprContext *econtext);
3737
externxmltype*xmlparse(text*data,boolis_doc,boolpreserve_whitespace);
3838
externxmltype*xmlpi(char*target,text*arg,boolarg_is_null,bool*result_is_null);
3939
externxmltype*xmlroot(xmltype*data,text*version,intstandalone);
40+
externboolxml_is_document(xmltype*arg);
4041

4142
externchar*map_sql_identifier_to_xml_name(char*ident,boolfully_escaped);
4243
externchar*map_xml_name_to_sql_identifier(char*name);

‎src/test/regress/expected/xml.out

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,33 @@ SELECT xmlserialize(content data as character varying) FROM xmltest;
228228
<value>two</value>
229229
(2 rows)
230230

231+
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
232+
?column?
233+
----------
234+
t
235+
(1 row)
236+
237+
SELECT xml '<foo>bar</foo><bar>foo</bar>' IS DOCUMENT;
238+
?column?
239+
----------
240+
f
241+
(1 row)
242+
243+
SELECT xml '<abc/>' IS NOT DOCUMENT;
244+
?column?
245+
----------
246+
f
247+
(1 row)
248+
249+
SELECT xml 'abc' IS NOT DOCUMENT;
250+
?column?
251+
----------
252+
t
253+
(1 row)
254+
255+
SELECT '<>' IS NOT DOCUMENT;
256+
ERROR: invalid XML content
257+
DETAIL: Element name not found
231258
-- Check mapping SQL identifier to XML name
232259
SELECT xmlpi(name ":::_xml_abc135.%-&_");
233260
xmlpi

‎src/test/regress/expected/xml_1.out

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,16 @@ SELECT xmlserialize(content data as character varying) FROM xmltest;
107107
------
108108
(0 rows)
109109

110+
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
111+
ERROR: no XML support in this installation
112+
SELECT xml '<foo>bar</foo><bar>foo</bar>' IS DOCUMENT;
113+
ERROR: no XML support in this installation
114+
SELECT xml '<abc/>' IS NOT DOCUMENT;
115+
ERROR: no XML support in this installation
116+
SELECT xml 'abc' IS NOT DOCUMENT;
117+
ERROR: no XML support in this installation
118+
SELECT '<>' IS NOT DOCUMENT;
119+
ERROR: no XML support in this installation
110120
-- Check mapping SQL identifier to XML name
111121
SELECT xmlpi(name ":::_xml_abc135.%-&_");
112122
ERROR: no XML support in this installation

‎src/test/regress/sql/xml.sql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ SELECT xmlroot (
8686
SELECT xmlserialize(content dataas character varying)FROM xmltest;
8787

8888

89+
SELECT xml'<foo>bar</foo>' IS DOCUMENT;
90+
SELECT xml'<foo>bar</foo><bar>foo</bar>' IS DOCUMENT;
91+
SELECT xml'<abc/>' IS NOT DOCUMENT;
92+
SELECT xml'abc' IS NOT DOCUMENT;
93+
SELECT'<>' IS NOT DOCUMENT;
94+
95+
8996
-- Check mapping SQL identifier to XML name
9097

9198
SELECT xmlpi(name":::_xml_abc135.%-&_");

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp