[Bucardo-general] Sync of fields with user-function as default, Sync of XML fields
Franz Dürr
info at fduerr.de
Mon Sep 6 14:15:45 UTC 2010
On 02.09.2010 21:00, Greg Sabino Mullane wrote:
> On Thu, Sep 02, 2010 at 06:47:28PM +0200, Franz Dürr wrote:
>>>> Does DBD ignore user defined operators or am i using the wrong schema?
>>>> I'm stuck at this point and would greatly appreciate any help
>>> As far as I know, that should work. I'd try running some sql at the
>>> command line to see if you can duplicate that error, then ask for
>>> help on #postgresql on irc.freenode.net.
>>>
>> I'd be quite astonished if sync of XML-fields work, as there is no
>> XML-equality operator neither in Pg 8.4.4 nor in 9.0B4 and Bucardo
>> doesn't provide one either
> No, I meant your custom casting solution should work. DBD is agnostic
> about user defined operators. As long as they are in your search path
> it should all just work.
>
Just for the records:
I managed to solve the 'DBD::Pg::st execute failed: ERROR: could not
identify an equality operator for type xml' - problem (thanks to Tom
Lane for pointing me into the right direction): Bucardo compares
complete records for equality, and the underlying PostgreSQL function
'record_eq()' doesn't care about user-defined operators. To let it work
with XML-fields, you have to create an operator class for XML:
---------------------------
CREATE OR REPLACE FUNCTION pg_catalog.xml_ops_lt(XML,XML) RETURNS BOOLEAN AS
'SELECT CAST($1 AS TEXT) < CAST($2 AS TEXT);' LANGUAGE SQL IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION pg_catalog.xml_ops_le(XML,XML) RETURNS BOOLEAN AS
'SELECT CAST($1 AS TEXT) <= CAST($2 AS TEXT);' LANGUAGE SQL IMMUTABLE
STRICT;
CREATE OR REPLACE FUNCTION pg_catalog.xml_ops_eq(XML,XML) RETURNS BOOLEAN AS
'SELECT CAST($1 AS TEXT) = CAST($2 AS TEXT);' LANGUAGE SQL IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION pg_catalog.xml_ops_ge(XML,XML) RETURNS BOOLEAN AS
'SELECT CAST($1 AS TEXT) >= CAST($2 AS TEXT);' LANGUAGE SQL IMMUTABLE
STRICT;
CREATE OR REPLACE FUNCTION pg_catalog.xml_ops_gt(XML,XML) RETURNS BOOLEAN AS
'SELECT CAST($1 AS TEXT) > CAST($2 AS TEXT);' LANGUAGE SQL IMMUTABLE STRICT;
CREATE OPERATOR pg_catalog.< (
leftarg = xml, rightarg = xml, procedure = pg_catalog.xml_ops_lt,
commutator = > , negator = >= ,
restrict = scalarltsel, join = scalarltjoinsel
);
CREATE OPERATOR pg_catalog.<= (
leftarg = xml, rightarg = xml, procedure = pg_catalog.xml_ops_le,
commutator = >= , negator = > ,
restrict = scalarltsel, join = scalarltjoinsel
);
CREATE OPERATOR pg_catalog.= (
leftarg = xml, rightarg = xml, procedure = pg_catalog.xml_ops_eq,
commutator = = , -- no negator
restrict = eqsel, join = eqjoinsel
);
CREATE OPERATOR pg_catalog.>= (
leftarg = xml, rightarg = xml, procedure = pg_catalog.xml_ops_ge,
commutator = <= , negator = < ,
restrict = scalargtsel, join = scalargtjoinsel
);
CREATE OPERATOR pg_catalog.> (
leftarg = xml, rightarg = xml, procedure = pg_catalog.xml_ops_gt,
commutator = < , negator = <= ,
restrict = scalargtsel, join = scalargtjoinsel
);
CREATE OR REPLACE FUNCTION pg_catalog.xml_ops_cmp(XML,XML) RETURNS
INTEGER AS
'SELECT CASE CAST($1 AS TEXT)=CAST($2 AS TEXT) WHEN true THEN 0 ELSE
CASE CAST($1 AS TEXT)<CAST($2 AS TEXT) WHEN true THEN -1 ELSE 1 END
END;' LANGUAGE SQL IMMUTABLE STRICT;
CREATE OPERATOR CLASS pg_catalog.xml_ops DEFAULT FOR TYPE XML USING BTREE AS
OPERATOR 1 < ,
OPERATOR 2 <= ,
OPERATOR 3 = ,
OPERATOR 4 >= ,
OPERATOR 5 > ,
FUNCTION 1 pg_catalog.xml_ops_cmp(XML,XML);
---------------------------
Please note that this operator class is not for general usage like
indexing (there's hardly any sense in ordering XML - trees).
I also have to admit, that I didn't dive into the restriction parameter,
just copied them from tutorial/complex.source, so if you know better,
tell me please!
Another thing that gave me errors during syncs was that user 'bucardo'
doesn't have the public-schema in it's search_path. (I call functions
from schema public in my table constraints)
'ALTER USER bucardo SET search_path = bucardo,public;'
fixed that ok. I just wonder, why bucardo.schema sets bucardo's search
path to 'bucardo' only, as 'public' should normally always be in the
search_path.
Thanks again, Greg, for your great work and support
fd
More information about the Bucardo-general
mailing list