-- Regression tests for fixed bugs that need no OAI-PMH repository. -- Port 1 on localhost refuses connections, so requests fail right away. \set VERBOSITY terse CREATE SERVER regress_offline FOREIGN DATA WRAPPER oai_fdw OPTIONS (url 'http://127.0.0.1:1/oai', connect_retry '0'); CREATE FOREIGN TABLE regress_t ( id text OPTIONS (oai_node 'identifier'), sets text[] OPTIONS (oai_node 'setspec'), updated timestamp OPTIONS (oai_node 'datestamp'), deleted boolean OPTIONS (oai_node 'status') ) SERVER regress_offline OPTIONS (metadataprefix 'oai_dc'); -- NULL element in a setspec array: used to crash the backend EXPLAIN (COSTS OFF) SELECT id FROM regress_t WHERE sets && ARRAY[NULL::text]; QUERY PLAN ---------------------------------------------- Foreign Scan on regress_t Filter: (sets && '{NULL}'::text[]) Foreign Server URL: http://127.0.0.1:1/oai requestVerb: ListIdentifiers metadataPrefix: oai_dc (5 rows) -- prefix operator: used to read past the argument list and crash CREATE FUNCTION regress_not(boolean) RETURNS boolean LANGUAGE plpgsql IMMUTABLE AS 'BEGIN RETURN NOT $1; END'; CREATE OPERATOR !!! (RIGHTARG = boolean, FUNCTION = regress_not); EXPLAIN (COSTS OFF) SELECT id FROM regress_t WHERE !!! deleted; QUERY PLAN ---------------------------------------------- Foreign Scan on regress_t Filter: (!!! deleted) Foreign Server URL: http://127.0.0.1:1/oai requestVerb: ListIdentifiers metadataPrefix: oai_dc (5 rows) DROP OPERATOR !!! (NONE, boolean); DROP FUNCTION regress_not(boolean); -- constants that cannot be pushed down as they are EXPLAIN (COSTS OFF) SELECT id FROM regress_t WHERE updated < '2020-01-06'::date; QUERY PLAN ---------------------------------------------- Foreign Scan on regress_t Filter: (updated < '01-06-2020'::date) Foreign Server URL: http://127.0.0.1:1/oai requestVerb: ListIdentifiers metadataPrefix: oai_dc until: 2020-01-06T00:00:00Z (6 rows) EXPLAIN (COSTS OFF) SELECT id FROM regress_t WHERE updated > '-infinity'; QUERY PLAN ---------------------------------------------------------------- Foreign Scan on regress_t Filter: (updated > '-infinity'::timestamp without time zone) Foreign Server URL: http://127.0.0.1:1/oai requestVerb: ListIdentifiers metadataPrefix: oai_dc (5 rows) EXPLAIN (COSTS OFF) SELECT id FROM regress_t WHERE updated > '4714-11-24 BC'; QUERY PLAN ---------------------------------------------------------------------------------- Foreign Scan on regress_t Filter: (updated > 'Mon Nov 24 00:00:00 4714 BC'::timestamp without time zone) Foreign Server URL: http://127.0.0.1:1/oai requestVerb: ListIdentifiers metadataPrefix: oai_dc (5 rows) EXPLAIN (COSTS OFF) SELECT id FROM regress_t WHERE id = 'oai:x:1'; QUERY PLAN ---------------------------------------------- Foreign Scan on regress_t Filter: (id = 'oai:x:1'::text) Foreign Server URL: http://127.0.0.1:1/oai requestVerb: GetRecord metadataPrefix: oai_dc (5 rows) -- support functions on a server of another FDW: used to crash CREATE FOREIGN DATA WRAPPER regress_dummy_fdw; CREATE SERVER regress_other FOREIGN DATA WRAPPER regress_dummy_fdw; SELECT * FROM OAI_Identify('regress_other'); ERROR: FOREIGN SERVER 'regress_other' does not belong to oai_fdw DROP FOREIGN DATA WRAPPER regress_dummy_fdw CASCADE; NOTICE: drop cascades to server regress_other -- support functions require USAGE on the server CREATE ROLE regress_oai_nopriv; SET ROLE regress_oai_nopriv; SELECT * FROM OAI_ListSets('regress_offline'); ERROR: permission denied for foreign server regress_offline RESET ROLE; DROP ROLE regress_oai_nopriv; -- connect_retry 0 disables retries: no "request ... failed (n/m)" warnings SELECT * FROM OAI_Identify('regress_offline'); ERROR: OAI request failed: HTTP 0 -- server option validation CREATE SERVER regress_bad FOREIGN DATA WRAPPER oai_fdw OPTIONS (url 'http://127.0.0.1:1/oai', request_redirect 'maybe'); ERROR: invalid request_redirect: maybe CREATE SERVER regress_bad FOREIGN DATA WRAPPER oai_fdw OPTIONS (url 'http://127.0.0.1:1/oai', request_max_redirect 'foo'); ERROR: invalid request_max_redirect: foo CREATE SERVER regress_bad FOREIGN DATA WRAPPER oai_fdw OPTIONS (url 'ftp://127.0.0.1/oai'); ERROR: invalid url: 'ftp://127.0.0.1/oai' -- from/until table options CREATE FOREIGN TABLE regress_bad_t (id text OPTIONS (oai_node 'identifier')) SERVER regress_offline OPTIONS (metadataprefix 'oai_dc', from 'yesterday'); ERROR: invalid from: yesterday CREATE FOREIGN TABLE regress_bad_t (id text OPTIONS (oai_node 'identifier')) SERVER regress_offline OPTIONS (metadataprefix 'oai_dc', until '2020-02-30'); ERROR: date/time field value out of range: "2020-02-30" CREATE FOREIGN TABLE regress_bad_t (id text OPTIONS (oai_node 'identifier')) SERVER regress_offline OPTIONS (metadataprefix 'oai_dc', until '2020-01-02 10:00:00'); ERROR: invalid until: 2020-01-02 10:00:00 CREATE FOREIGN TABLE regress_ok_t (id text OPTIONS (oai_node 'identifier')) SERVER regress_offline OPTIONS (metadataprefix 'oai_dc', from '2020-01-02T10:00:00Z'); ALTER FOREIGN TABLE regress_ok_t OPTIONS (ADD until 'tomorrow'); ERROR: invalid until: tomorrow DROP FOREIGN TABLE regress_ok_t; -- hint for an invalid oai_node \set VERBOSITY default CREATE FOREIGN TABLE regress_bad_t (x text OPTIONS (oai_node 'foo')) SERVER regress_offline OPTIONS (metadataprefix 'oai_dc'); ERROR: invalid oai_node option 'foo' HINT: Valid values for oai_node are 'identifier', 'content', 'datestamp', 'setspec', 'metadataprefix' and 'status'. \set VERBOSITY terse -- OAI_HarvestTable finds foreign tables whose name needs quoting CREATE FOREIGN TABLE "Regress T" ( id text OPTIONS (oai_node 'identifier'), updated timestamp OPTIONS (oai_node 'datestamp') ) SERVER regress_offline OPTIONS (metadataprefix 'oai_dc'); CALL OAI_HarvestTable('"Regress T"', 'regress_h', interval '1 day', '2020-01-01', '2020-01-02'); NOTICE: target table "public.regress_h" created ERROR: OAI request failed: HTTP 0 -- values only known at execution time are pushed down (see the DETAIL) \set VERBOSITY default SET regress.oai_id = 'oai:x:2'; SELECT id FROM regress_t WHERE id = current_setting('regress.oai_id'); ERROR: OAI request failed: HTTP 0 DETAIL: URL: "http://127.0.0.1:1/oai?verb=GetRecord&identifier=oai%3Ax%3A2&metadataPrefix=oai_dc" HINT: Check your request parameters and try again. SET regress.oai_set = 'a'; SELECT id FROM regress_t WHERE sets && ARRAY[current_setting('regress.oai_set')]; ERROR: OAI request failed: HTTP 0 DETAIL: URL: "http://127.0.0.1:1/oai?verb=ListIdentifiers&set=a&metadataPrefix=oai_dc" HINT: Check your request parameters and try again. \set VERBOSITY terse EXPLAIN (COSTS OFF) SELECT id FROM regress_t WHERE id = current_setting('regress.oai_id') AND updated > now() - interval '1 day' AND updated > now() - interval '2 days'; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------------- Foreign Scan on regress_t Filter: ((id = current_setting('regress.oai_id'::text)) AND (updated > (now() - '@ 1 day'::interval)) AND (updated > (now() - '@ 2 days'::interval))) Foreign Server URL: http://127.0.0.1:1/oai requestVerb: ListIdentifiers metadataPrefix: oai_dc Runtime arguments: identifier, from (6 rows) \set VERBOSITY default -- a parameter is evaluated again on each rescan, a NULL one needs no request SELECT v.x, (SELECT count(*) FROM regress_t WHERE id = v.x) FROM (VALUES (NULL), ('oai:x:1')) v(x); ERROR: OAI request failed: HTTP 0 DETAIL: URL: "http://127.0.0.1:1/oai?verb=GetRecord&identifier=oai%3Ax%3A1&metadataPrefix=oai_dc" HINT: Check your request parameters and try again. \set VERBOSITY terse -- GetRecord takes no from/until: no Identify request for their granularity CREATE FOREIGN TABLE regress_from_t (id text OPTIONS (oai_node 'identifier')) SERVER regress_offline OPTIONS (metadataprefix 'oai_dc', from '2020-01-01'); \set VERBOSITY default SELECT id FROM regress_from_t WHERE id = 'oai:x:1'; ERROR: OAI request failed: HTTP 0 DETAIL: URL: "http://127.0.0.1:1/oai?verb=GetRecord&identifier=oai%3Ax%3A1&metadataPrefix=oai_dc" HINT: Check your request parameters and try again. \set VERBOSITY terse -- OAI_HarvestTable in a current schema whose name needs quoting CREATE SCHEMA "Regress Schema"; SET search_path = "Regress Schema", public; CREATE FOREIGN TABLE regress_schema_t ( id text OPTIONS (oai_node 'identifier'), updated timestamp OPTIONS (oai_node 'datestamp') ) SERVER regress_offline OPTIONS (metadataprefix 'oai_dc'); CALL OAI_HarvestTable('regress_schema_t', 'regress_h', interval '1 day', '2020-01-01', '2020-01-02'); NOTICE: target table ""Regress Schema".regress_h" created ERROR: OAI request failed: HTTP 0 RESET search_path; DROP SCHEMA "Regress Schema" CASCADE; NOTICE: drop cascades to foreign table "Regress Schema".regress_schema_t -- OAI_HarvestTable checks its arguments before creating anything CALL OAI_HarvestTable('regress_t', 'regress_h', interval '-1 day', '2020-01-01', '2020-01-10'); ERROR: invalid page size [@ 1 day ago]. It must be a positive interval CALL OAI_HarvestTable('regress_t', 'regress_h', interval '0', '2020-01-01', '2020-01-10'); ERROR: invalid page size [@ 0]. It must be a positive interval CALL OAI_HarvestTable('regress_t', 'regress_h', interval '1 day', NULL, '2020-01-10'); ERROR: page_size, start_date and end_date must not be NULL SELECT to_regclass('regress_h') IS NULL AS no_target_table; no_target_table ----------------- t (1 row) DROP SERVER regress_offline CASCADE; NOTICE: drop cascades to 3 other objects