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

Commitb4c8d49

Browse files
committed
Fix xmlconcat by properly merging the XML declarations. Add aggregate
function xmlagg.
1 parent9a83bd5 commitb4c8d49

File tree

9 files changed

+171
-19
lines changed

9 files changed

+171
-19
lines changed

‎src/backend/executor/execQual.c

Lines changed: 13 additions & 12 deletions
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.207 2007/01/14 13:11:53 petere Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.208 2007/01/20 09:27:19 petere Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -2651,7 +2651,6 @@ ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
26512651
StringInfoDatabuf;
26522652
Datumvalue;
26532653
boolisnull;
2654-
char*str;
26552654
ListCell*arg;
26562655
ListCell*narg;
26572656
inti;
@@ -2663,20 +2662,22 @@ ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
26632662
switch (xexpr->op)
26642663
{
26652664
caseIS_XMLCONCAT:
2666-
initStringInfo(&buf);
2667-
foreach(arg,xmlExpr->args)
26682665
{
2669-
ExprState*e=(ExprState*)lfirst(arg);
2666+
List*values=NIL;
26702667

2671-
value=ExecEvalExpr(e,econtext,&isnull,NULL);
2672-
if (!isnull)
2668+
foreach(arg,xmlExpr->args)
2669+
{
2670+
ExprState*e= (ExprState*)lfirst(arg);
2671+
2672+
value=ExecEvalExpr(e,econtext,&isnull,NULL);
2673+
if (!isnull)
2674+
values=lappend(values,DatumGetPointer(value));
2675+
}
2676+
2677+
if (list_length(values)>0)
26732678
{
2674-
/* we know the value is XML type */
2675-
str=DatumGetCString(DirectFunctionCall1(xml_out,
2676-
value));
2677-
appendStringInfoString(&buf,str);
2678-
pfree(str);
26792679
*isNull= false;
2680+
returnPointerGetDatum(xmlconcat(values));
26802681
}
26812682
}
26822683
break;

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

Lines changed: 97 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.19 2007/01/19 16:58:46 petere Exp $
10+
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.20 2007/01/20 09:27:19 petere Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -359,6 +359,102 @@ xmlcomment(PG_FUNCTION_ARGS)
359359
}
360360

361361

