SELECT sparql.add_context('testctx', 'test context'); add_context ------------- (1 row) SELECT sparql.add_prefix('testctx', 'rdf', 'http://www.w3.org/2000/01/rdf-schema#'); add_prefix ------------ (1 row) CREATE SERVER graphdb FOREIGN DATA WRAPPER rdf_fdw OPTIONS ( endpoint 'http://graphdb:7200/repositories/test/statements', -- this tests if the regular endpoint is used for updates prefix_context 'testctx', batch_size '5'); CREATE USER MAPPING FOR postgres SERVER graphdb OPTIONS (user 'admin', password 'secret'); CREATE FOREIGN TABLE ft ( subject rdfnode OPTIONS (variable '?s'), predicate rdfnode OPTIONS (variable '?p'), foo rdfnode OPTIONS (variable '?foo'), -- will be ignored object rdfnode OPTIONS (variable '?o') ) SERVER graphdb OPTIONS ( log_sparql 'false', sparql 'SELECT * {?s ?p ?o}', sparql_update_pattern '?s ?p ?o . ?s rdf:comment "added via rdf_fdw 🐘"^^.' ); INSERT INTO ft (subject, predicate, object) VALUES ('', '', 'http://dbpedia.org/resource/University'); INSERT INTO ft (subject, predicate, object) VALUES ('', '', 'http://dbpedia.org/resource/University'), ('', '', ''), ('', '', '""'), ('', '', '""@es'), ('', '', '"University of Münster"@en'), ('', '', '"Westfälische \"Wilhelms-Universität\" Münster"@de'), ('', '', '"Westfälische \nWilhelms-Universität\n Münster"@de'), ('', '', '"Westfälische .. Wilhelms-Universität . Münster"@de'), ('', '', '🐘'::rdfnode); /* Set the endpoint to the right URL and add update_url */ ALTER SERVER graphdb OPTIONS (ADD update_url 'http://graphdb:7200/repositories/test/statements', SET endpoint 'http://graphdb:7200/repositories/test'); SELECT subject, predicate, object FROM ft WHERE subject = '' ORDER BY predicate, object::text COLLATE "C"; subject | predicate | object -------------------------------+------------------------------------------------------+----------------------------------------------------- | | "🐘" | | "http://dbpedia.org/resource/University" | | "added via rdf_fdw 🐘" | | "" | | ""@es | | "University of Münster"@en | | "Westfälische + | | Wilhelms-Universität + | | Münster"@de | | "Westfälische .. Wilhelms-Universität . Münster"@de | | "Westfälische \"Wilhelms-Universität\" Münster"@de (9 rows) /* Test DEFAULT values handling */ ALTER FOREIGN TABLE ft ALTER COLUMN object SET DEFAULT '"default literal"'::rdfnode; INSERT INTO ft (subject, predicate) VALUES ('', ''); SELECT subject, predicate, object FROM ft WHERE predicate = ''; subject | predicate | object -------------------------------+-------------------------------------------------+------------------- | | "default literal" (1 row) ALTER FOREIGN TABLE ft ALTER COLUMN object DROP DEFAULT; /* insert large literal */ ALTER FOREIGN TABLE ft OPTIONS (SET log_sparql 'false'); -- disable logging to not flood the ouput file INSERT INTO ft (subject, predicate, object) VALUES ('', '', repeat('b', 1000000)::rdfnode); SELECT subject, predicate, sparql.strlen(object) FROM ft WHERE predicate = ''; subject | predicate | strlen -------------------------------+-------------------------------------------------+--------- | | 15 | | 1000000 (2 rows) /* bulk insert */ INSERT INTO ft (subject, predicate, object) SELECT sparql.iri('https://www.uni-muenster.de'), sparql.iri('http://www.w3.org/1999/02/22-rdf-syntax-ns#value'), i::rdfnode FROM generate_series(1,100) AS j (i); SELECT count(*) FROM ft; count ------- 190 (1 row) /* insert with RETURNING */ INSERT INTO ft (subject, predicate, object) VALUES ('', '', '"Universidade de Münster"@pt') RETURNING *; subject | predicate | foo | object -------------------------------+----------------------------------------------+-----+------------------------------ | | | "Universidade de Münster"@pt (1 row) /* * Here we transfer data from Wikidata to graphdb. * The NAMED GRAPH is manually specified in the sparql * and sparql_update_pattern options. graphdb will then * create the graph in query time, if it does not exist. */ CREATE SERVER wikidata FOREIGN DATA WRAPPER rdf_fdw OPTIONS ( endpoint 'https://query.wikidata.org/sparql'); CREATE FOREIGN TABLE rdbms_wikidata ( s rdfnode OPTIONS (variable '?s'), p rdfnode OPTIONS (variable '?p'), o rdfnode OPTIONS (variable '?o') ) SERVER wikidata OPTIONS ( log_sparql 'false', sparql $$ SELECT * {?s ?p ?o . FILTER(?s=) FILTER(?p=)} $$ ); CREATE FOREIGN TABLE rdbms_graphdb ( s rdfnode OPTIONS (variable '?s'), p rdfnode OPTIONS (variable '?p'), o rdfnode OPTIONS (variable '?o') ) SERVER graphdb OPTIONS ( log_sparql 'true', sparql $$ SELECT * { GRAPH { ?s ?p ?o . FILTER(?s=) FILTER(?p=) } } $$, sparql_update_pattern $$ GRAPH { ?s ?p ?o . } $$); INSERT INTO rdbms_graphdb (s, p, o) SELECT s, p, o FROM rdbms_wikidata; INFO: SPARQL query sent to 'graphdb': PREFIX rdf: INSERT DATA { GRAPH { "PostgreSQL"@ar . } }; INSERT DATA { GRAPH { "পোস্টজিআরই"@bn . } }; INSERT DATA { GRAPH { "Postgres"@ca . } }; INSERT DATA { GRAPH { "Postgres"@de . } }; INSERT DATA { GRAPH { "PostgreSQL project"@de . } }; INFO: SPARQL query sent to 'graphdb': PREFIX rdf: INSERT DATA { GRAPH { "Postgres"@en . } }; INSERT DATA { GRAPH { "پست گر اس کیوال"@fa . } }; INSERT DATA { GRAPH { "پستگر اسکیوال"@fa . } }; INSERT DATA { GRAPH { "Postgres"@fr . } }; INSERT DATA { GRAPH { "Postgres"@hu . } }; INFO: SPARQL query sent to 'graphdb': PREFIX rdf: INSERT DATA { GRAPH { "Postgres"@it . } }; INSERT DATA { GRAPH { "Postgres"@ja . } }; INSERT DATA { GRAPH { "ポスグレ"@ja . } }; INSERT DATA { GRAPH { "ポストグレスキューエル"@ja . } }; INSERT DATA { GRAPH { "Postgres"@lv . } }; INFO: SPARQL query sent to 'graphdb': PREFIX rdf: INSERT DATA { GRAPH { "Postgres"@mul . } }; INSERT DATA { GRAPH { "postgres"@nl . } }; INSERT DATA { GRAPH { "PgSQL"@pl . } }; INSERT DATA { GRAPH { "Postgre"@pl . } }; INSERT DATA { GRAPH { "Postgres"@pl . } }; INFO: SPARQL query sent to 'graphdb': PREFIX rdf: INSERT DATA { GRAPH { "Postgres"@pt . } }; INSERT DATA { GRAPH { "pgsql"@pt-br . } }; INSERT DATA { GRAPH { "Postgre"@sr . } }; INSERT DATA { GRAPH { "Postgre SQL"@sr . } }; INSERT DATA { GRAPH { "Postgres"@sr . } }; INFO: SPARQL query sent to 'graphdb': PREFIX rdf: INSERT DATA { GRAPH { "Postgresql"@sr . } }; INSERT DATA { GRAPH { "PostgreSQL, слободни софтвер"@sr . } }; INSERT DATA { GRAPH { "Postgres"@sv . } }; INSERT DATA { GRAPH { "போசுகிரசு"@ta . } }; INSERT DATA { GRAPH { "PostgreSQL"@th . } }; INFO: SPARQL query sent to 'graphdb': PREFIX rdf: INSERT DATA { GRAPH { "โพสต์เกรส"@th . } }; INSERT DATA { GRAPH { "POSTGRE SQL"@vi . } }; INSERT DATA { GRAPH { "Postgres"@zh . } }; INSERT DATA { GRAPH { "Postgres"@zh-hant . } }; INSERT DATA { GRAPH { "Postgres"@zh-tw . } }; SELECT * FROM rdbms_graphdb ORDER BY o::text COLLATE "C"; INFO: SPARQL query sent to 'graphdb': PREFIX rdf: SELECT ?s ?p ?o { GRAPH { ?s ?p ?o . FILTER(?s=) FILTER(?p=) } } INFO: SPARQL returned 35 records. s | p | o ------------------------------------------+------------------------------------------------+----------------------------------- | | "POSTGRE SQL"@vi | | "PgSQL"@pl | | "Postgre SQL"@sr | | "Postgre"@pl | | "Postgre"@sr | | "PostgreSQL project"@de | | "PostgreSQL"@ar | | "PostgreSQL"@th | | "PostgreSQL, слободни софтвер"@sr | | "Postgres"@ca | | "Postgres"@de | | "Postgres"@en | | "Postgres"@fr | | "Postgres"@hu | | "Postgres"@it | | "Postgres"@ja | | "Postgres"@lv | | "Postgres"@mul | | "Postgres"@pl | | "Postgres"@pt | | "Postgres"@sr | | "Postgres"@sv | | "Postgres"@zh | | "Postgres"@zh-Hant | | "Postgres"@zh-TW | | "Postgresql"@sr | | "pgsql"@pt-BR | | "postgres"@nl | | "پست گر اس کیوال"@fa | | "پستگر اسکیوال"@fa | | "পোস্টজিআরই"@bn | | "போசுகிரசு"@ta | | "โพสต์เกรส"@th | | "ポスグレ"@ja | | "ポストグレスキューエル"@ja (35 rows) COPY ( SELECT s, p , o FROM rdbms_graphdb ORDER BY o::text COLLATE "C" ) TO STDOUT DELIMITER E' '; INFO: SPARQL query sent to 'graphdb': PREFIX rdf: SELECT ?s ?p ?o { GRAPH { ?s ?p ?o . FILTER(?s=) FILTER(?p=) } } INFO: SPARQL returned 35 records. "POSTGRE\ SQL"@vi "PgSQL"@pl "Postgre\ SQL"@sr "Postgre"@pl "Postgre"@sr "PostgreSQL\ project"@de "PostgreSQL"@ar "PostgreSQL"@th "PostgreSQL,\ слободни\ софтвер"@sr "Postgres"@ca "Postgres"@de "Postgres"@en "Postgres"@fr "Postgres"@hu "Postgres"@it "Postgres"@ja "Postgres"@lv "Postgres"@mul "Postgres"@pl "Postgres"@pt "Postgres"@sr "Postgres"@sv "Postgres"@zh "Postgres"@zh-Hant "Postgres"@zh-TW "Postgresql"@sr "pgsql"@pt-BR "postgres"@nl "پست\ گر\ اس\ کیوال"@fa "پستگر\ اسکیوال"@fa "পোস্টজিআরই"@bn "போசுகிரசு"@ta "โพสต์เกรส"@th "ポスグレ"@ja "ポストグレスキューエル"@ja /*** Exception tests ***/ /* COPY .. FROM must fail - not supported */ COPY ft (subject, predicate, object) FROM STDIN WITH (DELIMITER ' '); ERROR: cannot copy to foreign table "ft" /* INSERT must fail - all columns must be of type rdfnode */ ALTER FOREIGN TABLE ft ALTER COLUMN predicate TYPE text; INSERT INTO ft (subject, predicate, object) VALUES ('', '', 'http://dbpedia.org/resource/University'); ERROR: rdfExecForeignInsert: column 'predicate' is not of type rdfnode ALTER FOREIGN TABLE ft ALTER COLUMN predicate TYPE rdfnode; /* INSERT must fail - no column with the variable ?p */ ALTER FOREIGN TABLE ft ALTER COLUMN predicate OPTIONS (SET variable '?bar'); INSERT INTO ft (subject, predicate, object) VALUES ('', '', 'http://dbpedia.org/resource/University'); ERROR: SPARQL variable '?p' in 'sparql_update_pattern' is not mapped to any table column /* ALTER COLUMN must fail - variable is required */ ALTER FOREIGN TABLE ft ALTER COLUMN predicate OPTIONS (DROP variable); ERROR: required option 'variable' is missing INSERT INTO ft (subject, predicate, object) VALUES ('', '', 'http://dbpedia.org/resource/University'); ERROR: SPARQL variable '?p' in 'sparql_update_pattern' is not mapped to any table column \set VERBOSITY terse /* invalid sparql_update_pattern - no triple pattern */ ALTER FOREIGN TABLE ft ALTER COLUMN predicate OPTIONS (SET variable '?p'); ALTER FOREIGN TABLE ft OPTIONS (SET sparql_update_pattern '?s ?o .'); INSERT INTO ft (subject, predicate, object) VALUES ('', '', 'http://dbpedia.org/resource/University'); ERROR: 'sparql_update_pattern' contains no valid triple patterns /* invalid sparql_update_pattern - no variable */ ALTER FOREIGN TABLE ft OPTIONS (SET sparql_update_pattern 'foo .'); INSERT INTO ft (subject, predicate, object) VALUES ('', '', 'http://dbpedia.org/resource/University'); ERROR: 'sparql_update_pattern' contains no valid triple patterns /* invalid update_url - no URL */ ALTER FOREIGN TABLE ft OPTIONS (SET sparql_update_pattern '?s ?p o .'); ALTER SERVER graphdb OPTIONS (SET update_url 'foo'); INSERT INTO ft (subject, predicate, object) VALUES ('', '', 'http://dbpedia.org/resource/University'); ERROR: invalid update_url: 'foo' /* invalid triple pattern - no sparql_update_pattern OPTION */ ALTER SERVER graphdb OPTIONS (SET update_url 'http://graphdb:7200/repositories/test/statements', SET endpoint 'http://graphdb:7200/repositories/test'); ALTER FOREIGN TABLE ft OPTIONS (DROP sparql_update_pattern); INSERT INTO ft (subject, predicate, object) VALUES ('', '', 'http://dbpedia.org/resource/University'); ERROR: INSERT operation requires a valid triple pattern in 'sparql_update_pattern' /* invalid triple pattern - empty sparql_update_pattern OPTION */ ALTER FOREIGN TABLE ft OPTIONS (ADD sparql_update_pattern ' '); INSERT INTO ft (subject, predicate, object) VALUES ('', '', 'http://dbpedia.org/resource/University'); ERROR: 'sparql_update_pattern' contains no valid triple patterns /* invalid value - NULL value */ ALTER FOREIGN TABLE ft OPTIONS (SET sparql_update_pattern '?s ?p ?o .'); INSERT INTO ft (subject, predicate, object) VALUES ('', '', NULL); ERROR: NULL value in column "object" violates RDF constraint /* invalid value - blank node */ INSERT INTO ft (subject, predicate, object) VALUES ('', '', sparql.bnode()); ERROR: blank nodes are not allowed in INSERT operations /* cleanup */ DELETE FROM ft; SELECT sparql.drop_context('testctx', true); drop_context -------------- (1 row) DROP SERVER graphdb CASCADE; NOTICE: drop cascades to 3 other objects DROP SERVER wikidata CASCADE; NOTICE: drop cascades to foreign table rdbms_wikidata