\pset null '(null)' CREATE SERVER graphdb FOREIGN DATA WRAPPER rdf_fdw OPTIONS ( endpoint 'http://graphdb:7200/repositories/test', update_url 'http://graphdb:7200/repositories/test/statements'); CREATE FOREIGN TABLE ft ( subject rdfnode OPTIONS (variable '?s'), predicate rdfnode OPTIONS (variable '?p'), object rdfnode OPTIONS (variable '?o') ) SERVER graphdb OPTIONS ( log_sparql 'true', sparql 'SELECT * WHERE {?s ?p ?o}', sparql_update_pattern '?s ?p ?o .' ); CREATE USER MAPPING FOR postgres SERVER graphdb OPTIONS (user 'admin', password 'secret'); INSERT INTO ft (subject, predicate, object) VALUES ('', '', '"Westfälische Wilhelms-Universität Münster"@de'); INFO: SPARQL query sent to 'graphdb': INSERT DATA { "Westfälische Wilhelms-Universität Münster"@de }; SELECT * FROM ft WHERE subject = ''; INFO: SPARQL query sent to 'graphdb': SELECT ?s ?p ?o {?s ?p ?o ## rdf_fdw pushdown conditions ## FILTER(?s = ) } INFO: SPARQL returned 1 record. subject | predicate | object -------------------------------+----------------------------------------------+------------------------------------------------ | | "Westfälische Wilhelms-Universität Münster"@de (1 row) UPDATE ft SET object = '"University of Münster"@en' WHERE subject = '' AND predicate = ''; INFO: SPARQL query sent to 'graphdb': SELECT ?s ?p ?o {?s ?p ?o ## rdf_fdw pushdown conditions ## FILTER(?s = ) FILTER(?p = ) } INFO: SPARQL returned 1 record. INFO: SPARQL query sent to 'graphdb': DELETE DATA { "Westfälische Wilhelms-Universität Münster"@de }; INSERT DATA { "University of Münster"@en }; SELECT * FROM ft WHERE subject = ''; INFO: SPARQL query sent to 'graphdb': SELECT ?s ?p ?o {?s ?p ?o ## rdf_fdw pushdown conditions ## FILTER(?s = ) } INFO: SPARQL returned 1 record. subject | predicate | object -------------------------------+----------------------------------------------+---------------------------- | | "University of Münster"@en (1 row) UPDATE ft SET object = '""'::rdfnode WHERE subject = '' AND predicate = ''; INFO: SPARQL query sent to 'graphdb': SELECT ?s ?p ?o {?s ?p ?o ## rdf_fdw pushdown conditions ## FILTER(?s = ) FILTER(?p = ) } INFO: SPARQL returned 1 record. INFO: SPARQL query sent to 'graphdb': DELETE DATA { "University of Münster"@en }; INSERT DATA { "" }; SELECT * FROM ft WHERE subject = ''; INFO: SPARQL query sent to 'graphdb': SELECT ?s ?p ?o {?s ?p ?o ## rdf_fdw pushdown conditions ## FILTER(?s = ) } INFO: SPARQL returned 1 record. subject | predicate | object -------------------------------+----------------------------------------------+-------- | | "" (1 row) UPDATE ft SET object = '🐘'::rdfnode WHERE subject = '' AND predicate = ''; INFO: SPARQL query sent to 'graphdb': SELECT ?s ?p ?o {?s ?p ?o ## rdf_fdw pushdown conditions ## FILTER(?s = ) FILTER(?p = ) } INFO: SPARQL returned 1 record. INFO: SPARQL query sent to 'graphdb': DELETE DATA { "" }; INSERT DATA { "🐘" }; SELECT * FROM ft WHERE subject = ''; INFO: SPARQL query sent to 'graphdb': SELECT ?s ?p ?o {?s ?p ?o ## rdf_fdw pushdown conditions ## FILTER(?s = ) } INFO: SPARQL returned 1 record. subject | predicate | object -------------------------------+----------------------------------------------+-------- | | "🐘" (1 row) /* update using existing column */ UPDATE ft SET object = predicate WHERE subject = '' AND predicate = ''; INFO: SPARQL query sent to 'graphdb': SELECT ?s ?p ?o {?s ?p ?o ## rdf_fdw pushdown conditions ## FILTER(?s = ) FILTER(?p = ) } INFO: SPARQL returned 1 record. INFO: SPARQL query sent to 'graphdb': DELETE DATA { "🐘" }; INSERT DATA { }; SELECT * FROM ft WHERE subject = ''; INFO: SPARQL query sent to 'graphdb': SELECT ?s ?p ?o {?s ?p ?o ## rdf_fdw pushdown conditions ## FILTER(?s = ) } INFO: SPARQL returned 1 record. subject | predicate | object -------------------------------+----------------------------------------------+---------------------------------------------- | | (1 row) /* update literals with quotes */ UPDATE ft SET object = '"\"text with quotes\""'::rdfnode WHERE subject = '' AND predicate = ''; INFO: SPARQL query sent to 'graphdb': SELECT ?s ?p ?o {?s ?p ?o ## rdf_fdw pushdown conditions ## FILTER(?s = ) FILTER(?p = ) } INFO: SPARQL returned 1 record. INFO: SPARQL query sent to 'graphdb': DELETE DATA { }; INSERT DATA { "\"text with quotes\"" }; SELECT * FROM ft WHERE subject = ''; INFO: SPARQL query sent to 'graphdb': SELECT ?s ?p ?o {?s ?p ?o ## rdf_fdw pushdown conditions ## FILTER(?s = ) } INFO: SPARQL returned 1 record. subject | predicate | object -------------------------------+----------------------------------------------+------------------------ | | "\"text with quotes\"" (1 row) /* update literals containing newlines */ UPDATE ft SET object = '"text \n newline"'::rdfnode WHERE subject = '' AND predicate = ''; INFO: SPARQL query sent to 'graphdb': SELECT ?s ?p ?o {?s ?p ?o ## rdf_fdw pushdown conditions ## FILTER(?s = ) FILTER(?p = ) } INFO: SPARQL returned 1 record. INFO: SPARQL query sent to 'graphdb': DELETE DATA { "\"text with quotes\"" }; INSERT DATA { "text \n newline" }; SELECT * FROM ft WHERE subject = ''; INFO: SPARQL query sent to 'graphdb': SELECT ?s ?p ?o {?s ?p ?o ## rdf_fdw pushdown conditions ## FILTER(?s = ) } INFO: SPARQL returned 1 record. subject | predicate | object -------------------------------+----------------------------------------------+----------- | | "text + | | newline" (1 row) /* update to xsd:string literal (graphdb might omit xsd:string datatype) */ UPDATE ft SET object = '"text xsd string"^^'::rdfnode WHERE subject = '' AND predicate = ''; INFO: SPARQL query sent to 'graphdb': SELECT ?s ?p ?o {?s ?p ?o ## rdf_fdw pushdown conditions ## FILTER(?s = ) FILTER(?p = ) } INFO: SPARQL returned 1 record. INFO: SPARQL query sent to 'graphdb': DELETE DATA { "text \n newline" }; INSERT DATA { "text xsd string"^^ }; SELECT * FROM ft WHERE subject = ''; INFO: SPARQL query sent to 'graphdb': SELECT ?s ?p ?o {?s ?p ?o ## rdf_fdw pushdown conditions ## FILTER(?s = ) } INFO: SPARQL returned 1 record. subject | predicate | object -------------------------------+----------------------------------------------+------------------- | | "text xsd string" (1 row) /* update to xsd:int literal */ UPDATE ft SET object = 42::rdfnode WHERE subject = '' AND predicate = ''; INFO: SPARQL query sent to 'graphdb': SELECT ?s ?p ?o {?s ?p ?o ## rdf_fdw pushdown conditions ## FILTER(?s = ) FILTER(?p = ) } INFO: SPARQL returned 1 record. INFO: SPARQL query sent to 'graphdb': DELETE DATA { "text xsd string" }; INSERT DATA { "42"^^ }; SELECT * FROM ft WHERE subject = ''; INFO: SPARQL query sent to 'graphdb': SELECT ?s ?p ?o {?s ?p ?o ## rdf_fdw pushdown conditions ## FILTER(?s = ) } INFO: SPARQL returned 1 record. subject | predicate | object -------------------------------+----------------------------------------------+---------------------------------------------- | | "42"^^ (1 row) /* update to xsd:decimal literal */ UPDATE ft SET object = 42.37::rdfnode WHERE subject = '' AND predicate = ''; INFO: SPARQL query sent to 'graphdb': SELECT ?s ?p ?o {?s ?p ?o ## rdf_fdw pushdown conditions ## FILTER(?s = ) FILTER(?p = ) } INFO: SPARQL returned 1 record. INFO: SPARQL query sent to 'graphdb': DELETE DATA { "42"^^ }; INSERT DATA { "42.37"^^ }; SELECT * FROM ft WHERE subject = ''; INFO: SPARQL query sent to 'graphdb': SELECT ?s ?p ?o {?s ?p ?o ## rdf_fdw pushdown conditions ## FILTER(?s = ) } INFO: SPARQL returned 1 record. subject | predicate | object -------------------------------+----------------------------------------------+----------------------------------------------------- | | "42.37"^^ (1 row) /* update to xsd:long literal */ UPDATE ft SET object = 423712345678911::rdfnode WHERE subject = '' AND predicate = ''; INFO: SPARQL query sent to 'graphdb': SELECT ?s ?p ?o {?s ?p ?o ## rdf_fdw pushdown conditions ## FILTER(?s = ) FILTER(?p = ) } INFO: SPARQL returned 1 record. INFO: SPARQL query sent to 'graphdb': DELETE DATA { "42.37"^^ }; INSERT DATA { "423712345678911"^^ }; SELECT * FROM ft WHERE subject = ''; INFO: SPARQL query sent to 'graphdb': SELECT ?s ?p ?o {?s ?p ?o ## rdf_fdw pushdown conditions ## FILTER(?s = ) } INFO: SPARQL returned 1 record. subject | predicate | object -------------------------------+----------------------------------------------+------------------------------------------------------------ | | "423712345678911"^^ (1 row) /* update with NULL - must fail (after SELECT since FDW must fetch OLD values first) */ UPDATE ft SET object = NULL WHERE subject = '' AND predicate = ''; INFO: SPARQL query sent to 'graphdb': SELECT ?s ?p ?o {?s ?p ?o ## rdf_fdw pushdown conditions ## FILTER(?s = ) FILTER(?p = ) } INFO: SPARQL returned 1 record. ERROR: NULL value in column "object" violates RDF constraint DETAIL: SPARQL variable '?o' cannot be NULL in RDF triple patterns HINT: RDF triples require all components to be non-NULL. Filter NULL values in your query or provide default values. SELECT * FROM ft WHERE subject = ''; INFO: SPARQL query sent to 'graphdb': SELECT ?s ?p ?o {?s ?p ?o ## rdf_fdw pushdown conditions ## FILTER(?s = ) } INFO: SPARQL returned 1 record. subject | predicate | object -------------------------------+----------------------------------------------+------------------------------------------------------------ | | "423712345678911"^^ (1 row) /* update rdfnode with a blank node */ UPDATE ft SET object = sparql.bnode() WHERE subject = '' AND predicate = ''; INFO: SPARQL query sent to 'graphdb': SELECT ?s ?p ?o {?s ?p ?o ## rdf_fdw pushdown conditions ## FILTER(?s = ) FILTER(?p = ) } INFO: SPARQL returned 1 record. ERROR: blank nodes are not allowed in UPDATE operations HINT: Blank nodes are document-local and have no global meaning. Use IRIs instead. /* update with RETURNING */ UPDATE ft SET object = '"Westfälische Wilhelms-Universität Münster"@de' WHERE subject = '' AND predicate = '' RETURNING OLD.subject, OLD.predicate, OLD.object, NEW.subject AS new_subject, NEW.predicate AS new_predicate, NEW.object AS new_object; INFO: SPARQL query sent to 'graphdb': SELECT ?s ?p ?o {?s ?p ?o ## rdf_fdw pushdown conditions ## FILTER(?s = ) FILTER(?p = ) } INFO: SPARQL returned 1 record. INFO: SPARQL query sent to 'graphdb': DELETE DATA { "423712345678911"^^ }; INSERT DATA { "Westfälische Wilhelms-Universität Münster"@de }; subject | predicate | object | new_subject | new_predicate | new_object -------------------------------+----------------------------------------------+------------------------------------------------------------+-------------------------------+----------------------------------------------+------------------------------------------------ | | "423712345678911"^^ | | | "Westfälische Wilhelms-Universität Münster"@de (1 row) /* cleanup */ DELETE FROM ft; INFO: SPARQL query sent to 'graphdb': SELECT ?s ?p ?o {?s ?p ?o} INFO: SPARQL returned 77 records. INFO: SPARQL query sent to 'graphdb': DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; INFO: SPARQL query sent to 'graphdb': DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { }; DELETE DATA { "Westfälische Wilhelms-Universität Münster"@de }; DROP SERVER graphdb CASCADE; NOTICE: drop cascades to 2 other objects DETAIL: drop cascades to foreign table ft drop cascades to user mapping for postgres on server graphdb