362+
363+
/*
364+
* TODO: xmlconcat needs to merge the notations and unparsed entities
365+
* of the argument values. Not very important in practice, though.
366+
*/
367+
xmltype*
368+
xmlconcat(List*args)
369+
{
370+
#ifdefUSE_LIBXML
371+
StringInfoDatabuf;
372+
ListCell*v;
373+
374+
intglobal_standalone=1;
375+
xmlChar*global_version=NULL;
376+
boolglobal_version_no_value= false;
377+
378+
initStringInfo(&buf);
379+
foreach(v,args)
380+
{
381+
size_tlen;
382+
xmlChar*version;
383+
intstandalone;
384+
xmltype*x=DatumGetXmlP(PointerGetDatum(lfirst(v)));
385+
char*str;
386+
387+
len=VARSIZE(x)-VARHDRSZ;
388+
str=palloc(len+1);
389+
memcpy(str,VARDATA(x),len);
390+
str[len]='\0';
391+
392+
parse_xml_decl((xmlChar*)str,&len,&version,NULL,&standalone);
393+
394+
if (standalone==0&&global_standalone==1)
395+
global_standalone=0;
396+
if (standalone<0)
397+
global_standalone=-1;
398+
399+
if (!global_version)
400+
global_version=xmlStrdup(version);
401+
elseif (version&&xmlStrcmp(version,global_version)!=0)
402+
global_version_no_value= true;
403+
404+
appendStringInfoString(&buf,str+len);
405+
pfree(str);
406+
}
407+
408+
if (!global_version_no_value||global_standalone >=0)
409+
{
410+
StringInfoDatabuf2;
411+
412+
initStringInfo(&buf2);
413+
414+
if (!global_version_no_value&&global_version)
415+
appendStringInfo(&buf2,"<?xml version=\"%s\"",global_version);
416+
else
417+
appendStringInfo(&buf2,"<?xml version=\"%s\"",PG_XML_DEFAULT_VERSION);
418+
419+
if (global_standalone==1)
420+
appendStringInfoString(&buf2," standalone=\"yes\"");
421+
elseif (global_standalone==0)
422+
appendStringInfoString(&buf2," standalone=\"no\"");
423+
424+
appendStringInfoString(&buf2,"?>");
425+
426+
appendStringInfoString(&buf2,buf.data);
427+
buf=buf2;
428+
}
429+
430+
returnstringinfo_to_xmltype(&buf);
431+
#else
432+
NO_XML_SUPPORT();
433+
returnNULL;
434+
#endif
435+
}
436+
437+
438+
/*
439+
* XMLAGG support
440+
*/
441+
Datum
442+
xmlconcat2(PG_FUNCTION_ARGS)
443+
{
444+
if (PG_ARGISNULL(0))
445+
{
446+
if (PG_ARGISNULL(1))
447+
PG_RETURN_NULL();
448+
else
449+
PG_RETURN_XML_P(PG_GETARG_XML_P(1));
450+
}
451+
elseif (PG_ARGISNULL(1))
452+
PG_RETURN_XML_P(PG_GETARG_XML_P(0));
453+
else
454+
PG_RETURN_XML_P(xmlconcat(list_make2(PG_GETARG_XML_P(0),PG_GETARG_XML_P(1))));
455+
}
456+
457+
362458
Datum
363459
texttoxml(PG_FUNCTION_ARGS)
364460
{

‎src/include/catalog/catversion.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
3838
* Portions Copyright (c) 1994, Regents of the University of California
3939
*
40-
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.372 2007/01/16 21:41:13 neilc Exp $
40+
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.373 2007/01/20 09:27:19 petere Exp $
4141
*
4242
*-------------------------------------------------------------------------
4343
*/
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/*yyyymmddN */
56-
#defineCATALOG_VERSION_NO200701161
56+
#defineCATALOG_VERSION_NO200701201
5757

5858
#endif

‎src/include/catalog/pg_aggregate.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
99
* Portions Copyright (c) 1994, Regents of the University of California
1010
*
11-
* $PostgreSQL: pgsql/src/include/catalog/pg_aggregate.h,v 1.59 2007/01/05 22:19:52 momjian Exp $
11+
* $PostgreSQL: pgsql/src/include/catalog/pg_aggregate.h,v 1.60 2007/01/20 09:27:19 petere Exp $
1212
*
1313
* NOTES
1414
* the genbki.sh script reads this file and generates .bki
@@ -221,6 +221,9 @@ DATA(insert ( 2241 int8or -020_null_ ));
221221
DATA(insert (2242bitand-01560_null_ ));
222222
DATA(insert (2243bitor-01560_null_ ));
223223

224+
/* xml */
225+
DATA(insert (2901xmlconcat2-0142_null_ ));
226+
224227
/*
225228
* prototypes for functions in pg_aggregate.c
226229
*/

‎src/include/catalog/pg_proc.h

Lines changed: 5 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/catalog/pg_proc.h,v 1.437 2007/01/16 21:41:13 neilc Exp $
10+
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.438 2007/01/20 09:27:19 petere Exp $
1111
*
1212
* NOTES
1313
* The script catalog/genbki.sh reads this file and generates .bki
@@ -4037,6 +4037,10 @@ DATA(insert OID = 2898 ( xml_recv PGNSP PGUID 12 f f t f s 1 142 "2281" _nu
40374037
DESCR("I/O");
40384038
DATA(insertOID=2899 (xml_sendPGNSPPGUID12fftfs117"142"_null__null__null_xml_send-_null_ ));
40394039
DESCR("I/O");
4040+
DATA(insertOID=2900 (xmlconcat2PGNSPPGUID12ffffi2142"142 142"_null__null__null_xmlconcat2-_null_ ));
4041+
DESCR("aggregate transition function");
4042+
DATA(insertOID=2901 (xmlaggPGNSPPGUID12tfffi1142"142"_null__null__null_aggregate_dummy-_null_ ));
4043+
DESCR("concatenate XML values");
40404044

40414045

40424046
/*

‎src/include/utils/xml.h

Lines changed: 3 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.11 2007/01/19 16:58:46 petere Exp $
10+
* $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.12 2007/01/20 09:27:20 petere Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -30,9 +30,11 @@ extern Datum xml_out(PG_FUNCTION_ARGS);
3030
externDatumxml_recv(PG_FUNCTION_ARGS);
3131
externDatumxml_send(PG_FUNCTION_ARGS);
3232
externDatumxmlcomment(PG_FUNCTION_ARGS);
33+
externDatumxmlconcat2(PG_FUNCTION_ARGS);
3334
externDatumtexttoxml(PG_FUNCTION_ARGS);
3435
externDatumxmlvalidate(PG_FUNCTION_ARGS);
3536

37+
externxmltype*xmlconcat(List*args);
3638
externxmltype*xmlelement(XmlExprState*xmlExpr,ExprContext*econtext);
3739
externxmltype*xmlparse(text*data,boolis_doc,boolpreserve_whitespace);
3840
externxmltype*xmlpi(char*target,text*arg,boolarg_is_null,bool*result_is_null);

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

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ ERROR: argument of XMLCONCAT must be type xml, not type integer
5555
SELECT xmlconcat('bad', '<syntax');
5656
ERROR: invalid XML content
5757
DETAIL: Expected '>'
58+
SELECT xmlconcat('<foo/>', NULL, '<?xml version="1.1" standalone="no"?><bar/>');
59+
xmlconcat
60+
---------------------------------------------------
61+
<?xml version="1.1" standalone="no"?><foo/><bar/>
62+
(1 row)
63+
5864
SELECT xmlelement(name element,
5965
xmlattributes (1 as one, 'deuce' as two),
6066
'content');
@@ -190,7 +196,7 @@ SELECT xmlpi(name foo, ' bar');
190196
(1 row)
191197

192198
SELECT xmlroot(xml '<foo/>', version no value, standalone no value);
193-
xmlroot
199+
xmlroot
194200
---------
195201
<foo/>
196202

@@ -268,6 +274,24 @@ SELECT xml 'abc' IS NOT DOCUMENT;
268274
SELECT '<>' IS NOT DOCUMENT;
269275
ERROR: invalid XML content
270276
DETAIL: Element name not found
277+
SELECT xmlagg(data) FROM xmltest;
278+
xmlagg
279+
--------------------------------------
280+
<value>one</value><value>two</value>
281+
(1 row)
282+
283+
SELECT xmlagg(data) FROM xmltest WHERE id > 10;
284+
xmlagg
285+
--------
286+
287+
(1 row)
288+
289+
SELECT xmlelement(name employees, xmlagg(xmlelement(name name, name))) FROM emp;
290+
xmlelement
291+
--------------------------------------------------------------------------------------------------------------------------------
292+
<employees><name>sharon</name><name>sam</name><name>bill</name><name>jeff</name><name>cim</name><name>linda</name></employees>
293+
(1 row)
294+
271295
-- Check mapping SQL identifier to XML name
272296
SELECT xmlpi(name ":::_xml_abc135.%-&_");
273297
xmlpi

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ SELECT xmlconcat(1, 2);
3333
ERROR: argument of XMLCONCAT must be type xml, not type integer
3434
SELECT xmlconcat('bad', '<syntax');
3535
ERROR: no XML support in this installation
36+
SELECT xmlconcat('<foo/>', NULL, '<?xml version="1.1" standalone="no"?><bar/>');
37+
ERROR: no XML support in this installation
3638
SELECT xmlelement(name element,
3739
xmlattributes (1 as one, 'deuce' as two),
3840
'content');
@@ -123,6 +125,20 @@ SELECT xml 'abc' IS NOT DOCUMENT;
123125
ERROR: no XML support in this installation
124126
SELECT '<>' IS NOT DOCUMENT;
125127
ERROR: no XML support in this installation
128+
SELECT xmlagg(data) FROM xmltest;
129+
xmlagg
130+
--------
131+
132+
(1 row)
133+
134+
SELECT xmlagg(data) FROM xmltest WHERE id > 10;
135+
xmlagg
136+
--------
137+
138+
(1 row)
139+
140+
SELECT xmlelement(name employees, xmlagg(xmlelement(name name, name))) FROM emp;
141+
ERROR: no XML support in this installation
126142
-- Check mapping SQL identifier to XML name
127143
SELECT xmlpi(name ":::_xml_abc135.%-&_");
128144
ERROR: no XML support in this installation

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ SELECT xmlconcat(xmlcomment('hello'),
2424
SELECT xmlconcat('hello','you');
2525
SELECT xmlconcat(1,2);
2626
SELECT xmlconcat('bad','<syntax');
27+
SELECT xmlconcat('<foo/>',NULL,'<?xml version="1.1" standalone="no"?><bar/>');
2728

2829

2930
SELECT xmlelement(name element,
@@ -97,6 +98,11 @@ SELECT xml 'abc' IS NOT DOCUMENT;
9798
SELECT'<>' IS NOT DOCUMENT;
9899

99100

101+
SELECT xmlagg(data)FROM xmltest;
102+
SELECT xmlagg(data)FROM xmltestWHERE id>10;
103+
SELECT xmlelement(name employees, xmlagg(xmlelement(name name, name)))FROM emp;
104+
105+
100106
-- Check mapping SQL identifier to XML name
101107

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

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp