How to create an index on an XML column in PostgreSQL with an xpath expression?

Khorkrak

I'm running into this error when attempting to create a btree index on an XML data type column that uses an xpath expression on AuroraDB - PostgreSQL 9.6:

ERROR:  could not identify a comparison function for type xml
SQL state: 42883

This 2009 thread without a clear resolution is the only one I've found discussing this error message in regards to creating an xpath based index for a much earlier version of PostgreSQL: https://www.postgresql-archive.org/Slow-select-times-on-select-with-xpath-td2074839.html

In my case I do also need to specify namespaces as well and the original poster in that thread cast the result of the xpath expression to text[] which does get by the error for me too - but why is that even needed? I also don't see PostgreSQL ever using my index even when I have thousands of rows to go through.

So I tried out a simpler case and the error still occurs - please shed some light as to why if you could:

CREATE TABLE test
(
    id integer NOT NULL,
    xml_data xml NOT NULL,
    CONSTRAINT test_pkey PRIMARY KEY (id)
)
WITH (
    OIDS = FALSE
)
TABLESPACE pg_default;



CREATE INDEX test_idx
    ON test USING btree 
    (xpath('/book/title', xml_data))

and the resulting message is:

ERROR:  could not identify a comparison function for type xml
SQL state: 42883

The database encoding is UTF8. The Collation and Character Type are en_US.UTF-8.

Some sample insert statements too:

insert into source_data.test(id, xml_data) 
values(1, XMLPARSE (DOCUMENT '<?xml version="1.0"?><book><title>Manual</title><chapter>1</chapter><chapter>2</chapter></book>'))

insert into source_data.test(id, xml_data) 
values(2, XMLPARSE (DOCUMENT '<?xml version="1.0"?><book><title>Apropos</title><chapter>1</chapter><chapter>2</chapter></book>'))
Markus

Your getting this error because the XML data type does not provide any comparison operators, hence you can't create an index on the result of xpath(), because it returns an array of XML values.

Therefore you need to cast the XPath expression to a text array when creating the index:

CREATE INDEX test_idx
ON test USING BTREE 
    (cast(xpath('/book/title', xml_data) as text[])) ;

This index then gets used when querying the table:

EXPLAIN ANALYZE
SELECT * FROM test where
cast(xpath('/book/title', xml_data) as text[]) = '{<title>Apropos</title>}';

gives

                                                    QUERY PLAN                                                     
-------------------------------------------------------------------------------------------------------------------
Index Scan using test_idx on test  (cost=0.13..8.15 rows=1 width=36) (actual time=0.034..0.038 rows=1 loops=1)
    Index Cond: ((xpath('/book/title'::text, xml_data, '{}'::text[]))::text[] = '{<title>Apropos</title>}'::text[])
Planning time: 0.168 ms
Execution time: 0.073 ms (4 rows)

This works the same when using text():

CREATE INDEX test_idx
ON test USING BTREE 
    (cast(xpath('/book/title/text()', xml_data) as text[])) ;

explain analyze select * from test where
cast(xpath('/book/title/text()', xml_data) as text[]) = '{Apropos}';

gives

                                                   QUERY PLAN                                                   
----------------------------------------------------------------------------------------------------------------
 Index Scan using test_idx on test  (cost=0.13..8.15 rows=1 width=36) (actual time=0.034..0.038 rows=1 loops=1)
   Index Cond: ((xpath('/book/title/text()'::text, xml_data, '{}'::text[]))::text[] = '{Apropos}'::text[])
 Planning time: 0.166 ms
 Execution time: 0.076 ms
(4 rows)

Note that I forced the use of the index via the following command, as I only had 4 rows in the test table I created.

SET enable_seqscan TO off;

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How to create a Gin index on a geometry column in Postgresql?

How to create multi-column index with column expression(NLSSORT)?

Create combined index for JSONB column in PostgreSQL

odoo, how to create a correct xpath expression

How do I create an index in PostgreSQL on an expression that uses the date_trunc function?

How to query XML column in Postgresql?

How to query an XML column in postgresql?

How to create an arithmetic expression with lenght of items in each row of a column using PostgreSQL

How to create an Index on a boolean column

"Retreat" in XML with Xpath expression

XPath expression on xml file

How to create ruby test to ensure that created postgresql index for specific column is used/covered

Xml Xpath Expression for Nested XML

How to set array index in a XPATH expression in python lxml package

How to create a spatial index on a PostgreSQL GEOMETRY field?

How to create index in postgresql for regexp_matches?

How to use clause GROUP BY xml column in postgresql?

How to create array column with UNNEST and JOIN in PostgreSQL?

How to create a column that increments in steps of 4 in Postgresql

Create XML with XPATH + SQL

How to create an index column with groupby in pandas

How to create a UDF to find index in an array column

Pandas DataFrame: How to Create Multi Column Index

How to create a Column expression from collection of column names?

PostgreSQL create index on JSONB[]

Postgresql Create Unique Index

How to write the xpath expression?

How to read this xpath expression?

Multicolumn index with expression (PostgreSQL and Rails)

TOP Ranking

  1. 1

    Failed to listen on localhost:8000 (reason: Cannot assign requested address)

  2. 2

    Loopback Error: connect ECONNREFUSED 127.0.0.1:3306 (MAMP)

  3. 3

    How to import an asset in swift using Bundle.main.path() in a react-native native module

  4. 4

    pump.io port in URL

  5. 5

    Compiler error CS0246 (type or namespace not found) on using Ninject in ASP.NET vNext

  6. 6

    BigQuery - concatenate ignoring NULL

  7. 7

    ngClass error (Can't bind ngClass since it isn't a known property of div) in Angular 11.0.3

  8. 8

    ggplotly no applicable method for 'plotly_build' applied to an object of class "NULL" if statements

  9. 9

    Spring Boot JPA PostgreSQL Web App - Internal Authentication Error

  10. 10

    How to remove the extra space from right in a webview?

  11. 11

    java.lang.NullPointerException: Cannot read the array length because "<local3>" is null

  12. 12

    Jquery different data trapped from direct mousedown event and simulation via $(this).trigger('mousedown');

  13. 13

    flutter: dropdown item programmatically unselect problem

  14. 14

    How to use merge windows unallocated space into Ubuntu using GParted?

  15. 15

    Change dd-mm-yyyy date format of dataframe date column to yyyy-mm-dd

  16. 16

    Nuget add packages gives access denied errors

  17. 17

    Svchost high CPU from Microsoft.BingWeather app errors

  18. 18

    Can't pre-populate phone number and message body in SMS link on iPhones when SMS app is not running in the background

  19. 19

    12.04.3--- Dconf Editor won't show com>canonical>unity option

  20. 20

    Any way to remove trailing whitespace *FOR EDITED* lines in Eclipse [for Java]?

  21. 21

    maven-jaxb2-plugin cannot generate classes due to two declarations cause a collision in ObjectFactory class

HotTag

Archive