!45 add xml data type and test case

Merge pull request !45 from liang/master
This commit is contained in:
opengauss-bot
2020-07-23 19:44:35 +08:00
committed by Gitee
5 changed files with 47 additions and 115 deletions

View File

@ -472,6 +472,7 @@ Compilation log: **make_compile.log**
export PATH=$GAUSSHOME/bin:$GCC_PATH/gcc/bin:$PATH
```
if you want to use xml data type,you also need to export LD_LIBRARY_PATH=$BINARYLIBS/dependency/***/libobs/comm/lib:$LD_LIBRARY_PATH
For example, on CENTOS X86-64 platform, binarylibs directory is placed as the sibling directory of openGauss-server directory.
The following command can be executed under openGauss-server directory.
@ -515,6 +516,7 @@ Compilation log: **make_compile.log**
> 4. If **binarylibs** is moved to **openGauss-server** or a soft link to **binarylibs** is created in **openGauss-server**, you do not need to specify the **--3rd** parameter. However, if you do so, please note that the file is easy to be deleted by the `git clean` command.
> 5. To build with mysql_fdw, add **--enable-mysql-fdw** when configure. Note that before build mysql_fdw, MariaDB's C client library is needed.
> 6. To build with oracle_fdw, add **--enable-oracle-fdw** when configure. Note that before build oracle_fdw, Oracle's C client library is needed.
> 7. To build with xml data type, add **--with-libxml** when configure. If this error occurs "configure: error: library 'xml2' (version >= 2.6.23) is required for XML support", you can fix it with command "yum install -y libxml2-devel".
4. Run the following commands to compile openGauss:

View File

@ -826,7 +826,7 @@ bool IsTypeInBlacklist(Oid typoid)
switch (typoid) {
case LINEOID:
case XMLOID:
// case XMLOID:
case PGNODETREEOID:
isblack = true;
break;

View File

@ -1421,12 +1421,12 @@ void xml_ereport(PgXmlErrorContext* errcxt, int level, int sqlcode, const char*
/*
* Error handler for libxml errors and warnings
*/
static void xml_errorHandler(void* data, xmlErrorPtr error)
static void xml_error_handler(void* data, xmlErrorPtr error)
{
PgXmlErrorContext* xml_errcxt = (PgXmlErrorContext*)data;
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr)error->ctxt;
xmlParserInputPtr input = (ctxt != NULL) ? ctxt->input : NULL;
xmlNodePtr node = error->node;
xmlNodePtr node = (xmlNodePtr)error->node;
const xmlChar* name = (node != NULL && node->type == XML_ELEMENT_NODE) ? node->name : NULL;
int domain = error->domain;
int level = error->level;
@ -1915,7 +1915,7 @@ char* map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings)
if (writer == NULL || xml_errcxt->err_occurred) {
xml_ereport(xml_errcxt, ERROR, ERRCODE_OUT_OF_MEMORY, "could not allocate xmlTextWriter");
}
if (xmlbinary == XMLBINARY_BASE64) {
if (u_sess->attr.attr_common.xmlbinary == XMLBINARY_BASE64) {
xmlTextWriterWriteBase64(writer, VARDATA_ANY(b_str), 0, VARSIZE_ANY_EXHDR(b_str));
} else {
xmlTextWriterWriteBinHex(writer, VARDATA_ANY(b_str), 0, VARSIZE_ANY_EXHDR(b_str));

View File

@ -1,3 +1,4 @@
\set VERBOSITY terse
CREATE TABLE xmltest (
id int,
data xml
@ -5,12 +6,7 @@ CREATE TABLE xmltest (
INSERT INTO xmltest VALUES (1, '<value>one</value>');
INSERT INTO xmltest VALUES (2, '<value>two</value>');
INSERT INTO xmltest VALUES (3, '<wrong');
ERROR: invalid XML content
LINE 1: INSERT INTO xmltest VALUES (3, '<wrong');
^
DETAIL: line 1: Couldn't find end of Start Tag wrong line 1
<wrong
^
ERROR: invalid XML content at character 32
SELECT * FROM xmltest;
id | data
----+--------------------
@ -55,16 +51,9 @@ SELECT xmlconcat('hello', 'you');
(1 row)
SELECT xmlconcat(1, 2);
ERROR: argument of XMLCONCAT must be type xml, not type integer
LINE 1: SELECT xmlconcat(1, 2);
^
ERROR: argument of XMLCONCAT must be type xml, not type integer at character 18
SELECT xmlconcat('bad', '<syntax');
ERROR: invalid XML content
LINE 1: SELECT xmlconcat('bad', '<syntax');
^
DETAIL: line 1: Couldn't find end of Start Tag syntax line 1
<syntax
^
ERROR: invalid XML content at character 25
SELECT xmlconcat('<foo/>', NULL, '<?xml version="1.1" standalone="no"?><bar/>');
xmlconcat
--------------
@ -99,16 +88,21 @@ SELECT xmlelement(name element,
SELECT xmlelement(name element,
xmlattributes ('unnamed and wrong'));
ERROR: unnamed XML attribute value must be a column reference
LINE 2: xmlattributes ('unnamed and wrong'));
^
ERROR: unnamed XML attribute value must be a column reference at character 66
SELECT xmlelement(name element, xmlelement(name nested, 'stuff'));
xmlelement
-------------------------------------------
<element><nested>stuff</nested></element>
(1 row)
SELECT xmlelement(name employee, xmlforest(name, age, salary as pay)) FROM emp;
CREATE TABLE xml_emp (name varchar(12),age int,salary int);
INSERT INTO xml_emp VALUES ('sharon',25,1000);
INSERT INTO xml_emp VALUES ('sam',30,2000);
INSERT INTO xml_emp VALUES ('bill',20,1000);
INSERT INTO xml_emp VALUES ('jeff',23,600);
INSERT INTO xml_emp VALUES ('cim',30,400);
INSERT INTO xml_emp VALUES ('linda',19,100);
SELECT xmlelement(name employee, xmlforest(name, age, salary as pay)) FROM xml_emp;
xmlelement
----------------------------------------------------------------------
<employee><name>sharon</name><age>25</age><pay>1000</pay></employee>
@ -120,9 +114,7 @@ SELECT xmlelement(name employee, xmlforest(name, age, salary as pay)) FROM emp;
(6 rows)
SELECT xmlelement(name duplicate, xmlattributes(1 as a, 2 as b, 3 as a));
ERROR: XML attribute name "a" appears more than once
LINE 1: ...ment(name duplicate, xmlattributes(1 as a, 2 as b, 3 as a));
^
ERROR: XML attribute name "a" appears more than once at character 65
SELECT xmlelement(name num, 37);
xmlelement
---------------
@ -186,8 +178,7 @@ SELECT xmlelement(name foo, xmlattributes('2009-04-09 00:24:37'::timestamp as ba
(1 row)
SELECT xmlelement(name foo, xmlattributes('infinity'::timestamp as bar));
ERROR: timestamp out of range
DETAIL: XML does not support infinite timestamp values.
ERROR: time_stamp out of range
SELECT xmlelement(name foo, xmlattributes('<>&"''' as funny, xml 'b<a/>r' as funnier));
xmlelement
------------------------------------------------------------
@ -208,20 +199,8 @@ SELECT xmlparse(content '<abc>x</abc>');
SELECT xmlparse(content '<invalidentity>&</invalidentity>');
ERROR: invalid XML content
DETAIL: line 1: xmlParseEntityRef: no name
<invalidentity>&</invalidentity>
^
line 1: chunk is not well balanced
<invalidentity>&</invalidentity>
^
SELECT xmlparse(content '<undefinedentity>&idontexist;</undefinedentity>');
ERROR: invalid XML content
DETAIL: line 1: Entity 'idontexist' not defined
<undefinedentity>&idontexist;</undefinedentity>
^
line 1: chunk is not well balanced
<undefinedentity>&idontexist;</undefinedentity>
^
SELECT xmlparse(content '<invalidns xmlns=''&lt;''/>');
xmlparse
---------------------------
@ -236,15 +215,6 @@ SELECT xmlparse(content '<relativens xmlns=''relative''/>');
SELECT xmlparse(content '<twoerrors>&idontexist;</unbalanced>');
ERROR: invalid XML content
DETAIL: line 1: Entity 'idontexist' not defined
<twoerrors>&idontexist;</unbalanced>
^
line 1: Opening and ending tag mismatch: twoerrors line 1 and unbalanced
<twoerrors>&idontexist;</unbalanced>
^
line 1: chunk is not well balanced
<twoerrors>&idontexist;</unbalanced>
^
SELECT xmlparse(content '<nosuchprefix:tag/>');
xmlparse
---------------------
@ -253,9 +223,6 @@ SELECT xmlparse(content '<nosuchprefix:tag/>');
SELECT xmlparse(document 'abc');
ERROR: invalid XML document
DETAIL: line 1: Start tag expected, '<' not found
abc
^
SELECT xmlparse(document '<abc>x</abc>');
xmlparse
--------------
@ -264,20 +231,8 @@ SELECT xmlparse(document '<abc>x</abc>');
SELECT xmlparse(document '<invalidentity>&</abc>');
ERROR: invalid XML document
DETAIL: line 1: xmlParseEntityRef: no name
<invalidentity>&</abc>
^
line 1: Opening and ending tag mismatch: invalidentity line 1 and abc
<invalidentity>&</abc>
^
SELECT xmlparse(document '<undefinedentity>&idontexist;</abc>');
ERROR: invalid XML document
DETAIL: line 1: Entity 'idontexist' not defined
<undefinedentity>&idontexist;</abc>
^
line 1: Opening and ending tag mismatch: undefinedentity line 1 and abc
<undefinedentity>&idontexist;</abc>
^
SELECT xmlparse(document '<invalidns xmlns=''&lt;''/>');
xmlparse
---------------------------
@ -292,12 +247,6 @@ SELECT xmlparse(document '<relativens xmlns=''relative''/>');
SELECT xmlparse(document '<twoerrors>&idontexist;</unbalanced>');
ERROR: invalid XML document
DETAIL: line 1: Entity 'idontexist' not defined
<twoerrors>&idontexist;</unbalanced>
^
line 1: Opening and ending tag mismatch: twoerrors line 1 and unbalanced
<twoerrors>&idontexist;</unbalanced>
^
SELECT xmlparse(document '<nosuchprefix:tag/>');
xmlparse
---------------------
@ -312,7 +261,6 @@ SELECT xmlpi(name foo);
SELECT xmlpi(name xml);
ERROR: invalid XML processing instruction
DETAIL: XML processing instruction target name cannot be "xml".
SELECT xmlpi(name xmlstuff);
xmlpi
--------------
@ -327,7 +275,6 @@ SELECT xmlpi(name foo, 'bar');
SELECT xmlpi(name foo, 'in?>valid');
ERROR: invalid XML processing instruction
DETAIL: XML processing instruction cannot contain "?>".
SELECT xmlpi(name foo, null);
xmlpi
-------
@ -336,7 +283,6 @@ SELECT xmlpi(name foo, null);
SELECT xmlpi(name xml, null);
ERROR: invalid XML processing instruction
DETAIL: XML processing instruction target name cannot be "xml".
SELECT xmlpi(name xmlstuff, null);
xmlpi
-------
@ -463,12 +409,7 @@ SELECT xml 'abc' IS NOT DOCUMENT;
(1 row)
SELECT '<>' IS NOT DOCUMENT;
ERROR: invalid XML content
LINE 1: SELECT '<>' IS NOT DOCUMENT;
^
DETAIL: line 1: StartTag: invalid element name
<>
^
ERROR: invalid XML content at character 8
SELECT xmlagg(data) FROM xmltest;
xmlagg
--------------------------------------
@ -481,7 +422,7 @@ SELECT xmlagg(data) FROM xmltest WHERE id > 10;
(1 row)
SELECT xmlelement(name employees, xmlagg(xmlelement(name name, name))) FROM emp;
SELECT xmlelement(name employees, xmlagg(xmlelement(name name, name))) FROM xml_emp;
xmlelement
--------------------------------------------------------------------------------------------------------------------------------
<employees><name>sharon</name><name>sam</name><name>bill</name><name>jeff</name><name>cim</name><name>linda</name></employees>
@ -509,12 +450,7 @@ EXECUTE foo ('<bar/>');
(1 row)
EXECUTE foo ('bad');
ERROR: invalid XML document
LINE 1: EXECUTE foo ('bad');
^
DETAIL: line 1: Start tag expected, '<' not found
bad
^
ERROR: invalid XML document at character 14
SET XML OPTION CONTENT;
EXECUTE foo ('<bar/>');
xmlconcat
@ -532,7 +468,7 @@ EXECUTE foo ('good');
CREATE VIEW xmlview1 AS SELECT xmlcomment('test');
CREATE VIEW xmlview2 AS SELECT xmlconcat('hello', 'you');
CREATE VIEW xmlview3 AS SELECT xmlelement(name element, xmlattributes (1 as ":one:", 'deuce' as two), 'content&');
CREATE VIEW xmlview4 AS SELECT xmlelement(name employee, xmlforest(name, age, salary as pay)) FROM emp;
CREATE VIEW xmlview4 AS SELECT xmlelement(name employee, xmlforest(name, age, salary as pay)) FROM xml_emp;
CREATE VIEW xmlview5 AS SELECT xmlparse(content '<abc>x</abc>');
CREATE VIEW xmlview6 AS SELECT xmlpi(name foo, 'bar');
CREATE VIEW xmlview7 AS SELECT xmlroot(xml '<foo/>', version no value, standalone yes);
@ -541,11 +477,11 @@ CREATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' as text);
SELECT table_name, view_definition FROM information_schema.views
WHERE table_name LIKE 'xmlview%' ORDER BY 1;
table_name | view_definition
------------+----------------------------------------------------------------------------------------------------------------------------
------------+--------------------------------------------------------------------------------------------------------------------------------------------
xmlview1 | SELECT xmlcomment('test'::text) AS xmlcomment;
xmlview2 | SELECT XMLCONCAT('hello'::xml, 'you'::xml) AS "xmlconcat";
xmlview3 | SELECT XMLELEMENT(NAME element, XMLATTRIBUTES(1 AS ":one:", 'deuce' AS two), 'content&') AS "xmlelement";
xmlview4 | SELECT XMLELEMENT(NAME employee, XMLFOREST(emp.name AS name, emp.age AS age, emp.salary AS pay)) AS "xmlelement" FROM emp;
xmlview4 | SELECT XMLELEMENT(NAME employee, XMLFOREST(xml_emp.name AS name, xml_emp.age AS age, xml_emp.salary AS pay)) AS "xmlelement" FROM xml_emp;
xmlview5 | SELECT XMLPARSE(CONTENT '<abc>x</abc>'::text STRIP WHITESPACE) AS "xmlparse";
xmlview6 | SELECT XMLPI(NAME foo, 'bar'::text) AS "xmlpi";
xmlview7 | SELECT XMLROOT('<foo/>'::xml, VERSION NO VALUE, STANDALONE YES) AS "xmlroot";
@ -568,9 +504,8 @@ SELECT xpath(NULL, NULL) IS NULL FROM xmltest;
t
(2 rows)
SELECT xpath('', '<!-- error -->');
ERROR: empty XPath expression
CONTEXT: SQL function "xpath" statement 1
SELECT xpath(' ', '<!-- error -->');
ERROR: could not parse XML document
SELECT xpath('//text()', '<local:data xmlns:local="http://127.0.0.1"><local:piece id="1">number one</local:piece><local:piece id="2" /></local:data>');
xpath
----------------
@ -583,21 +518,6 @@ SELECT xpath('//loc:piece/@id', '<local:data xmlns:local="http://127.0.0.1"><loc
{1,2}
(1 row)
SELECT xpath('//loc:piece', '<local:data xmlns:local="http://127.0.0.1"><local:piece id="1">number one</local:piece><local:piece id="2" /></local:data>', ARRAY[ARRAY['loc', 'http://127.0.0.1']]);
xpath
------------------------------------------------------------------------------------------------------------------------------------------------
{"<local:piece xmlns:local=\"http://127.0.0.1\" id=\"1\">number one</local:piece>","<local:piece xmlns:local=\"http://127.0.0.1\" id=\"2\"/>"}
(1 row)
SELECT xpath('//loc:piece', '<local:data xmlns:local="http://127.0.0.1" xmlns="http://127.0.0.2"><local:piece id="1"><internal>number one</internal><internal2/></local:piece><local:piece id="2" /></local:data>', ARRAY[ARRAY['loc', 'http://127.0.0.1']]);
xpath
--------------------------------------------------------------------------------------
{"<local:piece xmlns:local=\"http://127.0.0.1\" xmlns=\"http://127.0.0.2\" id=\"1\">+
<internal>number one</internal> +
<internal2/> +
</local:piece>","<local:piece xmlns:local=\"http://127.0.0.1\" id=\"2\"/>"}
(1 row)
SELECT xpath('//b', '<a>one <b>two</b> three <b>etc</b></a>');
xpath
-------------------------
@ -898,14 +818,18 @@ ERROR: could not parse XML document
DETAIL: line 1: Namespace prefix nosuchprefix on tag is not defined
<nosuchprefix:tag/>
^
CONTEXT: SQL function "xpath" statement 1
CONTEXT: referenced column: xpath
SQL function "xpath" statement 1
referenced column: xpath
-- XPath deprecates relative namespaces, but they're not supposed to
-- throw an error, only a warning.
SELECT xpath('/*', '<relativens xmlns=''relative''/>');
WARNING: line 1: xmlns: URI relative is not absolute
<relativens xmlns='relative'/>
^
CONTEXT: SQL function "xpath" statement 1
CONTEXT: referenced column: xpath
SQL function "xpath" statement 1
referenced column: xpath
xpath
--------------------------------------
{"<relativens xmlns=\"relative\"/>"}

View File

@ -1,3 +1,4 @@
\set VERBOSITY terse
CREATE TABLE xmltest (
id int,
data xml
@ -38,8 +39,15 @@ SELECT xmlelement(name element,
xmlattributes ('unnamed and wrong'));
SELECT xmlelement(name element, xmlelement(name nested, 'stuff'));
CREATE TABLE xml_emp (name varchar(12),age int,salary int);
INSERT INTO xml_emp VALUES ('sharon',25,1000);
INSERT INTO xml_emp VALUES ('sam',30,2000);
INSERT INTO xml_emp VALUES ('bill',20,1000);
INSERT INTO xml_emp VALUES ('jeff',23,600);
INSERT INTO xml_emp VALUES ('cim',30,400);
INSERT INTO xml_emp VALUES ('linda',19,100);
SELECT xmlelement(name employee, xmlforest(name, age, salary as pay)) FROM emp;
SELECT xmlelement(name employee, xmlforest(name, age, salary as pay)) FROM xml_emp;
SELECT xmlelement(name duplicate, xmlattributes(1 as a, 2 as b, 3 as a));
@ -132,7 +140,7 @@ SELECT '<>' IS NOT DOCUMENT;
SELECT xmlagg(data) FROM xmltest;
SELECT xmlagg(data) FROM xmltest WHERE id > 10;
SELECT xmlelement(name employees, xmlagg(xmlelement(name name, name))) FROM emp;
SELECT xmlelement(name employees, xmlagg(xmlelement(name name, name))) FROM xml_emp;
-- Check mapping SQL identifier to XML name
@ -157,7 +165,7 @@ EXECUTE foo ('good');
CREATE VIEW xmlview1 AS SELECT xmlcomment('test');
CREATE VIEW xmlview2 AS SELECT xmlconcat('hello', 'you');
CREATE VIEW xmlview3 AS SELECT xmlelement(name element, xmlattributes (1 as ":one:", 'deuce' as two), 'content&');
CREATE VIEW xmlview4 AS SELECT xmlelement(name employee, xmlforest(name, age, salary as pay)) FROM emp;
CREATE VIEW xmlview4 AS SELECT xmlelement(name employee, xmlforest(name, age, salary as pay)) FROM xml_emp;
CREATE VIEW xmlview5 AS SELECT xmlparse(content '<abc>x</abc>');
CREATE VIEW xmlview6 AS SELECT xmlpi(name foo, 'bar');
CREATE VIEW xmlview7 AS SELECT xmlroot(xml '<foo/>', version no value, standalone yes);
@ -171,11 +179,9 @@ SELECT table_name, view_definition FROM information_schema.views
SELECT xpath('/value', data) FROM xmltest;
SELECT xpath(NULL, NULL) IS NULL FROM xmltest;
SELECT xpath('', '<!-- error -->');
SELECT xpath(' ', '<!-- error -->');
SELECT xpath('//text()', '<local:data xmlns:local="http://127.0.0.1"><local:piece id="1">number one</local:piece><local:piece id="2" /></local:data>');
SELECT xpath('//loc:piece/@id', '<local:data xmlns:local="http://127.0.0.1"><local:piece id="1">number one</local:piece><local:piece id="2" /></local:data>', ARRAY[ARRAY['loc', 'http://127.0.0.1']]);
SELECT xpath('//loc:piece', '<local:data xmlns:local="http://127.0.0.1"><local:piece id="1">number one</local:piece><local:piece id="2" /></local:data>', ARRAY[ARRAY['loc', 'http://127.0.0.1']]);
SELECT xpath('//loc:piece', '<local:data xmlns:local="http://127.0.0.1" xmlns="http://127.0.0.2"><local:piece id="1"><internal>number one</internal><internal2/></local:piece><local:piece id="2" /></local:data>', ARRAY[ARRAY['loc', 'http://127.0.0.1']]);
SELECT xpath('//b', '<a>one <b>two</b> three <b>etc</b></a>');
SELECT xpath('//text()', '<root>&lt;</root>');
SELECT xpath('//@value', '<root value="&lt;"/>');