mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-24 18:55:04 +08:00
a0f357e570
Make separate columns "Collation", "Nullable", "Default". Reviewed-by: Kuntal Ghosh <kuntalghosh.2007@gmail.com>
6975 lines
344 KiB
Plaintext
6975 lines
344 KiB
Plaintext
-- ===================================================================
|
|
-- create FDW objects
|
|
-- ===================================================================
|
|
CREATE EXTENSION postgres_fdw;
|
|
CREATE SERVER testserver1 FOREIGN DATA WRAPPER postgres_fdw;
|
|
DO $d$
|
|
BEGIN
|
|
EXECUTE $$CREATE SERVER loopback FOREIGN DATA WRAPPER postgres_fdw
|
|
OPTIONS (dbname '$$||current_database()||$$',
|
|
port '$$||current_setting('port')||$$'
|
|
)$$;
|
|
EXECUTE $$CREATE SERVER loopback2 FOREIGN DATA WRAPPER postgres_fdw
|
|
OPTIONS (dbname '$$||current_database()||$$',
|
|
port '$$||current_setting('port')||$$'
|
|
)$$;
|
|
END;
|
|
$d$;
|
|
CREATE USER MAPPING FOR public SERVER testserver1
|
|
OPTIONS (user 'value', password 'value');
|
|
CREATE USER MAPPING FOR CURRENT_USER SERVER loopback;
|
|
CREATE USER MAPPING FOR CURRENT_USER SERVER loopback2;
|
|
-- ===================================================================
|
|
-- create objects used through FDW loopback server
|
|
-- ===================================================================
|
|
CREATE TYPE user_enum AS ENUM ('foo', 'bar', 'buz');
|
|
CREATE SCHEMA "S 1";
|
|
CREATE TABLE "S 1"."T 1" (
|
|
"C 1" int NOT NULL,
|
|
c2 int NOT NULL,
|
|
c3 text,
|
|
c4 timestamptz,
|
|
c5 timestamp,
|
|
c6 varchar(10),
|
|
c7 char(10),
|
|
c8 user_enum,
|
|
CONSTRAINT t1_pkey PRIMARY KEY ("C 1")
|
|
);
|
|
CREATE TABLE "S 1"."T 2" (
|
|
c1 int NOT NULL,
|
|
c2 text,
|
|
CONSTRAINT t2_pkey PRIMARY KEY (c1)
|
|
);
|
|
CREATE TABLE "S 1"."T 3" (
|
|
c1 int NOT NULL,
|
|
c2 int NOT NULL,
|
|
c3 text,
|
|
CONSTRAINT t3_pkey PRIMARY KEY (c1)
|
|
);
|
|
CREATE TABLE "S 1"."T 4" (
|
|
c1 int NOT NULL,
|
|
c2 int NOT NULL,
|
|
c3 text,
|
|
CONSTRAINT t4_pkey PRIMARY KEY (c1)
|
|
);
|
|
INSERT INTO "S 1"."T 1"
|
|
SELECT id,
|
|
id % 10,
|
|
to_char(id, 'FM00000'),
|
|
'1970-01-01'::timestamptz + ((id % 100) || ' days')::interval,
|
|
'1970-01-01'::timestamp + ((id % 100) || ' days')::interval,
|
|
id % 10,
|
|
id % 10,
|
|
'foo'::user_enum
|
|
FROM generate_series(1, 1000) id;
|
|
INSERT INTO "S 1"."T 2"
|
|
SELECT id,
|
|
'AAA' || to_char(id, 'FM000')
|
|
FROM generate_series(1, 100) id;
|
|
INSERT INTO "S 1"."T 3"
|
|
SELECT id,
|
|
id + 1,
|
|
'AAA' || to_char(id, 'FM000')
|
|
FROM generate_series(1, 100) id;
|
|
DELETE FROM "S 1"."T 3" WHERE c1 % 2 != 0; -- delete for outer join tests
|
|
INSERT INTO "S 1"."T 4"
|
|
SELECT id,
|
|
id + 1,
|
|
'AAA' || to_char(id, 'FM000')
|
|
FROM generate_series(1, 100) id;
|
|
DELETE FROM "S 1"."T 4" WHERE c1 % 3 != 0; -- delete for outer join tests
|
|
ANALYZE "S 1"."T 1";
|
|
ANALYZE "S 1"."T 2";
|
|
ANALYZE "S 1"."T 3";
|
|
ANALYZE "S 1"."T 4";
|
|
-- ===================================================================
|
|
-- create foreign tables
|
|
-- ===================================================================
|
|
CREATE FOREIGN TABLE ft1 (
|
|
c0 int,
|
|
c1 int NOT NULL,
|
|
c2 int NOT NULL,
|
|
c3 text,
|
|
c4 timestamptz,
|
|
c5 timestamp,
|
|
c6 varchar(10),
|
|
c7 char(10) default 'ft1',
|
|
c8 user_enum
|
|
) SERVER loopback;
|
|
ALTER FOREIGN TABLE ft1 DROP COLUMN c0;
|
|
CREATE FOREIGN TABLE ft2 (
|
|
c1 int NOT NULL,
|
|
c2 int NOT NULL,
|
|
cx int,
|
|
c3 text,
|
|
c4 timestamptz,
|
|
c5 timestamp,
|
|
c6 varchar(10),
|
|
c7 char(10) default 'ft2',
|
|
c8 user_enum
|
|
) SERVER loopback;
|
|
ALTER FOREIGN TABLE ft2 DROP COLUMN cx;
|
|
CREATE FOREIGN TABLE ft4 (
|
|
c1 int NOT NULL,
|
|
c2 int NOT NULL,
|
|
c3 text
|
|
) SERVER loopback OPTIONS (schema_name 'S 1', table_name 'T 3');
|
|
CREATE FOREIGN TABLE ft5 (
|
|
c1 int NOT NULL,
|
|
c2 int NOT NULL,
|
|
c3 text
|
|
) SERVER loopback OPTIONS (schema_name 'S 1', table_name 'T 4');
|
|
CREATE FOREIGN TABLE ft6 (
|
|
c1 int NOT NULL,
|
|
c2 int NOT NULL,
|
|
c3 text
|
|
) SERVER loopback2 OPTIONS (schema_name 'S 1', table_name 'T 4');
|
|
-- A table with oids. CREATE FOREIGN TABLE doesn't support the
|
|
-- WITH OIDS option, but ALTER does.
|
|
CREATE FOREIGN TABLE ft_pg_type (
|
|
typname name,
|
|
typlen smallint
|
|
) SERVER loopback OPTIONS (schema_name 'pg_catalog', table_name 'pg_type');
|
|
ALTER TABLE ft_pg_type SET WITH OIDS;
|
|
-- ===================================================================
|
|
-- tests for validator
|
|
-- ===================================================================
|
|
-- requiressl, krbsrvname and gsslib are omitted because they depend on
|
|
-- configure options
|
|
ALTER SERVER testserver1 OPTIONS (
|
|
use_remote_estimate 'false',
|
|
updatable 'true',
|
|
fdw_startup_cost '123.456',
|
|
fdw_tuple_cost '0.123',
|
|
service 'value',
|
|
connect_timeout 'value',
|
|
dbname 'value',
|
|
host 'value',
|
|
hostaddr 'value',
|
|
port 'value',
|
|
--client_encoding 'value',
|
|
application_name 'value',
|
|
--fallback_application_name 'value',
|
|
keepalives 'value',
|
|
keepalives_idle 'value',
|
|
keepalives_interval 'value',
|
|
-- requiressl 'value',
|
|
sslcompression 'value',
|
|
sslmode 'value',
|
|
sslcert 'value',
|
|
sslkey 'value',
|
|
sslrootcert 'value',
|
|
sslcrl 'value'
|
|
--requirepeer 'value',
|
|
-- krbsrvname 'value',
|
|
-- gsslib 'value',
|
|
--replication 'value'
|
|
);
|
|
-- Error, invalid list syntax
|
|
ALTER SERVER testserver1 OPTIONS (ADD extensions 'foo; bar');
|
|
ERROR: parameter "extensions" must be a list of extension names
|
|
-- OK but gets a warning
|
|
ALTER SERVER testserver1 OPTIONS (ADD extensions 'foo, bar');
|
|
WARNING: extension "foo" is not installed
|
|
WARNING: extension "bar" is not installed
|
|
ALTER SERVER testserver1 OPTIONS (DROP extensions);
|
|
ALTER USER MAPPING FOR public SERVER testserver1
|
|
OPTIONS (DROP user, DROP password);
|
|
ALTER FOREIGN TABLE ft1 OPTIONS (schema_name 'S 1', table_name 'T 1');
|
|
ALTER FOREIGN TABLE ft2 OPTIONS (schema_name 'S 1', table_name 'T 1');
|
|
ALTER FOREIGN TABLE ft1 ALTER COLUMN c1 OPTIONS (column_name 'C 1');
|
|
ALTER FOREIGN TABLE ft2 ALTER COLUMN c1 OPTIONS (column_name 'C 1');
|
|
\det+
|
|
List of foreign tables
|
|
Schema | Table | Server | FDW Options | Description
|
|
--------+------------+-----------+--------------------------------------------------+-------------
|
|
public | ft1 | loopback | (schema_name 'S 1', table_name 'T 1') |
|
|
public | ft2 | loopback | (schema_name 'S 1', table_name 'T 1') |
|
|
public | ft4 | loopback | (schema_name 'S 1', table_name 'T 3') |
|
|
public | ft5 | loopback | (schema_name 'S 1', table_name 'T 4') |
|
|
public | ft6 | loopback2 | (schema_name 'S 1', table_name 'T 4') |
|
|
public | ft_pg_type | loopback | (schema_name 'pg_catalog', table_name 'pg_type') |
|
|
(6 rows)
|
|
|
|
-- Now we should be able to run ANALYZE.
|
|
-- To exercise multiple code paths, we use local stats on ft1
|
|
-- and remote-estimate mode on ft2.
|
|
ANALYZE ft1;
|
|
ALTER FOREIGN TABLE ft2 OPTIONS (use_remote_estimate 'true');
|
|
-- ===================================================================
|
|
-- simple queries
|
|
-- ===================================================================
|
|
-- single table without alias
|
|
EXPLAIN (COSTS OFF) SELECT * FROM ft1 ORDER BY c3, c1 OFFSET 100 LIMIT 10;
|
|
QUERY PLAN
|
|
---------------------------
|
|
Limit
|
|
-> Foreign Scan on ft1
|
|
(2 rows)
|
|
|
|
SELECT * FROM ft1 ORDER BY c3, c1 OFFSET 100 LIMIT 10;
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
-----+----+-------+------------------------------+--------------------------+----+------------+-----
|
|
101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo
|
|
102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 PST | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo
|
|
103 | 3 | 00103 | Sun Jan 04 00:00:00 1970 PST | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo
|
|
104 | 4 | 00104 | Mon Jan 05 00:00:00 1970 PST | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo
|
|
105 | 5 | 00105 | Tue Jan 06 00:00:00 1970 PST | Tue Jan 06 00:00:00 1970 | 5 | 5 | foo
|
|
106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo
|
|
107 | 7 | 00107 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo
|
|
108 | 8 | 00108 | Fri Jan 09 00:00:00 1970 PST | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo
|
|
109 | 9 | 00109 | Sat Jan 10 00:00:00 1970 PST | Sat Jan 10 00:00:00 1970 | 9 | 9 | foo
|
|
110 | 0 | 00110 | Sun Jan 11 00:00:00 1970 PST | Sun Jan 11 00:00:00 1970 | 0 | 0 | foo
|
|
(10 rows)
|
|
|
|
-- single table with alias - also test that tableoid sort is not pushed to remote side
|
|
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 ORDER BY t1.c3, t1.c1, t1.tableoid OFFSET 100 LIMIT 10;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8, tableoid
|
|
-> Sort
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8, tableoid
|
|
Sort Key: t1.c3, t1.c1, t1.tableoid
|
|
-> Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8, tableoid
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1"
|
|
(8 rows)
|
|
|
|
SELECT * FROM ft1 t1 ORDER BY t1.c3, t1.c1, t1.tableoid OFFSET 100 LIMIT 10;
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
-----+----+-------+------------------------------+--------------------------+----+------------+-----
|
|
101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo
|
|
102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 PST | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo
|
|
103 | 3 | 00103 | Sun Jan 04 00:00:00 1970 PST | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo
|
|
104 | 4 | 00104 | Mon Jan 05 00:00:00 1970 PST | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo
|
|
105 | 5 | 00105 | Tue Jan 06 00:00:00 1970 PST | Tue Jan 06 00:00:00 1970 | 5 | 5 | foo
|
|
106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo
|
|
107 | 7 | 00107 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo
|
|
108 | 8 | 00108 | Fri Jan 09 00:00:00 1970 PST | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo
|
|
109 | 9 | 00109 | Sat Jan 10 00:00:00 1970 PST | Sat Jan 10 00:00:00 1970 | 9 | 9 | foo
|
|
110 | 0 | 00110 | Sun Jan 11 00:00:00 1970 PST | Sun Jan 11 00:00:00 1970 | 0 | 0 | foo
|
|
(10 rows)
|
|
|
|
-- whole-row reference
|
|
EXPLAIN (VERBOSE, COSTS OFF) SELECT t1 FROM ft1 t1 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10;
|
|
QUERY PLAN
|
|
--------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.*, c3, c1
|
|
-> Foreign Scan on public.ft1 t1
|
|
Output: t1.*, c3, c1
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ORDER BY c3 ASC NULLS LAST, "C 1" ASC NULLS LAST
|
|
(5 rows)
|
|
|
|
SELECT t1 FROM ft1 t1 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10;
|
|
t1
|
|
--------------------------------------------------------------------------------------------
|
|
(101,1,00101,"Fri Jan 02 00:00:00 1970 PST","Fri Jan 02 00:00:00 1970",1,"1 ",foo)
|
|
(102,2,00102,"Sat Jan 03 00:00:00 1970 PST","Sat Jan 03 00:00:00 1970",2,"2 ",foo)
|
|
(103,3,00103,"Sun Jan 04 00:00:00 1970 PST","Sun Jan 04 00:00:00 1970",3,"3 ",foo)
|
|
(104,4,00104,"Mon Jan 05 00:00:00 1970 PST","Mon Jan 05 00:00:00 1970",4,"4 ",foo)
|
|
(105,5,00105,"Tue Jan 06 00:00:00 1970 PST","Tue Jan 06 00:00:00 1970",5,"5 ",foo)
|
|
(106,6,00106,"Wed Jan 07 00:00:00 1970 PST","Wed Jan 07 00:00:00 1970",6,"6 ",foo)
|
|
(107,7,00107,"Thu Jan 08 00:00:00 1970 PST","Thu Jan 08 00:00:00 1970",7,"7 ",foo)
|
|
(108,8,00108,"Fri Jan 09 00:00:00 1970 PST","Fri Jan 09 00:00:00 1970",8,"8 ",foo)
|
|
(109,9,00109,"Sat Jan 10 00:00:00 1970 PST","Sat Jan 10 00:00:00 1970",9,"9 ",foo)
|
|
(110,0,00110,"Sun Jan 11 00:00:00 1970 PST","Sun Jan 11 00:00:00 1970",0,"0 ",foo)
|
|
(10 rows)
|
|
|
|
-- empty result
|
|
SELECT * FROM ft1 WHERE false;
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
----+----+----+----+----+----+----+----
|
|
(0 rows)
|
|
|
|
-- with WHERE clause
|
|
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.c1 = 101 AND t1.c6 = '1' AND t1.c7 >= '1';
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((c7 >= '1'::bpchar)) AND (("C 1" = 101)) AND ((c6 = '1'::text))
|
|
(3 rows)
|
|
|
|
SELECT * FROM ft1 t1 WHERE t1.c1 = 101 AND t1.c6 = '1' AND t1.c7 >= '1';
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
-----+----+-------+------------------------------+--------------------------+----+------------+-----
|
|
101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo
|
|
(1 row)
|
|
|
|
-- with FOR UPDATE/SHARE
|
|
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = 101 FOR UPDATE;
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------------------------------------------------
|
|
LockRows
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8, t1.*
|
|
-> Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8, t1.*
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 101)) FOR UPDATE
|
|
(5 rows)
|
|
|
|
SELECT * FROM ft1 t1 WHERE c1 = 101 FOR UPDATE;
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
-----+----+-------+------------------------------+--------------------------+----+------------+-----
|
|
101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo
|
|
(1 row)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = 102 FOR SHARE;
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------------------------
|
|
LockRows
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8, t1.*
|
|
-> Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8, t1.*
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 102)) FOR SHARE
|
|
(5 rows)
|
|
|
|
SELECT * FROM ft1 t1 WHERE c1 = 102 FOR SHARE;
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
-----+----+-------+------------------------------+--------------------------+----+------------+-----
|
|
102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 PST | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo
|
|
(1 row)
|
|
|
|
-- aggregate
|
|
SELECT COUNT(*) FROM ft1 t1;
|
|
count
|
|
-------
|
|
1000
|
|
(1 row)
|
|
|
|
-- subquery
|
|
SELECT * FROM ft1 t1 WHERE t1.c3 IN (SELECT c3 FROM ft2 t2 WHERE c1 <= 10) ORDER BY c1;
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
----+----+-------+------------------------------+--------------------------+----+------------+-----
|
|
1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo
|
|
2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo
|
|
3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo
|
|
4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo
|
|
5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 PST | Tue Jan 06 00:00:00 1970 | 5 | 5 | foo
|
|
6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo
|
|
7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo
|
|
8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 PST | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo
|
|
9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 PST | Sat Jan 10 00:00:00 1970 | 9 | 9 | foo
|
|
10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 PST | Sun Jan 11 00:00:00 1970 | 0 | 0 | foo
|
|
(10 rows)
|
|
|
|
-- subquery+MAX
|
|
SELECT * FROM ft1 t1 WHERE t1.c3 = (SELECT MAX(c3) FROM ft2 t2) ORDER BY c1;
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
------+----+-------+------------------------------+--------------------------+----+------------+-----
|
|
1000 | 0 | 01000 | Thu Jan 01 00:00:00 1970 PST | Thu Jan 01 00:00:00 1970 | 0 | 0 | foo
|
|
(1 row)
|
|
|
|
-- used in CTE
|
|
WITH t1 AS (SELECT * FROM ft1 WHERE c1 <= 10) SELECT t2.c1, t2.c2, t2.c3, t2.c4 FROM t1, ft2 t2 WHERE t1.c1 = t2.c1 ORDER BY t1.c1;
|
|
c1 | c2 | c3 | c4
|
|
----+----+-------+------------------------------
|
|
1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST
|
|
2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST
|
|
3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST
|
|
4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST
|
|
5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 PST
|
|
6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST
|
|
7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST
|
|
8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 PST
|
|
9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 PST
|
|
10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 PST
|
|
(10 rows)
|
|
|
|
-- fixed values
|
|
SELECT 'fixed', NULL FROM ft1 t1 WHERE c1 = 1;
|
|
?column? | ?column?
|
|
----------+----------
|
|
fixed |
|
|
(1 row)
|
|
|
|
-- Test forcing the remote server to produce sorted data for a merge join.
|
|
SET enable_hashjoin TO false;
|
|
SET enable_nestloop TO false;
|
|
-- inner join; expressions in the clauses appear in the equivalence class list
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2."C 1" FROM ft2 t1 JOIN "S 1"."T 1" t2 ON (t1.c1 = t2."C 1") OFFSET 100 LIMIT 10;
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2."C 1"
|
|
-> Merge Join
|
|
Output: t1.c1, t2."C 1"
|
|
Merge Cond: (t1.c1 = t2."C 1")
|
|
-> Foreign Scan on public.ft2 t1
|
|
Output: t1.c1
|
|
Remote SQL: SELECT "C 1" FROM "S 1"."T 1" ORDER BY "C 1" ASC NULLS LAST
|
|
-> Index Only Scan using t1_pkey on "S 1"."T 1" t2
|
|
Output: t2."C 1"
|
|
(10 rows)
|
|
|
|
SELECT t1.c1, t2."C 1" FROM ft2 t1 JOIN "S 1"."T 1" t2 ON (t1.c1 = t2."C 1") OFFSET 100 LIMIT 10;
|
|
c1 | C 1
|
|
-----+-----
|
|
101 | 101
|
|
102 | 102
|
|
103 | 103
|
|
104 | 104
|
|
105 | 105
|
|
106 | 106
|
|
107 | 107
|
|
108 | 108
|
|
109 | 109
|
|
110 | 110
|
|
(10 rows)
|
|
|
|
-- outer join; expressions in the clauses do not appear in equivalence class
|
|
-- list but no output change as compared to the previous query
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2."C 1" FROM ft2 t1 LEFT JOIN "S 1"."T 1" t2 ON (t1.c1 = t2."C 1") OFFSET 100 LIMIT 10;
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2."C 1"
|
|
-> Merge Left Join
|
|
Output: t1.c1, t2."C 1"
|
|
Merge Cond: (t1.c1 = t2."C 1")
|
|
-> Foreign Scan on public.ft2 t1
|
|
Output: t1.c1
|
|
Remote SQL: SELECT "C 1" FROM "S 1"."T 1" ORDER BY "C 1" ASC NULLS LAST
|
|
-> Index Only Scan using t1_pkey on "S 1"."T 1" t2
|
|
Output: t2."C 1"
|
|
(10 rows)
|
|
|
|
SELECT t1.c1, t2."C 1" FROM ft2 t1 LEFT JOIN "S 1"."T 1" t2 ON (t1.c1 = t2."C 1") OFFSET 100 LIMIT 10;
|
|
c1 | C 1
|
|
-----+-----
|
|
101 | 101
|
|
102 | 102
|
|
103 | 103
|
|
104 | 104
|
|
105 | 105
|
|
106 | 106
|
|
107 | 107
|
|
108 | 108
|
|
109 | 109
|
|
110 | 110
|
|
(10 rows)
|
|
|
|
-- A join between local table and foreign join. ORDER BY clause is added to the
|
|
-- foreign join so that the local table can be joined using merge join strategy.
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1."C 1" FROM "S 1"."T 1" t1 left join ft1 t2 join ft2 t3 on (t2.c1 = t3.c1) on (t3.c1 = t1."C 1") OFFSET 100 LIMIT 10;
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1."C 1"
|
|
-> Merge Right Join
|
|
Output: t1."C 1"
|
|
Merge Cond: (t3.c1 = t1."C 1")
|
|
-> Foreign Scan
|
|
Output: t3.c1
|
|
Relations: (public.ft1 t2) INNER JOIN (public.ft2 t3)
|
|
Remote SQL: SELECT r3."C 1" FROM ("S 1"."T 1" r2 INNER JOIN "S 1"."T 1" r3 ON (((r2."C 1" = r3."C 1")))) ORDER BY r2."C 1" ASC NULLS LAST
|
|
-> Index Only Scan using t1_pkey on "S 1"."T 1" t1
|
|
Output: t1."C 1"
|
|
(11 rows)
|
|
|
|
SELECT t1."C 1" FROM "S 1"."T 1" t1 left join ft1 t2 join ft2 t3 on (t2.c1 = t3.c1) on (t3.c1 = t1."C 1") OFFSET 100 LIMIT 10;
|
|
C 1
|
|
-----
|
|
101
|
|
102
|
|
103
|
|
104
|
|
105
|
|
106
|
|
107
|
|
108
|
|
109
|
|
110
|
|
(10 rows)
|
|
|
|
-- Test similar to above, except that the full join prevents any equivalence
|
|
-- classes from being merged. This produces single relation equivalence classes
|
|
-- included in join restrictions.
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1."C 1", t2.c1, t3.c1 FROM "S 1"."T 1" t1 left join ft1 t2 full join ft2 t3 on (t2.c1 = t3.c1) on (t3.c1 = t1."C 1") OFFSET 100 LIMIT 10;
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1."C 1", t2.c1, t3.c1
|
|
-> Merge Right Join
|
|
Output: t1."C 1", t2.c1, t3.c1
|
|
Merge Cond: (t3.c1 = t1."C 1")
|
|
-> Foreign Scan
|
|
Output: t3.c1, t2.c1
|
|
Relations: (public.ft2 t3) LEFT JOIN (public.ft1 t2)
|
|
Remote SQL: SELECT r3."C 1", r2."C 1" FROM ("S 1"."T 1" r3 LEFT JOIN "S 1"."T 1" r2 ON (((r2."C 1" = r3."C 1")))) ORDER BY r3."C 1" ASC NULLS LAST
|
|
-> Index Only Scan using t1_pkey on "S 1"."T 1" t1
|
|
Output: t1."C 1"
|
|
(11 rows)
|
|
|
|
SELECT t1."C 1", t2.c1, t3.c1 FROM "S 1"."T 1" t1 left join ft1 t2 full join ft2 t3 on (t2.c1 = t3.c1) on (t3.c1 = t1."C 1") OFFSET 100 LIMIT 10;
|
|
C 1 | c1 | c1
|
|
-----+-----+-----
|
|
101 | 101 | 101
|
|
102 | 102 | 102
|
|
103 | 103 | 103
|
|
104 | 104 | 104
|
|
105 | 105 | 105
|
|
106 | 106 | 106
|
|
107 | 107 | 107
|
|
108 | 108 | 108
|
|
109 | 109 | 109
|
|
110 | 110 | 110
|
|
(10 rows)
|
|
|
|
-- Test similar to above with all full outer joins
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1."C 1", t2.c1, t3.c1 FROM "S 1"."T 1" t1 full join ft1 t2 full join ft2 t3 on (t2.c1 = t3.c1) on (t3.c1 = t1."C 1") OFFSET 100 LIMIT 10;
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1."C 1", t2.c1, t3.c1
|
|
-> Merge Full Join
|
|
Output: t1."C 1", t2.c1, t3.c1
|
|
Merge Cond: (t3.c1 = t1."C 1")
|
|
-> Foreign Scan
|
|
Output: t2.c1, t3.c1
|
|
Relations: (public.ft1 t2) FULL JOIN (public.ft2 t3)
|
|
Remote SQL: SELECT r2."C 1", r3."C 1" FROM ("S 1"."T 1" r2 FULL JOIN "S 1"."T 1" r3 ON (((r2."C 1" = r3."C 1")))) ORDER BY r3."C 1" ASC NULLS LAST
|
|
-> Index Only Scan using t1_pkey on "S 1"."T 1" t1
|
|
Output: t1."C 1"
|
|
(11 rows)
|
|
|
|
SELECT t1."C 1", t2.c1, t3.c1 FROM "S 1"."T 1" t1 full join ft1 t2 full join ft2 t3 on (t2.c1 = t3.c1) on (t3.c1 = t1."C 1") OFFSET 100 LIMIT 10;
|
|
C 1 | c1 | c1
|
|
-----+-----+-----
|
|
101 | 101 | 101
|
|
102 | 102 | 102
|
|
103 | 103 | 103
|
|
104 | 104 | 104
|
|
105 | 105 | 105
|
|
106 | 106 | 106
|
|
107 | 107 | 107
|
|
108 | 108 | 108
|
|
109 | 109 | 109
|
|
110 | 110 | 110
|
|
(10 rows)
|
|
|
|
RESET enable_hashjoin;
|
|
RESET enable_nestloop;
|
|
-- ===================================================================
|
|
-- WHERE with remotely-executable conditions
|
|
-- ===================================================================
|
|
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.c1 = 1; -- Var, OpExpr(b), Const
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 1))
|
|
(3 rows)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.c1 = 100 AND t1.c2 = 0; -- BoolExpr
|
|
QUERY PLAN
|
|
--------------------------------------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 100)) AND ((c2 = 0))
|
|
(3 rows)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 IS NULL; -- NullTest
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" IS NULL))
|
|
(3 rows)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 IS NOT NULL; -- NullTest
|
|
QUERY PLAN
|
|
-----------------------------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" IS NOT NULL))
|
|
(3 rows)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE round(abs(c1), 0) = 1; -- FuncExpr
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((round(abs("C 1"), 0) = 1::numeric))
|
|
(3 rows)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = -c1; -- OpExpr(l)
|
|
QUERY PLAN
|
|
-----------------------------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = (- "C 1")))
|
|
(3 rows)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE 1 = c1!; -- OpExpr(r)
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((1::numeric = ("C 1" !)))
|
|
(3 rows)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (c1 IS NOT NULL) IS DISTINCT FROM (c1 IS NOT NULL); -- DistinctExpr
|
|
QUERY PLAN
|
|
--------------------------------------------------------------------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((("C 1" IS NOT NULL) IS DISTINCT FROM ("C 1" IS NOT NULL)))
|
|
(3 rows)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = ANY(ARRAY[c2, 1, c1 + 0]); -- ScalarArrayOpExpr
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = ANY (ARRAY[c2, 1, ("C 1" + 0)])))
|
|
(3 rows)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = (ARRAY[c1,c2,3])[1]; -- ArrayRef
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = ((ARRAY["C 1", c2, 3])[1])))
|
|
(3 rows)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c6 = E'foo''s\\bar'; -- check special chars
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((c6 = E'foo''s\\bar'::text))
|
|
(3 rows)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c8 = 'foo'; -- can't be sent to remote
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------
|
|
Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Filter: (t1.c8 = 'foo'::user_enum)
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1"
|
|
(4 rows)
|
|
|
|
-- parameterized remote path for foreign table
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT * FROM "S 1"."T 1" a, ft2 b WHERE a."C 1" = 47 AND b.c1 = a.c2;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------------------------------
|
|
Nested Loop
|
|
Output: a."C 1", a.c2, a.c3, a.c4, a.c5, a.c6, a.c7, a.c8, b.c1, b.c2, b.c3, b.c4, b.c5, b.c6, b.c7, b.c8
|
|
-> Index Scan using t1_pkey on "S 1"."T 1" a
|
|
Output: a."C 1", a.c2, a.c3, a.c4, a.c5, a.c6, a.c7, a.c8
|
|
Index Cond: (a."C 1" = 47)
|
|
-> Foreign Scan on public.ft2 b
|
|
Output: b.c1, b.c2, b.c3, b.c4, b.c5, b.c6, b.c7, b.c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (($1::integer = "C 1"))
|
|
(8 rows)
|
|
|
|
SELECT * FROM ft2 a, ft2 b WHERE a.c1 = 47 AND b.c1 = a.c2;
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
----+----+-------+------------------------------+--------------------------+----+------------+-----+----+----+-------+------------------------------+--------------------------+----+------------+-----
|
|
47 | 7 | 00047 | Tue Feb 17 00:00:00 1970 PST | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo | 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo
|
|
(1 row)
|
|
|
|
-- check both safe and unsafe join conditions
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT * FROM ft2 a, ft2 b
|
|
WHERE a.c2 = 6 AND b.c1 = a.c1 AND a.c8 = 'foo' AND b.c7 = upper(a.c7);
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------------------------------
|
|
Nested Loop
|
|
Output: a.c1, a.c2, a.c3, a.c4, a.c5, a.c6, a.c7, a.c8, b.c1, b.c2, b.c3, b.c4, b.c5, b.c6, b.c7, b.c8
|
|
-> Foreign Scan on public.ft2 a
|
|
Output: a.c1, a.c2, a.c3, a.c4, a.c5, a.c6, a.c7, a.c8
|
|
Filter: (a.c8 = 'foo'::user_enum)
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((c2 = 6))
|
|
-> Foreign Scan on public.ft2 b
|
|
Output: b.c1, b.c2, b.c3, b.c4, b.c5, b.c6, b.c7, b.c8
|
|
Filter: (upper((a.c7)::text) = (b.c7)::text)
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (($1::integer = "C 1"))
|
|
(10 rows)
|
|
|
|
SELECT * FROM ft2 a, ft2 b
|
|
WHERE a.c2 = 6 AND b.c1 = a.c1 AND a.c8 = 'foo' AND b.c7 = upper(a.c7);
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
-----+----+-------+------------------------------+--------------------------+----+------------+-----+-----+----+-------+------------------------------+--------------------------+----+------------+-----
|
|
6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo
|
|
16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo
|
|
26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo
|
|
36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo
|
|
46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo
|
|
56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo
|
|
66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo
|
|
76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo
|
|
86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo
|
|
96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo
|
|
106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo
|
|
116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo
|
|
126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo
|
|
136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo
|
|
146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo
|
|
156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo
|
|
166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo
|
|
176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo
|
|
186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo
|
|
196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo
|
|
206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo
|
|
216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo
|
|
226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo
|
|
236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo
|
|
246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo
|
|
256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo
|
|
266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo
|
|
276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo
|
|
286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo
|
|
296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo
|
|
306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo
|
|
316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo
|
|
326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo
|
|
336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo
|
|
346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo
|
|
356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo
|
|
366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo
|
|
376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo
|
|
386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo
|
|
396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo
|
|
406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo
|
|
416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo
|
|
426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo
|
|
436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo
|
|
446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo
|
|
456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo
|
|
466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo
|
|
476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo
|
|
486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo
|
|
496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo
|
|
506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo
|
|
516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo
|
|
526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo
|
|
536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo
|
|
546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo
|
|
556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo
|
|
566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo
|
|
576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo
|
|
586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo
|
|
596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo
|
|
606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo
|
|
616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo
|
|
626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo
|
|
636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo
|
|
646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo
|
|
656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo
|
|
666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo
|
|
676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo
|
|
686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo
|
|
696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo
|
|
706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo
|
|
716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo
|
|
726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo
|
|
736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo
|
|
746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo
|
|
756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo
|
|
766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo
|
|
776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo
|
|
786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo
|
|
796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo
|
|
806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo
|
|
816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo
|
|
826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo
|
|
836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo
|
|
846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo
|
|
856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo
|
|
866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo
|
|
876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo
|
|
886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo
|
|
896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo
|
|
906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo
|
|
916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo
|
|
926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo
|
|
936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo
|
|
946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo
|
|
956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo
|
|
966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo
|
|
976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo
|
|
986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo
|
|
996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo
|
|
(100 rows)
|
|
|
|
-- bug before 9.3.5 due to sloppy handling of remote-estimate parameters
|
|
SELECT * FROM ft1 WHERE c1 = ANY (ARRAY(SELECT c1 FROM ft2 WHERE c1 < 5));
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
----+----+-------+------------------------------+--------------------------+----+------------+-----
|
|
1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo
|
|
2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo
|
|
3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo
|
|
4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo
|
|
(4 rows)
|
|
|
|
SELECT * FROM ft2 WHERE c1 = ANY (ARRAY(SELECT c1 FROM ft1 WHERE c1 < 5));
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
----+----+-------+------------------------------+--------------------------+----+------------+-----
|
|
1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo
|
|
2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo
|
|
3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo
|
|
4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo
|
|
(4 rows)
|
|
|
|
-- we should not push order by clause with volatile expressions or unsafe
|
|
-- collations
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT * FROM ft2 ORDER BY ft2.c1, random();
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------
|
|
Sort
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8, (random())
|
|
Sort Key: ft2.c1, (random())
|
|
-> Foreign Scan on public.ft2
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8, random()
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1"
|
|
(6 rows)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT * FROM ft2 ORDER BY ft2.c1, ft2.c3 collate "C";
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------
|
|
Sort
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8, ((c3)::text)
|
|
Sort Key: ft2.c1, ft2.c3 COLLATE "C"
|
|
-> Foreign Scan on public.ft2
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8, c3
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1"
|
|
(6 rows)
|
|
|
|
-- user-defined operator/function
|
|
CREATE FUNCTION postgres_fdw_abs(int) RETURNS int AS $$
|
|
BEGIN
|
|
RETURN abs($1);
|
|
END
|
|
$$ LANGUAGE plpgsql IMMUTABLE;
|
|
CREATE OPERATOR === (
|
|
LEFTARG = int,
|
|
RIGHTARG = int,
|
|
PROCEDURE = int4eq,
|
|
COMMUTATOR = ===
|
|
);
|
|
-- built-in operators and functions can be shipped for remote execution
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = abs(t1.c2);
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------
|
|
Foreign Scan
|
|
Output: (count(c3))
|
|
Relations: Aggregate on (public.ft1 t1)
|
|
Remote SQL: SELECT count(c3) FROM "S 1"."T 1" WHERE (("C 1" = abs(c2)))
|
|
(4 rows)
|
|
|
|
SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = abs(t1.c2);
|
|
count
|
|
-------
|
|
9
|
|
(1 row)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = t1.c2;
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------
|
|
Foreign Scan
|
|
Output: (count(c3))
|
|
Relations: Aggregate on (public.ft1 t1)
|
|
Remote SQL: SELECT count(c3) FROM "S 1"."T 1" WHERE (("C 1" = c2))
|
|
(4 rows)
|
|
|
|
SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = t1.c2;
|
|
count
|
|
-------
|
|
9
|
|
(1 row)
|
|
|
|
-- by default, user-defined ones cannot
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = postgres_fdw_abs(t1.c2);
|
|
QUERY PLAN
|
|
-----------------------------------------------------------
|
|
Aggregate
|
|
Output: count(c3)
|
|
-> Foreign Scan on public.ft1 t1
|
|
Output: c3
|
|
Filter: (t1.c1 = postgres_fdw_abs(t1.c2))
|
|
Remote SQL: SELECT "C 1", c2, c3 FROM "S 1"."T 1"
|
|
(6 rows)
|
|
|
|
SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = postgres_fdw_abs(t1.c2);
|
|
count
|
|
-------
|
|
9
|
|
(1 row)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2;
|
|
QUERY PLAN
|
|
-----------------------------------------------------------
|
|
Aggregate
|
|
Output: count(c3)
|
|
-> Foreign Scan on public.ft1 t1
|
|
Output: c3
|
|
Filter: (t1.c1 === t1.c2)
|
|
Remote SQL: SELECT "C 1", c2, c3 FROM "S 1"."T 1"
|
|
(6 rows)
|
|
|
|
SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2;
|
|
count
|
|
-------
|
|
9
|
|
(1 row)
|
|
|
|
-- but let's put them in an extension ...
|
|
ALTER EXTENSION postgres_fdw ADD FUNCTION postgres_fdw_abs(int);
|
|
ALTER EXTENSION postgres_fdw ADD OPERATOR === (int, int);
|
|
ALTER SERVER loopback OPTIONS (ADD extensions 'postgres_fdw');
|
|
-- ... now they can be shipped
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = postgres_fdw_abs(t1.c2);
|
|
QUERY PLAN
|
|
-----------------------------------------------------------------------------------------------
|
|
Foreign Scan
|
|
Output: (count(c3))
|
|
Relations: Aggregate on (public.ft1 t1)
|
|
Remote SQL: SELECT count(c3) FROM "S 1"."T 1" WHERE (("C 1" = public.postgres_fdw_abs(c2)))
|
|
(4 rows)
|
|
|
|
SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = postgres_fdw_abs(t1.c2);
|
|
count
|
|
-------
|
|
9
|
|
(1 row)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2;
|
|
QUERY PLAN
|
|
-----------------------------------------------------------------------------------------
|
|
Foreign Scan
|
|
Output: (count(c3))
|
|
Relations: Aggregate on (public.ft1 t1)
|
|
Remote SQL: SELECT count(c3) FROM "S 1"."T 1" WHERE (("C 1" OPERATOR(public.===) c2))
|
|
(4 rows)
|
|
|
|
SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2;
|
|
count
|
|
-------
|
|
9
|
|
(1 row)
|
|
|
|
-- ===================================================================
|
|
-- JOIN queries
|
|
-- ===================================================================
|
|
-- Analyze ft4 and ft5 so that we have better statistics. These tables do not
|
|
-- have use_remote_estimate set.
|
|
ANALYZE ft4;
|
|
ANALYZE ft5;
|
|
-- join two tables
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10;
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2.c1, t1.c3
|
|
-> Foreign Scan
|
|
Output: t1.c1, t2.c1, t1.c3
|
|
Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2)
|
|
Remote SQL: SELECT r1."C 1", r1.c3, r2."C 1" FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) ORDER BY r1.c3 ASC NULLS LAST, r1."C 1" ASC NULLS LAST
|
|
(6 rows)
|
|
|
|
SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10;
|
|
c1 | c1
|
|
-----+-----
|
|
101 | 101
|
|
102 | 102
|
|
103 | 103
|
|
104 | 104
|
|
105 | 105
|
|
106 | 106
|
|
107 | 107
|
|
108 | 108
|
|
109 | 109
|
|
110 | 110
|
|
(10 rows)
|
|
|
|
-- join three tables
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c2, t3.c3 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) JOIN ft4 t3 ON (t3.c1 = t1.c1) ORDER BY t1.c3, t1.c1 OFFSET 10 LIMIT 10;
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2.c2, t3.c3, t1.c3
|
|
-> Sort
|
|
Output: t1.c1, t2.c2, t3.c3, t1.c3
|
|
Sort Key: t1.c3, t1.c1
|
|
-> Foreign Scan
|
|
Output: t1.c1, t2.c2, t3.c3, t1.c3
|
|
Relations: ((public.ft1 t1) INNER JOIN (public.ft2 t2)) INNER JOIN (public.ft4 t3)
|
|
Remote SQL: SELECT r1."C 1", r1.c3, r2.c2, r4.c3 FROM (("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) INNER JOIN "S 1"."T 3" r4 ON (((r1."C 1" = r4.c1))))
|
|
(9 rows)
|
|
|
|
SELECT t1.c1, t2.c2, t3.c3 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) JOIN ft4 t3 ON (t3.c1 = t1.c1) ORDER BY t1.c3, t1.c1 OFFSET 10 LIMIT 10;
|
|
c1 | c2 | c3
|
|
----+----+--------
|
|
22 | 2 | AAA022
|
|
24 | 4 | AAA024
|
|
26 | 6 | AAA026
|
|
28 | 8 | AAA028
|
|
30 | 0 | AAA030
|
|
32 | 2 | AAA032
|
|
34 | 4 | AAA034
|
|
36 | 6 | AAA036
|
|
38 | 8 | AAA038
|
|
40 | 0 | AAA040
|
|
(10 rows)
|
|
|
|
-- left outer join
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c1 FROM ft4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2.c1
|
|
-> Foreign Scan
|
|
Output: t1.c1, t2.c1
|
|
Relations: (public.ft4 t1) LEFT JOIN (public.ft5 t2)
|
|
Remote SQL: SELECT r1.c1, r2.c1 FROM ("S 1"."T 3" r1 LEFT JOIN "S 1"."T 4" r2 ON (((r1.c1 = r2.c1)))) ORDER BY r1.c1 ASC NULLS LAST, r2.c1 ASC NULLS LAST
|
|
(6 rows)
|
|
|
|
SELECT t1.c1, t2.c1 FROM ft4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10;
|
|
c1 | c1
|
|
----+----
|
|
22 |
|
|
24 | 24
|
|
26 |
|
|
28 |
|
|
30 | 30
|
|
32 |
|
|
34 |
|
|
36 | 36
|
|
38 |
|
|
40 |
|
|
(10 rows)
|
|
|
|
-- left outer join three tables
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10;
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2.c2, t3.c3
|
|
-> Foreign Scan
|
|
Output: t1.c1, t2.c2, t3.c3
|
|
Relations: ((public.ft2 t1) LEFT JOIN (public.ft2 t2)) LEFT JOIN (public.ft4 t3)
|
|
Remote SQL: SELECT r1."C 1", r2.c2, r4.c3 FROM (("S 1"."T 1" r1 LEFT JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) LEFT JOIN "S 1"."T 3" r4 ON (((r2."C 1" = r4.c1))))
|
|
(6 rows)
|
|
|
|
SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10;
|
|
c1 | c2 | c3
|
|
----+----+--------
|
|
11 | 1 |
|
|
12 | 2 | AAA012
|
|
13 | 3 |
|
|
14 | 4 | AAA014
|
|
15 | 5 |
|
|
16 | 6 | AAA016
|
|
17 | 7 |
|
|
18 | 8 | AAA018
|
|
19 | 9 |
|
|
20 | 0 | AAA020
|
|
(10 rows)
|
|
|
|
-- left outer join + placement of clauses.
|
|
-- clauses within the nullable side are not pulled up, but top level clause on
|
|
-- non-nullable side is pushed into non-nullable side
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t1.c2, t2.c1, t2.c2 FROM ft4 t1 LEFT JOIN (SELECT * FROM ft5 WHERE c1 < 10) t2 ON (t1.c1 = t2.c1) WHERE t1.c1 < 10;
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Foreign Scan
|
|
Output: t1.c1, t1.c2, ft5.c1, ft5.c2
|
|
Relations: (public.ft4 t1) LEFT JOIN (public.ft5)
|
|
Remote SQL: SELECT r1.c1, r1.c2, r4.c1, r4.c2 FROM ("S 1"."T 3" r1 LEFT JOIN "S 1"."T 4" r4 ON (((r1.c1 = r4.c1)) AND ((r4.c1 < 10)))) WHERE ((r1.c1 < 10))
|
|
(4 rows)
|
|
|
|
SELECT t1.c1, t1.c2, t2.c1, t2.c2 FROM ft4 t1 LEFT JOIN (SELECT * FROM ft5 WHERE c1 < 10) t2 ON (t1.c1 = t2.c1) WHERE t1.c1 < 10;
|
|
c1 | c2 | c1 | c2
|
|
----+----+----+----
|
|
2 | 3 | |
|
|
4 | 5 | |
|
|
6 | 7 | 6 | 7
|
|
8 | 9 | |
|
|
(4 rows)
|
|
|
|
-- clauses within the nullable side are not pulled up, but the top level clause
|
|
-- on nullable side is not pushed down into nullable side
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t1.c2, t2.c1, t2.c2 FROM ft4 t1 LEFT JOIN (SELECT * FROM ft5 WHERE c1 < 10) t2 ON (t1.c1 = t2.c1)
|
|
WHERE (t2.c1 < 10 OR t2.c1 IS NULL) AND t1.c1 < 10;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Foreign Scan
|
|
Output: t1.c1, t1.c2, ft5.c1, ft5.c2
|
|
Relations: (public.ft4 t1) LEFT JOIN (public.ft5)
|
|
Remote SQL: SELECT r1.c1, r1.c2, r4.c1, r4.c2 FROM ("S 1"."T 3" r1 LEFT JOIN "S 1"."T 4" r4 ON (((r1.c1 = r4.c1)) AND ((r4.c1 < 10)))) WHERE (((r4.c1 < 10) OR (r4.c1 IS NULL))) AND ((r1.c1 < 10))
|
|
(4 rows)
|
|
|
|
SELECT t1.c1, t1.c2, t2.c1, t2.c2 FROM ft4 t1 LEFT JOIN (SELECT * FROM ft5 WHERE c1 < 10) t2 ON (t1.c1 = t2.c1)
|
|
WHERE (t2.c1 < 10 OR t2.c1 IS NULL) AND t1.c1 < 10;
|
|
c1 | c2 | c1 | c2
|
|
----+----+----+----
|
|
2 | 3 | |
|
|
4 | 5 | |
|
|
6 | 7 | 6 | 7
|
|
8 | 9 | |
|
|
(4 rows)
|
|
|
|
-- right outer join
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c1 FROM ft5 t1 RIGHT JOIN ft4 t2 ON (t1.c1 = t2.c1) ORDER BY t2.c1, t1.c1 OFFSET 10 LIMIT 10;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2.c1
|
|
-> Foreign Scan
|
|
Output: t1.c1, t2.c1
|
|
Relations: (public.ft4 t2) LEFT JOIN (public.ft5 t1)
|
|
Remote SQL: SELECT r2.c1, r1.c1 FROM ("S 1"."T 3" r2 LEFT JOIN "S 1"."T 4" r1 ON (((r1.c1 = r2.c1)))) ORDER BY r2.c1 ASC NULLS LAST, r1.c1 ASC NULLS LAST
|
|
(6 rows)
|
|
|
|
SELECT t1.c1, t2.c1 FROM ft5 t1 RIGHT JOIN ft4 t2 ON (t1.c1 = t2.c1) ORDER BY t2.c1, t1.c1 OFFSET 10 LIMIT 10;
|
|
c1 | c1
|
|
----+----
|
|
| 22
|
|
24 | 24
|
|
| 26
|
|
| 28
|
|
30 | 30
|
|
| 32
|
|
| 34
|
|
36 | 36
|
|
| 38
|
|
| 40
|
|
(10 rows)
|
|
|
|
-- right outer join three tables
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10;
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2.c2, t3.c3
|
|
-> Foreign Scan
|
|
Output: t1.c1, t2.c2, t3.c3
|
|
Relations: ((public.ft4 t3) LEFT JOIN (public.ft2 t2)) LEFT JOIN (public.ft2 t1)
|
|
Remote SQL: SELECT r4.c3, r2.c2, r1."C 1" FROM (("S 1"."T 3" r4 LEFT JOIN "S 1"."T 1" r2 ON (((r2."C 1" = r4.c1)))) LEFT JOIN "S 1"."T 1" r1 ON (((r1."C 1" = r2."C 1"))))
|
|
(6 rows)
|
|
|
|
SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10;
|
|
c1 | c2 | c3
|
|
----+----+--------
|
|
22 | 2 | AAA022
|
|
24 | 4 | AAA024
|
|
26 | 6 | AAA026
|
|
28 | 8 | AAA028
|
|
30 | 0 | AAA030
|
|
32 | 2 | AAA032
|
|
34 | 4 | AAA034
|
|
36 | 6 | AAA036
|
|
38 | 8 | AAA038
|
|
40 | 0 | AAA040
|
|
(10 rows)
|
|
|
|
-- full outer join
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c1 FROM ft4 t1 FULL JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 45 LIMIT 10;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2.c1
|
|
-> Foreign Scan
|
|
Output: t1.c1, t2.c1
|
|
Relations: (public.ft4 t1) FULL JOIN (public.ft5 t2)
|
|
Remote SQL: SELECT r1.c1, r2.c1 FROM ("S 1"."T 3" r1 FULL JOIN "S 1"."T 4" r2 ON (((r1.c1 = r2.c1)))) ORDER BY r1.c1 ASC NULLS LAST, r2.c1 ASC NULLS LAST
|
|
(6 rows)
|
|
|
|
SELECT t1.c1, t2.c1 FROM ft4 t1 FULL JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 45 LIMIT 10;
|
|
c1 | c1
|
|
-----+----
|
|
92 |
|
|
94 |
|
|
96 | 96
|
|
98 |
|
|
100 |
|
|
| 3
|
|
| 9
|
|
| 15
|
|
| 21
|
|
| 27
|
|
(10 rows)
|
|
|
|
-- full outer join with restrictions on the joining relations
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1;
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------------------------
|
|
Sort
|
|
Output: ft4.c1, ft5.c1
|
|
Sort Key: ft4.c1, ft5.c1
|
|
-> Hash Full Join
|
|
Output: ft4.c1, ft5.c1
|
|
Hash Cond: (ft4.c1 = ft5.c1)
|
|
-> Foreign Scan on public.ft4
|
|
Output: ft4.c1, ft4.c2, ft4.c3
|
|
Remote SQL: SELECT c1 FROM "S 1"."T 3" WHERE ((c1 >= 50)) AND ((c1 <= 60))
|
|
-> Hash
|
|
Output: ft5.c1
|
|
-> Foreign Scan on public.ft5
|
|
Output: ft5.c1
|
|
Remote SQL: SELECT c1 FROM "S 1"."T 4" WHERE ((c1 >= 50)) AND ((c1 <= 60))
|
|
(14 rows)
|
|
|
|
SELECT t1.c1, t2.c1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1;
|
|
c1 | c1
|
|
----+----
|
|
50 |
|
|
52 |
|
|
54 | 54
|
|
56 |
|
|
58 |
|
|
60 | 60
|
|
| 51
|
|
| 57
|
|
(8 rows)
|
|
|
|
-- full outer join + inner join
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c1, t3.c1 FROM ft4 t1 INNER JOIN ft5 t2 ON (t1.c1 = t2.c1 + 1 and t1.c1 between 50 and 60) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1, t2.c1, t3.c1 LIMIT 10;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2.c1, t3.c1
|
|
-> Foreign Scan
|
|
Output: t1.c1, t2.c1, t3.c1
|
|
Relations: ((public.ft4 t1) INNER JOIN (public.ft5 t2)) FULL JOIN (public.ft4 t3)
|
|
Remote SQL: SELECT r1.c1, r2.c1, r4.c1 FROM (("S 1"."T 3" r1 INNER JOIN "S 1"."T 4" r2 ON (((r1.c1 = (r2.c1 + 1))) AND ((r1.c1 >= 50)) AND ((r1.c1 <= 60)))) FULL JOIN "S 1"."T 3" r4 ON (((r2.c1 = r4.c1)))) ORDER BY r1.c1 ASC NULLS LAST, r2.c1 ASC NULLS LAST, r4.c1 ASC NULLS LAST
|
|
(6 rows)
|
|
|
|
SELECT t1.c1, t2.c1, t3.c1 FROM ft4 t1 INNER JOIN ft5 t2 ON (t1.c1 = t2.c1 + 1 and t1.c1 between 50 and 60) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1, t2.c1, t3.c1 LIMIT 10;
|
|
c1 | c1 | c1
|
|
----+----+----
|
|
52 | 51 |
|
|
58 | 57 |
|
|
| | 2
|
|
| | 4
|
|
| | 6
|
|
| | 8
|
|
| | 10
|
|
| | 12
|
|
| | 14
|
|
| | 16
|
|
(10 rows)
|
|
|
|
-- full outer join three tables
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10;
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2.c2, t3.c3
|
|
-> Foreign Scan
|
|
Output: t1.c1, t2.c2, t3.c3
|
|
Relations: ((public.ft2 t1) FULL JOIN (public.ft2 t2)) FULL JOIN (public.ft4 t3)
|
|
Remote SQL: SELECT r1."C 1", r2.c2, r4.c3 FROM (("S 1"."T 1" r1 FULL JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) FULL JOIN "S 1"."T 3" r4 ON (((r2."C 1" = r4.c1))))
|
|
(6 rows)
|
|
|
|
SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10;
|
|
c1 | c2 | c3
|
|
----+----+--------
|
|
11 | 1 |
|
|
12 | 2 | AAA012
|
|
13 | 3 |
|
|
14 | 4 | AAA014
|
|
15 | 5 |
|
|
16 | 6 | AAA016
|
|
17 | 7 |
|
|
18 | 8 | AAA018
|
|
19 | 9 |
|
|
20 | 0 | AAA020
|
|
(10 rows)
|
|
|
|
-- full outer join + right outer join
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10;
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2.c2, t3.c3
|
|
-> Foreign Scan
|
|
Output: t1.c1, t2.c2, t3.c3
|
|
Relations: ((public.ft4 t3) LEFT JOIN (public.ft2 t2)) LEFT JOIN (public.ft2 t1)
|
|
Remote SQL: SELECT r4.c3, r2.c2, r1."C 1" FROM (("S 1"."T 3" r4 LEFT JOIN "S 1"."T 1" r2 ON (((r2."C 1" = r4.c1)))) LEFT JOIN "S 1"."T 1" r1 ON (((r1."C 1" = r2."C 1"))))
|
|
(6 rows)
|
|
|
|
SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10;
|
|
c1 | c2 | c3
|
|
----+----+--------
|
|
22 | 2 | AAA022
|
|
24 | 4 | AAA024
|
|
26 | 6 | AAA026
|
|
28 | 8 | AAA028
|
|
30 | 0 | AAA030
|
|
32 | 2 | AAA032
|
|
34 | 4 | AAA034
|
|
36 | 6 | AAA036
|
|
38 | 8 | AAA038
|
|
40 | 0 | AAA040
|
|
(10 rows)
|
|
|
|
-- right outer join + full outer join
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10;
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2.c2, t3.c3
|
|
-> Foreign Scan
|
|
Output: t1.c1, t2.c2, t3.c3
|
|
Relations: ((public.ft2 t2) LEFT JOIN (public.ft2 t1)) FULL JOIN (public.ft4 t3)
|
|
Remote SQL: SELECT r2.c2, r1."C 1", r4.c3 FROM (("S 1"."T 1" r2 LEFT JOIN "S 1"."T 1" r1 ON (((r1."C 1" = r2."C 1")))) FULL JOIN "S 1"."T 3" r4 ON (((r2."C 1" = r4.c1))))
|
|
(6 rows)
|
|
|
|
SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10;
|
|
c1 | c2 | c3
|
|
----+----+--------
|
|
11 | 1 |
|
|
12 | 2 | AAA012
|
|
13 | 3 |
|
|
14 | 4 | AAA014
|
|
15 | 5 |
|
|
16 | 6 | AAA016
|
|
17 | 7 |
|
|
18 | 8 | AAA018
|
|
19 | 9 |
|
|
20 | 0 | AAA020
|
|
(10 rows)
|
|
|
|
-- full outer join + left outer join
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10;
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2.c2, t3.c3
|
|
-> Foreign Scan
|
|
Output: t1.c1, t2.c2, t3.c3
|
|
Relations: ((public.ft2 t1) FULL JOIN (public.ft2 t2)) LEFT JOIN (public.ft4 t3)
|
|
Remote SQL: SELECT r1."C 1", r2.c2, r4.c3 FROM (("S 1"."T 1" r1 FULL JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) LEFT JOIN "S 1"."T 3" r4 ON (((r2."C 1" = r4.c1))))
|
|
(6 rows)
|
|
|
|
SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10;
|
|
c1 | c2 | c3
|
|
----+----+--------
|
|
11 | 1 |
|
|
12 | 2 | AAA012
|
|
13 | 3 |
|
|
14 | 4 | AAA014
|
|
15 | 5 |
|
|
16 | 6 | AAA016
|
|
17 | 7 |
|
|
18 | 8 | AAA018
|
|
19 | 9 |
|
|
20 | 0 | AAA020
|
|
(10 rows)
|
|
|
|
-- left outer join + full outer join
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10;
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2.c2, t3.c3
|
|
-> Foreign Scan
|
|
Output: t1.c1, t2.c2, t3.c3
|
|
Relations: ((public.ft2 t1) LEFT JOIN (public.ft2 t2)) FULL JOIN (public.ft4 t3)
|
|
Remote SQL: SELECT r1."C 1", r2.c2, r4.c3 FROM (("S 1"."T 1" r1 LEFT JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) FULL JOIN "S 1"."T 3" r4 ON (((r2."C 1" = r4.c1))))
|
|
(6 rows)
|
|
|
|
SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10;
|
|
c1 | c2 | c3
|
|
----+----+--------
|
|
11 | 1 |
|
|
12 | 2 | AAA012
|
|
13 | 3 |
|
|
14 | 4 | AAA014
|
|
15 | 5 |
|
|
16 | 6 | AAA016
|
|
17 | 7 |
|
|
18 | 8 | AAA018
|
|
19 | 9 |
|
|
20 | 0 | AAA020
|
|
(10 rows)
|
|
|
|
-- right outer join + left outer join
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10;
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2.c2, t3.c3
|
|
-> Foreign Scan
|
|
Output: t1.c1, t2.c2, t3.c3
|
|
Relations: ((public.ft2 t2) LEFT JOIN (public.ft2 t1)) LEFT JOIN (public.ft4 t3)
|
|
Remote SQL: SELECT r2.c2, r1."C 1", r4.c3 FROM (("S 1"."T 1" r2 LEFT JOIN "S 1"."T 1" r1 ON (((r1."C 1" = r2."C 1")))) LEFT JOIN "S 1"."T 3" r4 ON (((r2."C 1" = r4.c1))))
|
|
(6 rows)
|
|
|
|
SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10;
|
|
c1 | c2 | c3
|
|
----+----+--------
|
|
11 | 1 |
|
|
12 | 2 | AAA012
|
|
13 | 3 |
|
|
14 | 4 | AAA014
|
|
15 | 5 |
|
|
16 | 6 | AAA016
|
|
17 | 7 |
|
|
18 | 8 | AAA018
|
|
19 | 9 |
|
|
20 | 0 | AAA020
|
|
(10 rows)
|
|
|
|
-- left outer join + right outer join
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2.c2, t3.c3
|
|
-> Foreign Scan
|
|
Output: t1.c1, t2.c2, t3.c3
|
|
Relations: (public.ft4 t3) LEFT JOIN ((public.ft2 t1) INNER JOIN (public.ft2 t2))
|
|
Remote SQL: SELECT r4.c3, r1."C 1", r2.c2 FROM ("S 1"."T 3" r4 LEFT JOIN ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) ON (((r2."C 1" = r4.c1))))
|
|
(6 rows)
|
|
|
|
SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10;
|
|
c1 | c2 | c3
|
|
----+----+--------
|
|
22 | 2 | AAA022
|
|
24 | 4 | AAA024
|
|
26 | 6 | AAA026
|
|
28 | 8 | AAA028
|
|
30 | 0 | AAA030
|
|
32 | 2 | AAA032
|
|
34 | 4 | AAA034
|
|
36 | 6 | AAA036
|
|
38 | 8 | AAA038
|
|
40 | 0 | AAA040
|
|
(10 rows)
|
|
|
|
-- full outer join + WHERE clause, only matched rows
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c1 FROM ft4 t1 FULL JOIN ft5 t2 ON (t1.c1 = t2.c1) WHERE (t1.c1 = t2.c1 OR t1.c1 IS NULL) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10;
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2.c1
|
|
-> Sort
|
|
Output: t1.c1, t2.c1
|
|
Sort Key: t1.c1, t2.c1
|
|
-> Foreign Scan
|
|
Output: t1.c1, t2.c1
|
|
Relations: (public.ft4 t1) FULL JOIN (public.ft5 t2)
|
|
Remote SQL: SELECT r1.c1, r2.c1 FROM ("S 1"."T 3" r1 FULL JOIN "S 1"."T 4" r2 ON (((r1.c1 = r2.c1)))) WHERE (((r1.c1 = r2.c1) OR (r1.c1 IS NULL)))
|
|
(9 rows)
|
|
|
|
SELECT t1.c1, t2.c1 FROM ft4 t1 FULL JOIN ft5 t2 ON (t1.c1 = t2.c1) WHERE (t1.c1 = t2.c1 OR t1.c1 IS NULL) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10;
|
|
c1 | c1
|
|
----+----
|
|
66 | 66
|
|
72 | 72
|
|
78 | 78
|
|
84 | 84
|
|
90 | 90
|
|
96 | 96
|
|
| 3
|
|
| 9
|
|
| 15
|
|
| 21
|
|
(10 rows)
|
|
|
|
-- join two tables with FOR UPDATE clause
|
|
-- tests whole-row reference for row marks
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR UPDATE OF t1;
|
|
QUERY PLAN
|
|
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2.c1, t1.c3, t1.*, t2.*
|
|
-> LockRows
|
|
Output: t1.c1, t2.c1, t1.c3, t1.*, t2.*
|
|
-> Foreign Scan
|
|
Output: t1.c1, t2.c1, t1.c3, t1.*, t2.*
|
|
Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2)
|
|
Remote SQL: SELECT r1."C 1", r1.c3, CASE WHEN (r1.*)::text IS NOT NULL THEN ROW(r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8) END, r2."C 1", CASE WHEN (r2.*)::text IS NOT NULL THEN ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) END FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) ORDER BY r1.c3 ASC NULLS LAST, r1."C 1" ASC NULLS LAST FOR UPDATE OF r1
|
|
-> Merge Join
|
|
Output: t1.c1, t1.c3, t1.*, t2.c1, t2.*
|
|
Merge Cond: (t1.c1 = t2.c1)
|
|
-> Sort
|
|
Output: t1.c1, t1.c3, t1.*
|
|
Sort Key: t1.c1
|
|
-> Foreign Scan on public.ft1 t1
|
|
Output: t1.c1, t1.c3, t1.*
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" FOR UPDATE
|
|
-> Sort
|
|
Output: t2.c1, t2.*
|
|
Sort Key: t2.c1
|
|
-> Foreign Scan on public.ft2 t2
|
|
Output: t2.c1, t2.*
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1"
|
|
(23 rows)
|
|
|
|
SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR UPDATE OF t1;
|
|
c1 | c1
|
|
-----+-----
|
|
101 | 101
|
|
102 | 102
|
|
103 | 103
|
|
104 | 104
|
|
105 | 105
|
|
106 | 106
|
|
107 | 107
|
|
108 | 108
|
|
109 | 109
|
|
110 | 110
|
|
(10 rows)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR UPDATE;
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2.c1, t1.c3, t1.*, t2.*
|
|
-> LockRows
|
|
Output: t1.c1, t2.c1, t1.c3, t1.*, t2.*
|
|
-> Foreign Scan
|
|
Output: t1.c1, t2.c1, t1.c3, t1.*, t2.*
|
|
Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2)
|
|
Remote SQL: SELECT r1."C 1", r1.c3, CASE WHEN (r1.*)::text IS NOT NULL THEN ROW(r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8) END, r2."C 1", CASE WHEN (r2.*)::text IS NOT NULL THEN ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) END FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) ORDER BY r1.c3 ASC NULLS LAST, r1."C 1" ASC NULLS LAST FOR UPDATE OF r1 FOR UPDATE OF r2
|
|
-> Merge Join
|
|
Output: t1.c1, t1.c3, t1.*, t2.c1, t2.*
|
|
Merge Cond: (t1.c1 = t2.c1)
|
|
-> Sort
|
|
Output: t1.c1, t1.c3, t1.*
|
|
Sort Key: t1.c1
|
|
-> Foreign Scan on public.ft1 t1
|
|
Output: t1.c1, t1.c3, t1.*
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" FOR UPDATE
|
|
-> Sort
|
|
Output: t2.c1, t2.*
|
|
Sort Key: t2.c1
|
|
-> Foreign Scan on public.ft2 t2
|
|
Output: t2.c1, t2.*
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" FOR UPDATE
|
|
(23 rows)
|
|
|
|
SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR UPDATE;
|
|
c1 | c1
|
|
-----+-----
|
|
101 | 101
|
|
102 | 102
|
|
103 | 103
|
|
104 | 104
|
|
105 | 105
|
|
106 | 106
|
|
107 | 107
|
|
108 | 108
|
|
109 | 109
|
|
110 | 110
|
|
(10 rows)
|
|
|
|
-- join two tables with FOR SHARE clause
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR SHARE OF t1;
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2.c1, t1.c3, t1.*, t2.*
|
|
-> LockRows
|
|
Output: t1.c1, t2.c1, t1.c3, t1.*, t2.*
|
|
-> Foreign Scan
|
|
Output: t1.c1, t2.c1, t1.c3, t1.*, t2.*
|
|
Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2)
|
|
Remote SQL: SELECT r1."C 1", r1.c3, CASE WHEN (r1.*)::text IS NOT NULL THEN ROW(r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8) END, r2."C 1", CASE WHEN (r2.*)::text IS NOT NULL THEN ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) END FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) ORDER BY r1.c3 ASC NULLS LAST, r1."C 1" ASC NULLS LAST FOR SHARE OF r1
|
|
-> Merge Join
|
|
Output: t1.c1, t1.c3, t1.*, t2.c1, t2.*
|
|
Merge Cond: (t1.c1 = t2.c1)
|
|
-> Sort
|
|
Output: t1.c1, t1.c3, t1.*
|
|
Sort Key: t1.c1
|
|
-> Foreign Scan on public.ft1 t1
|
|
Output: t1.c1, t1.c3, t1.*
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" FOR SHARE
|
|
-> Sort
|
|
Output: t2.c1, t2.*
|
|
Sort Key: t2.c1
|
|
-> Foreign Scan on public.ft2 t2
|
|
Output: t2.c1, t2.*
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1"
|
|
(23 rows)
|
|
|
|
SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR SHARE OF t1;
|
|
c1 | c1
|
|
-----+-----
|
|
101 | 101
|
|
102 | 102
|
|
103 | 103
|
|
104 | 104
|
|
105 | 105
|
|
106 | 106
|
|
107 | 107
|
|
108 | 108
|
|
109 | 109
|
|
110 | 110
|
|
(10 rows)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR SHARE;
|
|
QUERY PLAN
|
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2.c1, t1.c3, t1.*, t2.*
|
|
-> LockRows
|
|
Output: t1.c1, t2.c1, t1.c3, t1.*, t2.*
|
|
-> Foreign Scan
|
|
Output: t1.c1, t2.c1, t1.c3, t1.*, t2.*
|
|
Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2)
|
|
Remote SQL: SELECT r1."C 1", r1.c3, CASE WHEN (r1.*)::text IS NOT NULL THEN ROW(r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8) END, r2."C 1", CASE WHEN (r2.*)::text IS NOT NULL THEN ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) END FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) ORDER BY r1.c3 ASC NULLS LAST, r1."C 1" ASC NULLS LAST FOR SHARE OF r1 FOR SHARE OF r2
|
|
-> Merge Join
|
|
Output: t1.c1, t1.c3, t1.*, t2.c1, t2.*
|
|
Merge Cond: (t1.c1 = t2.c1)
|
|
-> Sort
|
|
Output: t1.c1, t1.c3, t1.*
|
|
Sort Key: t1.c1
|
|
-> Foreign Scan on public.ft1 t1
|
|
Output: t1.c1, t1.c3, t1.*
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" FOR SHARE
|
|
-> Sort
|
|
Output: t2.c1, t2.*
|
|
Sort Key: t2.c1
|
|
-> Foreign Scan on public.ft2 t2
|
|
Output: t2.c1, t2.*
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" FOR SHARE
|
|
(23 rows)
|
|
|
|
SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR SHARE;
|
|
c1 | c1
|
|
-----+-----
|
|
101 | 101
|
|
102 | 102
|
|
103 | 103
|
|
104 | 104
|
|
105 | 105
|
|
106 | 106
|
|
107 | 107
|
|
108 | 108
|
|
109 | 109
|
|
110 | 110
|
|
(10 rows)
|
|
|
|
-- join in CTE
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
WITH t (c1_1, c1_3, c2_1) AS (SELECT t1.c1, t1.c3, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) SELECT c1_1, c2_1 FROM t ORDER BY c1_3, c1_1 OFFSET 100 LIMIT 10;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t.c1_1, t.c2_1, t.c1_3
|
|
CTE t
|
|
-> Foreign Scan
|
|
Output: t1.c1, t1.c3, t2.c1
|
|
Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2)
|
|
Remote SQL: SELECT r1."C 1", r1.c3, r2."C 1" FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1"))))
|
|
-> Sort
|
|
Output: t.c1_1, t.c2_1, t.c1_3
|
|
Sort Key: t.c1_3, t.c1_1
|
|
-> CTE Scan on t
|
|
Output: t.c1_1, t.c2_1, t.c1_3
|
|
(12 rows)
|
|
|
|
WITH t (c1_1, c1_3, c2_1) AS (SELECT t1.c1, t1.c3, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) SELECT c1_1, c2_1 FROM t ORDER BY c1_3, c1_1 OFFSET 100 LIMIT 10;
|
|
c1_1 | c2_1
|
|
------+------
|
|
101 | 101
|
|
102 | 102
|
|
103 | 103
|
|
104 | 104
|
|
105 | 105
|
|
106 | 106
|
|
107 | 107
|
|
108 | 108
|
|
109 | 109
|
|
110 | 110
|
|
(10 rows)
|
|
|
|
-- ctid with whole-row reference
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.ctid, t1, t2, t1.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10;
|
|
QUERY PLAN
|
|
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.ctid, t1.*, t2.*, t1.c1, t1.c3
|
|
-> Foreign Scan
|
|
Output: t1.ctid, t1.*, t2.*, t1.c1, t1.c3
|
|
Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2)
|
|
Remote SQL: SELECT r1.ctid, CASE WHEN (r1.*)::text IS NOT NULL THEN ROW(r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8) END, r1."C 1", r1.c3, CASE WHEN (r2.*)::text IS NOT NULL THEN ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) END FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) ORDER BY r1.c3 ASC NULLS LAST, r1."C 1" ASC NULLS LAST
|
|
(6 rows)
|
|
|
|
-- SEMI JOIN, not pushed down
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1 FROM ft1 t1 WHERE EXISTS (SELECT 1 FROM ft2 t2 WHERE t1.c1 = t2.c1) ORDER BY t1.c1 OFFSET 100 LIMIT 10;
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1
|
|
-> Merge Semi Join
|
|
Output: t1.c1
|
|
Merge Cond: (t1.c1 = t2.c1)
|
|
-> Foreign Scan on public.ft1 t1
|
|
Output: t1.c1
|
|
Remote SQL: SELECT "C 1" FROM "S 1"."T 1" ORDER BY "C 1" ASC NULLS LAST
|
|
-> Materialize
|
|
Output: t2.c1
|
|
-> Foreign Scan on public.ft2 t2
|
|
Output: t2.c1
|
|
Remote SQL: SELECT "C 1" FROM "S 1"."T 1" ORDER BY "C 1" ASC NULLS LAST
|
|
(13 rows)
|
|
|
|
SELECT t1.c1 FROM ft1 t1 WHERE EXISTS (SELECT 1 FROM ft2 t2 WHERE t1.c1 = t2.c1) ORDER BY t1.c1 OFFSET 100 LIMIT 10;
|
|
c1
|
|
-----
|
|
101
|
|
102
|
|
103
|
|
104
|
|
105
|
|
106
|
|
107
|
|
108
|
|
109
|
|
110
|
|
(10 rows)
|
|
|
|
-- ANTI JOIN, not pushed down
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1 FROM ft1 t1 WHERE NOT EXISTS (SELECT 1 FROM ft2 t2 WHERE t1.c1 = t2.c2) ORDER BY t1.c1 OFFSET 100 LIMIT 10;
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1
|
|
-> Merge Anti Join
|
|
Output: t1.c1
|
|
Merge Cond: (t1.c1 = t2.c2)
|
|
-> Foreign Scan on public.ft1 t1
|
|
Output: t1.c1
|
|
Remote SQL: SELECT "C 1" FROM "S 1"."T 1" ORDER BY "C 1" ASC NULLS LAST
|
|
-> Materialize
|
|
Output: t2.c2
|
|
-> Foreign Scan on public.ft2 t2
|
|
Output: t2.c2
|
|
Remote SQL: SELECT c2 FROM "S 1"."T 1" ORDER BY c2 ASC NULLS LAST
|
|
(13 rows)
|
|
|
|
SELECT t1.c1 FROM ft1 t1 WHERE NOT EXISTS (SELECT 1 FROM ft2 t2 WHERE t1.c1 = t2.c2) ORDER BY t1.c1 OFFSET 100 LIMIT 10;
|
|
c1
|
|
-----
|
|
110
|
|
111
|
|
112
|
|
113
|
|
114
|
|
115
|
|
116
|
|
117
|
|
118
|
|
119
|
|
(10 rows)
|
|
|
|
-- CROSS JOIN, not pushed down
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c1 FROM ft1 t1 CROSS JOIN ft2 t2 ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10;
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2.c1
|
|
-> Sort
|
|
Output: t1.c1, t2.c1
|
|
Sort Key: t1.c1, t2.c1
|
|
-> Nested Loop
|
|
Output: t1.c1, t2.c1
|
|
-> Foreign Scan on public.ft1 t1
|
|
Output: t1.c1
|
|
Remote SQL: SELECT "C 1" FROM "S 1"."T 1"
|
|
-> Materialize
|
|
Output: t2.c1
|
|
-> Foreign Scan on public.ft2 t2
|
|
Output: t2.c1
|
|
Remote SQL: SELECT "C 1" FROM "S 1"."T 1"
|
|
(15 rows)
|
|
|
|
SELECT t1.c1, t2.c1 FROM ft1 t1 CROSS JOIN ft2 t2 ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10;
|
|
c1 | c1
|
|
----+-----
|
|
1 | 101
|
|
1 | 102
|
|
1 | 103
|
|
1 | 104
|
|
1 | 105
|
|
1 | 106
|
|
1 | 107
|
|
1 | 108
|
|
1 | 109
|
|
1 | 110
|
|
(10 rows)
|
|
|
|
-- different server, not pushed down. No result expected.
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c1 FROM ft5 t1 JOIN ft6 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10;
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2.c1
|
|
-> Merge Join
|
|
Output: t1.c1, t2.c1
|
|
Merge Cond: (t2.c1 = t1.c1)
|
|
-> Foreign Scan on public.ft6 t2
|
|
Output: t2.c1, t2.c2, t2.c3
|
|
Remote SQL: SELECT c1 FROM "S 1"."T 4" ORDER BY c1 ASC NULLS LAST
|
|
-> Materialize
|
|
Output: t1.c1, t1.c2, t1.c3
|
|
-> Foreign Scan on public.ft5 t1
|
|
Output: t1.c1, t1.c2, t1.c3
|
|
Remote SQL: SELECT c1 FROM "S 1"."T 4" ORDER BY c1 ASC NULLS LAST
|
|
(13 rows)
|
|
|
|
SELECT t1.c1, t2.c1 FROM ft5 t1 JOIN ft6 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10;
|
|
c1 | c1
|
|
----+----
|
|
(0 rows)
|
|
|
|
-- unsafe join conditions (c8 has a UDT), not pushed down. Practically a CROSS
|
|
-- JOIN since c8 in both tables has same value.
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c1 FROM ft1 t1 LEFT JOIN ft2 t2 ON (t1.c8 = t2.c8) ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2.c1
|
|
-> Sort
|
|
Output: t1.c1, t2.c1
|
|
Sort Key: t1.c1, t2.c1
|
|
-> Merge Left Join
|
|
Output: t1.c1, t2.c1
|
|
Merge Cond: (t1.c8 = t2.c8)
|
|
-> Sort
|
|
Output: t1.c1, t1.c8
|
|
Sort Key: t1.c8
|
|
-> Foreign Scan on public.ft1 t1
|
|
Output: t1.c1, t1.c8
|
|
Remote SQL: SELECT "C 1", c8 FROM "S 1"."T 1"
|
|
-> Sort
|
|
Output: t2.c1, t2.c8
|
|
Sort Key: t2.c8
|
|
-> Foreign Scan on public.ft2 t2
|
|
Output: t2.c1, t2.c8
|
|
Remote SQL: SELECT "C 1", c8 FROM "S 1"."T 1"
|
|
(20 rows)
|
|
|
|
SELECT t1.c1, t2.c1 FROM ft1 t1 LEFT JOIN ft2 t2 ON (t1.c8 = t2.c8) ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10;
|
|
c1 | c1
|
|
----+-----
|
|
1 | 101
|
|
1 | 102
|
|
1 | 103
|
|
1 | 104
|
|
1 | 105
|
|
1 | 106
|
|
1 | 107
|
|
1 | 108
|
|
1 | 109
|
|
1 | 110
|
|
(10 rows)
|
|
|
|
-- unsafe conditions on one side (c8 has a UDT), not pushed down.
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c1 FROM ft1 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE t1.c8 = 'foo' ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10;
|
|
QUERY PLAN
|
|
-----------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2.c1, t1.c3
|
|
-> Sort
|
|
Output: t1.c1, t2.c1, t1.c3
|
|
Sort Key: t1.c3, t1.c1
|
|
-> Hash Right Join
|
|
Output: t1.c1, t2.c1, t1.c3
|
|
Hash Cond: (t2.c1 = t1.c1)
|
|
-> Foreign Scan on public.ft2 t2
|
|
Output: t2.c1
|
|
Remote SQL: SELECT "C 1" FROM "S 1"."T 1"
|
|
-> Hash
|
|
Output: t1.c1, t1.c3
|
|
-> Foreign Scan on public.ft1 t1
|
|
Output: t1.c1, t1.c3
|
|
Filter: (t1.c8 = 'foo'::user_enum)
|
|
Remote SQL: SELECT "C 1", c3, c8 FROM "S 1"."T 1"
|
|
(17 rows)
|
|
|
|
SELECT t1.c1, t2.c1 FROM ft1 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE t1.c8 = 'foo' ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10;
|
|
c1 | c1
|
|
-----+-----
|
|
101 | 101
|
|
102 | 102
|
|
103 | 103
|
|
104 | 104
|
|
105 | 105
|
|
106 | 106
|
|
107 | 107
|
|
108 | 108
|
|
109 | 109
|
|
110 | 110
|
|
(10 rows)
|
|
|
|
-- join where unsafe to pushdown condition in WHERE clause has a column not
|
|
-- in the SELECT clause. In this test unsafe clause needs to have column
|
|
-- references from both joining sides so that the clause is not pushed down
|
|
-- into one of the joining sides.
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE t1.c8 = t2.c8 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, t2.c1, t1.c3
|
|
-> Sort
|
|
Output: t1.c1, t2.c1, t1.c3
|
|
Sort Key: t1.c3, t1.c1
|
|
-> Foreign Scan
|
|
Output: t1.c1, t2.c1, t1.c3
|
|
Filter: (t1.c8 = t2.c8)
|
|
Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2)
|
|
Remote SQL: SELECT r1."C 1", r1.c3, r2."C 1", r1.c8, r2.c8 FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1"))))
|
|
(10 rows)
|
|
|
|
SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE t1.c8 = t2.c8 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10;
|
|
c1 | c1
|
|
-----+-----
|
|
101 | 101
|
|
102 | 102
|
|
103 | 103
|
|
104 | 104
|
|
105 | 105
|
|
106 | 106
|
|
107 | 107
|
|
108 | 108
|
|
109 | 109
|
|
110 | 110
|
|
(10 rows)
|
|
|
|
-- Aggregate after UNION, for testing setrefs
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1c1, avg(t1c1 + t2c1) FROM (SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) UNION SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) AS t (t1c1, t2c1) GROUP BY t1c1 ORDER BY t1c1 OFFSET 100 LIMIT 10;
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1.c1, (avg((t1.c1 + t2.c1)))
|
|
-> Sort
|
|
Output: t1.c1, (avg((t1.c1 + t2.c1)))
|
|
Sort Key: t1.c1
|
|
-> HashAggregate
|
|
Output: t1.c1, avg((t1.c1 + t2.c1))
|
|
Group Key: t1.c1
|
|
-> HashAggregate
|
|
Output: t1.c1, t2.c1
|
|
Group Key: t1.c1, t2.c1
|
|
-> Append
|
|
-> Foreign Scan
|
|
Output: t1.c1, t2.c1
|
|
Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2)
|
|
Remote SQL: SELECT r1."C 1", r2."C 1" FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1"))))
|
|
-> Foreign Scan
|
|
Output: t1_1.c1, t2_1.c1
|
|
Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2)
|
|
Remote SQL: SELECT r1."C 1", r2."C 1" FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1"))))
|
|
(20 rows)
|
|
|
|
SELECT t1c1, avg(t1c1 + t2c1) FROM (SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) UNION SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) AS t (t1c1, t2c1) GROUP BY t1c1 ORDER BY t1c1 OFFSET 100 LIMIT 10;
|
|
t1c1 | avg
|
|
------+----------------------
|
|
101 | 202.0000000000000000
|
|
102 | 204.0000000000000000
|
|
103 | 206.0000000000000000
|
|
104 | 208.0000000000000000
|
|
105 | 210.0000000000000000
|
|
106 | 212.0000000000000000
|
|
107 | 214.0000000000000000
|
|
108 | 216.0000000000000000
|
|
109 | 218.0000000000000000
|
|
110 | 220.0000000000000000
|
|
(10 rows)
|
|
|
|
-- join with lateral reference
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1."C 1" FROM "S 1"."T 1" t1, LATERAL (SELECT DISTINCT t2.c1, t3.c1 FROM ft1 t2, ft2 t3 WHERE t2.c1 = t3.c1 AND t2.c2 = t1.c2) q ORDER BY t1."C 1" OFFSET 10 LIMIT 10;
|
|
QUERY PLAN
|
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: t1."C 1"
|
|
-> Nested Loop
|
|
Output: t1."C 1"
|
|
-> Index Scan using t1_pkey on "S 1"."T 1" t1
|
|
Output: t1."C 1", t1.c2, t1.c3, t1.c4, t1.c5, t1.c6, t1.c7, t1.c8
|
|
-> HashAggregate
|
|
Output: t2.c1, t3.c1
|
|
Group Key: t2.c1, t3.c1
|
|
-> Foreign Scan
|
|
Output: t2.c1, t3.c1
|
|
Relations: (public.ft1 t2) INNER JOIN (public.ft2 t3)
|
|
Remote SQL: SELECT r1."C 1", r2."C 1" FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")) AND ((r1.c2 = $1::integer))))
|
|
(13 rows)
|
|
|
|
SELECT t1."C 1" FROM "S 1"."T 1" t1, LATERAL (SELECT DISTINCT t2.c1, t3.c1 FROM ft1 t2, ft2 t3 WHERE t2.c1 = t3.c1 AND t2.c2 = t1.c2) q ORDER BY t1."C 1" OFFSET 10 LIMIT 10;
|
|
C 1
|
|
-----
|
|
1
|
|
1
|
|
1
|
|
1
|
|
1
|
|
1
|
|
1
|
|
1
|
|
1
|
|
1
|
|
(10 rows)
|
|
|
|
-- non-Var items in targelist of the nullable rel of a join preventing
|
|
-- push-down in some cases
|
|
-- unable to push {ft1, ft2}
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT q.a, ft2.c1 FROM (SELECT 13 FROM ft1 WHERE c1 = 13) q(a) RIGHT JOIN ft2 ON (q.a = ft2.c1) WHERE ft2.c1 BETWEEN 10 AND 15;
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------------------------------------
|
|
Nested Loop Left Join
|
|
Output: (13), ft2.c1
|
|
Join Filter: (13 = ft2.c1)
|
|
-> Foreign Scan on public.ft2
|
|
Output: ft2.c1
|
|
Remote SQL: SELECT "C 1" FROM "S 1"."T 1" WHERE (("C 1" >= 10)) AND (("C 1" <= 15)) ORDER BY "C 1" ASC NULLS LAST
|
|
-> Materialize
|
|
Output: (13)
|
|
-> Foreign Scan on public.ft1
|
|
Output: 13
|
|
Remote SQL: SELECT NULL FROM "S 1"."T 1" WHERE (("C 1" = 13))
|
|
(11 rows)
|
|
|
|
SELECT q.a, ft2.c1 FROM (SELECT 13 FROM ft1 WHERE c1 = 13) q(a) RIGHT JOIN ft2 ON (q.a = ft2.c1) WHERE ft2.c1 BETWEEN 10 AND 15;
|
|
a | c1
|
|
----+----
|
|
| 10
|
|
| 11
|
|
| 12
|
|
13 | 13
|
|
| 14
|
|
| 15
|
|
(6 rows)
|
|
|
|
-- ok to push {ft1, ft2} but not {ft1, ft2, ft4}
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT ft4.c1, q.* FROM ft4 LEFT JOIN (SELECT 13, ft1.c1, ft2.c1 FROM ft1 RIGHT JOIN ft2 ON (ft1.c1 = ft2.c1) WHERE ft1.c1 = 12) q(a, b, c) ON (ft4.c1 = q.b) WHERE ft4.c1 BETWEEN 10 AND 15;
|
|
QUERY PLAN
|
|
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Nested Loop Left Join
|
|
Output: ft4.c1, (13), ft1.c1, ft2.c1
|
|
Join Filter: (ft4.c1 = ft1.c1)
|
|
-> Foreign Scan on public.ft4
|
|
Output: ft4.c1, ft4.c2, ft4.c3
|
|
Remote SQL: SELECT c1 FROM "S 1"."T 3" WHERE ((c1 >= 10)) AND ((c1 <= 15))
|
|
-> Materialize
|
|
Output: ft1.c1, ft2.c1, (13)
|
|
-> Foreign Scan
|
|
Output: ft1.c1, ft2.c1, 13
|
|
Relations: (public.ft1) INNER JOIN (public.ft2)
|
|
Remote SQL: SELECT r4."C 1", r5."C 1" FROM ("S 1"."T 1" r4 INNER JOIN "S 1"."T 1" r5 ON (((r5."C 1" = 12)) AND ((r4."C 1" = 12)))) ORDER BY r4."C 1" ASC NULLS LAST
|
|
(12 rows)
|
|
|
|
SELECT ft4.c1, q.* FROM ft4 LEFT JOIN (SELECT 13, ft1.c1, ft2.c1 FROM ft1 RIGHT JOIN ft2 ON (ft1.c1 = ft2.c1) WHERE ft1.c1 = 12) q(a, b, c) ON (ft4.c1 = q.b) WHERE ft4.c1 BETWEEN 10 AND 15;
|
|
c1 | a | b | c
|
|
----+----+----+----
|
|
10 | | |
|
|
12 | 13 | 12 | 12
|
|
14 | | |
|
|
(3 rows)
|
|
|
|
-- join with nullable side with some columns with null values
|
|
UPDATE ft5 SET c3 = null where c1 % 9 = 0;
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT ft5, ft5.c1, ft5.c2, ft5.c3, ft4.c1, ft4.c2 FROM ft5 left join ft4 on ft5.c1 = ft4.c1 WHERE ft4.c1 BETWEEN 10 and 30 ORDER BY ft5.c1, ft4.c1;
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Foreign Scan
|
|
Output: ft5.*, ft5.c1, ft5.c2, ft5.c3, ft4.c1, ft4.c2
|
|
Relations: (public.ft5) INNER JOIN (public.ft4)
|
|
Remote SQL: SELECT CASE WHEN (r1.*)::text IS NOT NULL THEN ROW(r1.c1, r1.c2, r1.c3) END, r1.c1, r1.c2, r1.c3, r2.c1, r2.c2 FROM ("S 1"."T 4" r1 INNER JOIN "S 1"."T 3" r2 ON (((r1.c1 = r2.c1)) AND ((r2.c1 >= 10)) AND ((r2.c1 <= 30)))) ORDER BY r1.c1 ASC NULLS LAST
|
|
(4 rows)
|
|
|
|
SELECT ft5, ft5.c1, ft5.c2, ft5.c3, ft4.c1, ft4.c2 FROM ft5 left join ft4 on ft5.c1 = ft4.c1 WHERE ft4.c1 BETWEEN 10 and 30 ORDER BY ft5.c1, ft4.c1;
|
|
ft5 | c1 | c2 | c3 | c1 | c2
|
|
----------------+----+----+--------+----+----
|
|
(12,13,AAA012) | 12 | 13 | AAA012 | 12 | 13
|
|
(18,19,) | 18 | 19 | | 18 | 19
|
|
(24,25,AAA024) | 24 | 25 | AAA024 | 24 | 25
|
|
(30,31,AAA030) | 30 | 31 | AAA030 | 30 | 31
|
|
(4 rows)
|
|
|
|
-- check join pushdown in situations where multiple userids are involved
|
|
CREATE ROLE regress_view_owner;
|
|
CREATE USER MAPPING FOR regress_view_owner SERVER loopback;
|
|
GRANT SELECT ON ft4 TO regress_view_owner;
|
|
GRANT SELECT ON ft5 TO regress_view_owner;
|
|
CREATE VIEW v4 AS SELECT * FROM ft4;
|
|
CREATE VIEW v5 AS SELECT * FROM ft5;
|
|
ALTER VIEW v5 OWNER TO regress_view_owner;
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN v5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; -- can't be pushed down, different view owners
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------
|
|
Limit
|
|
Output: ft4.c1, ft5.c2, ft5.c1
|
|
-> Sort
|
|
Output: ft4.c1, ft5.c2, ft5.c1
|
|
Sort Key: ft4.c1, ft5.c1
|
|
-> Hash Left Join
|
|
Output: ft4.c1, ft5.c2, ft5.c1
|
|
Hash Cond: (ft4.c1 = ft5.c1)
|
|
-> Foreign Scan on public.ft4
|
|
Output: ft4.c1, ft4.c2, ft4.c3
|
|
Remote SQL: SELECT c1 FROM "S 1"."T 3"
|
|
-> Hash
|
|
Output: ft5.c2, ft5.c1
|
|
-> Foreign Scan on public.ft5
|
|
Output: ft5.c2, ft5.c1
|
|
Remote SQL: SELECT c1, c2 FROM "S 1"."T 4"
|
|
(16 rows)
|
|
|
|
SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN v5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10;
|
|
c1 | c2
|
|
----+----
|
|
22 |
|
|
24 | 25
|
|
26 |
|
|
28 |
|
|
30 | 31
|
|
32 |
|
|
34 |
|
|
36 | 37
|
|
38 |
|
|
40 |
|
|
(10 rows)
|
|
|
|
ALTER VIEW v4 OWNER TO regress_view_owner;
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN v5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; -- can be pushed down
|
|
QUERY PLAN
|
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: ft4.c1, ft5.c2, ft5.c1
|
|
-> Foreign Scan
|
|
Output: ft4.c1, ft5.c2, ft5.c1
|
|
Relations: (public.ft4) LEFT JOIN (public.ft5)
|
|
Remote SQL: SELECT r6.c1, r9.c2, r9.c1 FROM ("S 1"."T 3" r6 LEFT JOIN "S 1"."T 4" r9 ON (((r6.c1 = r9.c1)))) ORDER BY r6.c1 ASC NULLS LAST, r9.c1 ASC NULLS LAST
|
|
(6 rows)
|
|
|
|
SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN v5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10;
|
|
c1 | c2
|
|
----+----
|
|
22 |
|
|
24 | 25
|
|
26 |
|
|
28 |
|
|
30 | 31
|
|
32 |
|
|
34 |
|
|
36 | 37
|
|
38 |
|
|
40 |
|
|
(10 rows)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; -- can't be pushed down, view owner not current user
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------
|
|
Limit
|
|
Output: ft4.c1, t2.c2, t2.c1
|
|
-> Sort
|
|
Output: ft4.c1, t2.c2, t2.c1
|
|
Sort Key: ft4.c1, t2.c1
|
|
-> Hash Left Join
|
|
Output: ft4.c1, t2.c2, t2.c1
|
|
Hash Cond: (ft4.c1 = t2.c1)
|
|
-> Foreign Scan on public.ft4
|
|
Output: ft4.c1, ft4.c2, ft4.c3
|
|
Remote SQL: SELECT c1 FROM "S 1"."T 3"
|
|
-> Hash
|
|
Output: t2.c2, t2.c1
|
|
-> Foreign Scan on public.ft5 t2
|
|
Output: t2.c2, t2.c1
|
|
Remote SQL: SELECT c1, c2 FROM "S 1"."T 4"
|
|
(16 rows)
|
|
|
|
SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10;
|
|
c1 | c2
|
|
----+----
|
|
22 |
|
|
24 | 25
|
|
26 |
|
|
28 |
|
|
30 | 31
|
|
32 |
|
|
34 |
|
|
36 | 37
|
|
38 |
|
|
40 |
|
|
(10 rows)
|
|
|
|
ALTER VIEW v4 OWNER TO CURRENT_USER;
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; -- can be pushed down
|
|
QUERY PLAN
|
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: ft4.c1, t2.c2, t2.c1
|
|
-> Foreign Scan
|
|
Output: ft4.c1, t2.c2, t2.c1
|
|
Relations: (public.ft4) LEFT JOIN (public.ft5 t2)
|
|
Remote SQL: SELECT r6.c1, r2.c2, r2.c1 FROM ("S 1"."T 3" r6 LEFT JOIN "S 1"."T 4" r2 ON (((r6.c1 = r2.c1)))) ORDER BY r6.c1 ASC NULLS LAST, r2.c1 ASC NULLS LAST
|
|
(6 rows)
|
|
|
|
SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10;
|
|
c1 | c2
|
|
----+----
|
|
22 |
|
|
24 | 25
|
|
26 |
|
|
28 |
|
|
30 | 31
|
|
32 |
|
|
34 |
|
|
36 | 37
|
|
38 |
|
|
40 |
|
|
(10 rows)
|
|
|
|
ALTER VIEW v4 OWNER TO regress_view_owner;
|
|
-- cleanup
|
|
DROP OWNED BY regress_view_owner;
|
|
DROP ROLE regress_view_owner;
|
|
-- ===================================================================
|
|
-- Aggregate and grouping queries
|
|
-- ===================================================================
|
|
-- Simple aggregates
|
|
explain (verbose, costs off)
|
|
select count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), sum(c1) * (random() <= 1)::int as sum2 from ft1 where c2 < 5 group by c2 order by 1, 2;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Result
|
|
Output: (count(c6)), (sum(c1)), (avg(c1)), (min(c2)), (max(c1)), (stddev(c2)), ((sum(c1)) * ((random() <= '1'::double precision))::integer), c2
|
|
-> Sort
|
|
Output: (count(c6)), (sum(c1)), (avg(c1)), (min(c2)), (max(c1)), (stddev(c2)), c2
|
|
Sort Key: (count(ft1.c6)), (sum(ft1.c1))
|
|
-> Foreign Scan
|
|
Output: (count(c6)), (sum(c1)), (avg(c1)), (min(c2)), (max(c1)), (stddev(c2)), c2
|
|
Relations: Aggregate on (public.ft1)
|
|
Remote SQL: SELECT count(c6), sum("C 1"), avg("C 1"), min(c2), max("C 1"), stddev(c2), c2 FROM "S 1"."T 1" WHERE ((c2 < 5)) GROUP BY c2
|
|
(9 rows)
|
|
|
|
select count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), sum(c1) * (random() <= 1)::int as sum2 from ft1 where c2 < 5 group by c2 order by 1, 2;
|
|
count | sum | avg | min | max | stddev | sum2
|
|
-------+-------+----------------------+-----+------+--------+-------
|
|
100 | 49600 | 496.0000000000000000 | 1 | 991 | 0 | 49600
|
|
100 | 49700 | 497.0000000000000000 | 2 | 992 | 0 | 49700
|
|
100 | 49800 | 498.0000000000000000 | 3 | 993 | 0 | 49800
|
|
100 | 49900 | 499.0000000000000000 | 4 | 994 | 0 | 49900
|
|
100 | 50500 | 505.0000000000000000 | 0 | 1000 | 0 | 50500
|
|
(5 rows)
|
|
|
|
-- Aggregate is not pushed down as aggregation contains random()
|
|
explain (verbose, costs off)
|
|
select sum(c1 * (random() <= 1)::int) as sum, avg(c1) from ft1;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------
|
|
Aggregate
|
|
Output: sum((c1 * ((random() <= '1'::double precision))::integer)), avg(c1)
|
|
-> Foreign Scan on public.ft1
|
|
Output: c1
|
|
Remote SQL: SELECT "C 1" FROM "S 1"."T 1"
|
|
(5 rows)
|
|
|
|
-- Aggregate over join query
|
|
explain (verbose, costs off)
|
|
select count(*), sum(t1.c1), avg(t2.c1) from ft1 t1 inner join ft1 t2 on (t1.c2 = t2.c2) where t1.c2 = 6;
|
|
QUERY PLAN
|
|
--------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Foreign Scan
|
|
Output: (count(*)), (sum(t1.c1)), (avg(t2.c1))
|
|
Relations: Aggregate on ((public.ft1 t1) INNER JOIN (public.ft1 t2))
|
|
Remote SQL: SELECT count(*), sum(r1."C 1"), avg(r2."C 1") FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r2.c2 = 6)) AND ((r1.c2 = 6))))
|
|
(4 rows)
|
|
|
|
select count(*), sum(t1.c1), avg(t2.c1) from ft1 t1 inner join ft1 t2 on (t1.c2 = t2.c2) where t1.c2 = 6;
|
|
count | sum | avg
|
|
-------+---------+----------------------
|
|
10000 | 5010000 | 501.0000000000000000
|
|
(1 row)
|
|
|
|
-- Not pushed down due to local conditions present in underneath input rel
|
|
explain (verbose, costs off)
|
|
select sum(t1.c1), count(t2.c1) from ft1 t1 inner join ft2 t2 on (t1.c1 = t2.c1) where ((t1.c1 * t2.c1)/(t1.c1 * t2.c1)) * random() <= 1;
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------------------------------------------------------------
|
|
Aggregate
|
|
Output: sum(t1.c1), count(t2.c1)
|
|
-> Foreign Scan
|
|
Output: t1.c1, t2.c1
|
|
Filter: (((((t1.c1 * t2.c1) / (t1.c1 * t2.c1)))::double precision * random()) <= '1'::double precision)
|
|
Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2)
|
|
Remote SQL: SELECT r1."C 1", r2."C 1" FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1"))))
|
|
(7 rows)
|
|
|
|
-- GROUP BY clause having expressions
|
|
explain (verbose, costs off)
|
|
select c2/2, sum(c2) * (c2/2) from ft1 group by c2/2 order by c2/2;
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------------------------
|
|
Sort
|
|
Output: ((c2 / 2)), ((sum(c2) * (c2 / 2)))
|
|
Sort Key: ((ft1.c2 / 2))
|
|
-> Foreign Scan
|
|
Output: ((c2 / 2)), ((sum(c2) * (c2 / 2)))
|
|
Relations: Aggregate on (public.ft1)
|
|
Remote SQL: SELECT (c2 / 2), (sum(c2) * (c2 / 2)) FROM "S 1"."T 1" GROUP BY ((c2 / 2))
|
|
(7 rows)
|
|
|
|
select c2/2, sum(c2) * (c2/2) from ft1 group by c2/2 order by c2/2;
|
|
?column? | ?column?
|
|
----------+----------
|
|
0 | 0
|
|
1 | 500
|
|
2 | 1800
|
|
3 | 3900
|
|
4 | 6800
|
|
(5 rows)
|
|
|
|
-- Aggregates in subquery are pushed down.
|
|
explain (verbose, costs off)
|
|
select count(x.a), sum(x.a) from (select c2 a, sum(c1) b from ft1 group by c2, sqrt(c1) order by 1, 2) x;
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------------------------------------------
|
|
Aggregate
|
|
Output: count(ft1.c2), sum(ft1.c2)
|
|
-> Sort
|
|
Output: ft1.c2, (sum(ft1.c1)), (sqrt((ft1.c1)::double precision))
|
|
Sort Key: ft1.c2, (sum(ft1.c1))
|
|
-> Foreign Scan
|
|
Output: ft1.c2, (sum(ft1.c1)), (sqrt((ft1.c1)::double precision))
|
|
Relations: Aggregate on (public.ft1)
|
|
Remote SQL: SELECT c2, sum("C 1"), sqrt("C 1") FROM "S 1"."T 1" GROUP BY c2, (sqrt("C 1"))
|
|
(9 rows)
|
|
|
|
select count(x.a), sum(x.a) from (select c2 a, sum(c1) b from ft1 group by c2, sqrt(c1) order by 1, 2) x;
|
|
count | sum
|
|
-------+------
|
|
1000 | 4500
|
|
(1 row)
|
|
|
|
-- Aggregate is still pushed down by taking unshippable expression out
|
|
explain (verbose, costs off)
|
|
select c2 * (random() <= 1)::int as sum1, sum(c1) * c2 as sum2 from ft1 group by c2 order by 1, 2;
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------------
|
|
Sort
|
|
Output: ((c2 * ((random() <= '1'::double precision))::integer)), ((sum(c1) * c2)), c2
|
|
Sort Key: ((ft1.c2 * ((random() <= '1'::double precision))::integer)), ((sum(ft1.c1) * ft1.c2))
|
|
-> Foreign Scan
|
|
Output: (c2 * ((random() <= '1'::double precision))::integer), ((sum(c1) * c2)), c2
|
|
Relations: Aggregate on (public.ft1)
|
|
Remote SQL: SELECT (sum("C 1") * c2), c2 FROM "S 1"."T 1" GROUP BY c2
|
|
(7 rows)
|
|
|
|
select c2 * (random() <= 1)::int as sum1, sum(c1) * c2 as sum2 from ft1 group by c2 order by 1, 2;
|
|
sum1 | sum2
|
|
------+--------
|
|
0 | 0
|
|
1 | 49600
|
|
2 | 99400
|
|
3 | 149400
|
|
4 | 199600
|
|
5 | 250000
|
|
6 | 300600
|
|
7 | 351400
|
|
8 | 402400
|
|
9 | 453600
|
|
(10 rows)
|
|
|
|
-- Aggregate with unshippable GROUP BY clause are not pushed
|
|
explain (verbose, costs off)
|
|
select c2 * (random() <= 1)::int as c2 from ft2 group by c2 * (random() <= 1)::int order by 1;
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------
|
|
Sort
|
|
Output: ((c2 * ((random() <= '1'::double precision))::integer))
|
|
Sort Key: ((ft2.c2 * ((random() <= '1'::double precision))::integer))
|
|
-> HashAggregate
|
|
Output: ((c2 * ((random() <= '1'::double precision))::integer))
|
|
Group Key: (ft2.c2 * ((random() <= '1'::double precision))::integer)
|
|
-> Foreign Scan on public.ft2
|
|
Output: (c2 * ((random() <= '1'::double precision))::integer)
|
|
Remote SQL: SELECT c2 FROM "S 1"."T 1"
|
|
(9 rows)
|
|
|
|
-- GROUP BY clause in various forms, cardinal, alias and constant expression
|
|
explain (verbose, costs off)
|
|
select count(c2) w, c2 x, 5 y, 7.0 z from ft1 group by 2, y, 9.0::int order by 2;
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------------------------------------------
|
|
Sort
|
|
Output: (count(c2)), c2, 5, 7.0, 9
|
|
Sort Key: ft1.c2
|
|
-> Foreign Scan
|
|
Output: (count(c2)), c2, 5, 7.0, 9
|
|
Relations: Aggregate on (public.ft1)
|
|
Remote SQL: SELECT count(c2), c2, 5, 7.0, 9 FROM "S 1"."T 1" GROUP BY c2, 5::integer, 9::integer
|
|
(7 rows)
|
|
|
|
select count(c2) w, c2 x, 5 y, 7.0 z from ft1 group by 2, y, 9.0::int order by 2;
|
|
w | x | y | z
|
|
-----+---+---+-----
|
|
100 | 0 | 5 | 7.0
|
|
100 | 1 | 5 | 7.0
|
|
100 | 2 | 5 | 7.0
|
|
100 | 3 | 5 | 7.0
|
|
100 | 4 | 5 | 7.0
|
|
100 | 5 | 5 | 7.0
|
|
100 | 6 | 5 | 7.0
|
|
100 | 7 | 5 | 7.0
|
|
100 | 8 | 5 | 7.0
|
|
100 | 9 | 5 | 7.0
|
|
(10 rows)
|
|
|
|
-- Testing HAVING clause shippability
|
|
explain (verbose, costs off)
|
|
select c2, sum(c1) from ft2 group by c2 having avg(c1) < 500 and sum(c1) < 49800 order by c2;
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------------------------------------------------------------------------
|
|
Sort
|
|
Output: c2, (sum(c1))
|
|
Sort Key: ft2.c2
|
|
-> Foreign Scan
|
|
Output: c2, (sum(c1))
|
|
Relations: Aggregate on (public.ft2)
|
|
Remote SQL: SELECT c2, sum("C 1") FROM "S 1"."T 1" GROUP BY c2 HAVING ((avg("C 1") < 500::numeric)) AND ((sum("C 1") < 49800))
|
|
(7 rows)
|
|
|
|
select c2, sum(c1) from ft2 group by c2 having avg(c1) < 500 and sum(c1) < 49800 order by c2;
|
|
c2 | sum
|
|
----+-------
|
|
1 | 49600
|
|
2 | 49700
|
|
(2 rows)
|
|
|
|
-- Unshippable HAVING clause will be evaluated locally, and other qual in HAVING clause is pushed down
|
|
explain (verbose, costs off)
|
|
select count(*) from (select c5, count(c1) from ft1 group by c5, sqrt(c2) having (avg(c1) / avg(c1)) * random() <= 1 and avg(c1) < 500) x;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Aggregate
|
|
Output: count(*)
|
|
-> Foreign Scan
|
|
Output: ft1.c5, NULL::bigint, (sqrt((ft1.c2)::double precision))
|
|
Filter: (((((avg(ft1.c1)) / (avg(ft1.c1))))::double precision * random()) <= '1'::double precision)
|
|
Relations: Aggregate on (public.ft1)
|
|
Remote SQL: SELECT c5, NULL::bigint, sqrt(c2), avg("C 1") FROM "S 1"."T 1" GROUP BY c5, (sqrt(c2)) HAVING ((avg("C 1") < 500::numeric))
|
|
(7 rows)
|
|
|
|
select count(*) from (select c5, count(c1) from ft1 group by c5, sqrt(c2) having (avg(c1) / avg(c1)) * random() <= 1 and avg(c1) < 500) x;
|
|
count
|
|
-------
|
|
49
|
|
(1 row)
|
|
|
|
-- Aggregate in HAVING clause is not pushable, and thus aggregation is not pushed down
|
|
explain (verbose, costs off)
|
|
select sum(c1) from ft1 group by c2 having avg(c1 * (random() <= 1)::int) > 100 order by 1;
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------------
|
|
Sort
|
|
Output: (sum(c1)), c2
|
|
Sort Key: (sum(ft1.c1))
|
|
-> HashAggregate
|
|
Output: sum(c1), c2
|
|
Group Key: ft1.c2
|
|
Filter: (avg((ft1.c1 * ((random() <= '1'::double precision))::integer)) > '100'::numeric)
|
|
-> Foreign Scan on public.ft1
|
|
Output: c2, c1
|
|
Remote SQL: SELECT "C 1", c2 FROM "S 1"."T 1"
|
|
(10 rows)
|
|
|
|
-- Testing ORDER BY, DISTINCT, FILTER, Ordered-sets and VARIADIC within aggregates
|
|
-- ORDER BY within aggregate, same column used to order
|
|
explain (verbose, costs off)
|
|
select array_agg(c1 order by c1) from ft1 where c1 < 100 group by c2 order by 1;
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------------------------------------------------------------------
|
|
Sort
|
|
Output: (array_agg(c1 ORDER BY c1)), c2
|
|
Sort Key: (array_agg(ft1.c1 ORDER BY ft1.c1))
|
|
-> Foreign Scan
|
|
Output: (array_agg(c1 ORDER BY c1)), c2
|
|
Relations: Aggregate on (public.ft1)
|
|
Remote SQL: SELECT array_agg("C 1" ORDER BY "C 1" ASC NULLS LAST), c2 FROM "S 1"."T 1" WHERE (("C 1" < 100)) GROUP BY c2
|
|
(7 rows)
|
|
|
|
select array_agg(c1 order by c1) from ft1 where c1 < 100 group by c2 order by 1;
|
|
array_agg
|
|
--------------------------------
|
|
{1,11,21,31,41,51,61,71,81,91}
|
|
{2,12,22,32,42,52,62,72,82,92}
|
|
{3,13,23,33,43,53,63,73,83,93}
|
|
{4,14,24,34,44,54,64,74,84,94}
|
|
{5,15,25,35,45,55,65,75,85,95}
|
|
{6,16,26,36,46,56,66,76,86,96}
|
|
{7,17,27,37,47,57,67,77,87,97}
|
|
{8,18,28,38,48,58,68,78,88,98}
|
|
{9,19,29,39,49,59,69,79,89,99}
|
|
{10,20,30,40,50,60,70,80,90}
|
|
(10 rows)
|
|
|
|
-- ORDER BY within aggregate, different column used to order also using DESC
|
|
explain (verbose, costs off)
|
|
select array_agg(c5 order by c1 desc) from ft2 where c2 = 6 and c1 < 50;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------------------------------------------
|
|
Foreign Scan
|
|
Output: (array_agg(c5 ORDER BY c1 DESC))
|
|
Relations: Aggregate on (public.ft2)
|
|
Remote SQL: SELECT array_agg(c5 ORDER BY "C 1" DESC NULLS FIRST) FROM "S 1"."T 1" WHERE (("C 1" < 50)) AND ((c2 = 6))
|
|
(4 rows)
|
|
|
|
select array_agg(c5 order by c1 desc) from ft2 where c2 = 6 and c1 < 50;
|
|
array_agg
|
|
------------------------------------------------------------------------------------------------------------------------------------------
|
|
{"Mon Feb 16 00:00:00 1970","Fri Feb 06 00:00:00 1970","Tue Jan 27 00:00:00 1970","Sat Jan 17 00:00:00 1970","Wed Jan 07 00:00:00 1970"}
|
|
(1 row)
|
|
|
|
-- DISTINCT within aggregate
|
|
explain (verbose, costs off)
|
|
select array_agg(distinct (t1.c1)%5) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1;
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Sort
|
|
Output: (array_agg(DISTINCT (t1.c1 % 5))), ((t2.c1 % 3))
|
|
Sort Key: (array_agg(DISTINCT (t1.c1 % 5)))
|
|
-> Foreign Scan
|
|
Output: (array_agg(DISTINCT (t1.c1 % 5))), ((t2.c1 % 3))
|
|
Relations: Aggregate on ((public.ft4 t1) FULL JOIN (public.ft5 t2))
|
|
Remote SQL: SELECT array_agg(DISTINCT (r1.c1 % 5)), (r2.c1 % 3) FROM ("S 1"."T 3" r1 FULL JOIN "S 1"."T 4" r2 ON (((r1.c1 = r2.c1)))) WHERE (((r1.c1 < 20) OR ((r1.c1 IS NULL) AND (r2.c1 < 5)))) GROUP BY ((r2.c1 % 3))
|
|
(7 rows)
|
|
|
|
select array_agg(distinct (t1.c1)%5) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1;
|
|
array_agg
|
|
--------------
|
|
{0,1,2,3,4}
|
|
{1,2,3,NULL}
|
|
(2 rows)
|
|
|
|
-- DISTINCT combined with ORDER BY within aggregate
|
|
explain (verbose, costs off)
|
|
select array_agg(distinct (t1.c1)%5 order by (t1.c1)%5) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1;
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Sort
|
|
Output: (array_agg(DISTINCT (t1.c1 % 5) ORDER BY (t1.c1 % 5))), ((t2.c1 % 3))
|
|
Sort Key: (array_agg(DISTINCT (t1.c1 % 5) ORDER BY (t1.c1 % 5)))
|
|
-> Foreign Scan
|
|
Output: (array_agg(DISTINCT (t1.c1 % 5) ORDER BY (t1.c1 % 5))), ((t2.c1 % 3))
|
|
Relations: Aggregate on ((public.ft4 t1) FULL JOIN (public.ft5 t2))
|
|
Remote SQL: SELECT array_agg(DISTINCT (r1.c1 % 5) ORDER BY ((r1.c1 % 5)) ASC NULLS LAST), (r2.c1 % 3) FROM ("S 1"."T 3" r1 FULL JOIN "S 1"."T 4" r2 ON (((r1.c1 = r2.c1)))) WHERE (((r1.c1 < 20) OR ((r1.c1 IS NULL) AND (r2.c1 < 5)))) GROUP BY ((r2.c1 % 3))
|
|
(7 rows)
|
|
|
|
select array_agg(distinct (t1.c1)%5 order by (t1.c1)%5) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1;
|
|
array_agg
|
|
--------------
|
|
{0,1,2,3,4}
|
|
{1,2,3,NULL}
|
|
(2 rows)
|
|
|
|
explain (verbose, costs off)
|
|
select array_agg(distinct (t1.c1)%5 order by (t1.c1)%5 desc nulls last) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Sort
|
|
Output: (array_agg(DISTINCT (t1.c1 % 5) ORDER BY (t1.c1 % 5) DESC NULLS LAST)), ((t2.c1 % 3))
|
|
Sort Key: (array_agg(DISTINCT (t1.c1 % 5) ORDER BY (t1.c1 % 5) DESC NULLS LAST))
|
|
-> Foreign Scan
|
|
Output: (array_agg(DISTINCT (t1.c1 % 5) ORDER BY (t1.c1 % 5) DESC NULLS LAST)), ((t2.c1 % 3))
|
|
Relations: Aggregate on ((public.ft4 t1) FULL JOIN (public.ft5 t2))
|
|
Remote SQL: SELECT array_agg(DISTINCT (r1.c1 % 5) ORDER BY ((r1.c1 % 5)) DESC NULLS LAST), (r2.c1 % 3) FROM ("S 1"."T 3" r1 FULL JOIN "S 1"."T 4" r2 ON (((r1.c1 = r2.c1)))) WHERE (((r1.c1 < 20) OR ((r1.c1 IS NULL) AND (r2.c1 < 5)))) GROUP BY ((r2.c1 % 3))
|
|
(7 rows)
|
|
|
|
select array_agg(distinct (t1.c1)%5 order by (t1.c1)%5 desc nulls last) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1;
|
|
array_agg
|
|
--------------
|
|
{3,2,1,NULL}
|
|
{4,3,2,1,0}
|
|
(2 rows)
|
|
|
|
-- FILTER within aggregate
|
|
explain (verbose, costs off)
|
|
select sum(c1) filter (where c1 < 100 and c2 > 5) from ft1 group by c2 order by 1 nulls last;
|
|
QUERY PLAN
|
|
--------------------------------------------------------------------------------------------------------------------
|
|
Sort
|
|
Output: (sum(c1) FILTER (WHERE ((c1 < 100) AND (c2 > 5)))), c2
|
|
Sort Key: (sum(ft1.c1) FILTER (WHERE ((ft1.c1 < 100) AND (ft1.c2 > 5))))
|
|
-> Foreign Scan
|
|
Output: (sum(c1) FILTER (WHERE ((c1 < 100) AND (c2 > 5)))), c2
|
|
Relations: Aggregate on (public.ft1)
|
|
Remote SQL: SELECT sum("C 1") FILTER (WHERE (("C 1" < 100) AND (c2 > 5))), c2 FROM "S 1"."T 1" GROUP BY c2
|
|
(7 rows)
|
|
|
|
select sum(c1) filter (where c1 < 100 and c2 > 5) from ft1 group by c2 order by 1 nulls last;
|
|
sum
|
|
-----
|
|
510
|
|
520
|
|
530
|
|
540
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(10 rows)
|
|
|
|
-- DISTINCT, ORDER BY and FILTER within aggregate
|
|
explain (verbose, costs off)
|
|
select sum(c1%3), sum(distinct c1%3 order by c1%3) filter (where c1%3 < 2), c2 from ft1 where c2 = 6 group by c2;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Foreign Scan
|
|
Output: (sum((c1 % 3))), (sum(DISTINCT (c1 % 3) ORDER BY (c1 % 3)) FILTER (WHERE ((c1 % 3) < 2))), c2
|
|
Relations: Aggregate on (public.ft1)
|
|
Remote SQL: SELECT sum(("C 1" % 3)), sum(DISTINCT ("C 1" % 3) ORDER BY (("C 1" % 3)) ASC NULLS LAST) FILTER (WHERE (("C 1" % 3) < 2)), c2 FROM "S 1"."T 1" WHERE ((c2 = 6)) GROUP BY c2
|
|
(4 rows)
|
|
|
|
select sum(c1%3), sum(distinct c1%3 order by c1%3) filter (where c1%3 < 2), c2 from ft1 where c2 = 6 group by c2;
|
|
sum | sum | c2
|
|
-----+-----+----
|
|
99 | 1 | 6
|
|
(1 row)
|
|
|
|
-- Outer query is aggregation query
|
|
explain (verbose, costs off)
|
|
select distinct (select count(*) filter (where t2.c2 = 6 and t2.c1 < 10) from ft1 t1 where t1.c1 = 6) from ft2 t2 order by 1;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------------------------
|
|
Unique
|
|
Output: ((SubPlan 1))
|
|
-> Sort
|
|
Output: ((SubPlan 1))
|
|
Sort Key: ((SubPlan 1))
|
|
-> Foreign Scan
|
|
Output: (SubPlan 1)
|
|
Relations: Aggregate on (public.ft2 t2)
|
|
Remote SQL: SELECT count(*) FILTER (WHERE ((c2 = 6) AND ("C 1" < 10))) FROM "S 1"."T 1"
|
|
SubPlan 1
|
|
-> Foreign Scan on public.ft1 t1
|
|
Output: (count(*) FILTER (WHERE ((t2.c2 = 6) AND (t2.c1 < 10))))
|
|
Remote SQL: SELECT NULL FROM "S 1"."T 1" WHERE (("C 1" = 6))
|
|
(13 rows)
|
|
|
|
select distinct (select count(*) filter (where t2.c2 = 6 and t2.c1 < 10) from ft1 t1 where t1.c1 = 6) from ft2 t2 order by 1;
|
|
count
|
|
-------
|
|
1
|
|
(1 row)
|
|
|
|
-- Inner query is aggregation query
|
|
explain (verbose, costs off)
|
|
select distinct (select count(t1.c1) filter (where t2.c2 = 6 and t2.c1 < 10) from ft1 t1 where t1.c1 = 6) from ft2 t2 order by 1;
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Unique
|
|
Output: ((SubPlan 1))
|
|
-> Sort
|
|
Output: ((SubPlan 1))
|
|
Sort Key: ((SubPlan 1))
|
|
-> Foreign Scan on public.ft2 t2
|
|
Output: (SubPlan 1)
|
|
Remote SQL: SELECT "C 1", c2 FROM "S 1"."T 1"
|
|
SubPlan 1
|
|
-> Foreign Scan
|
|
Output: (count(t1.c1) FILTER (WHERE ((t2.c2 = 6) AND (t2.c1 < 10))))
|
|
Relations: Aggregate on (public.ft1 t1)
|
|
Remote SQL: SELECT count("C 1") FILTER (WHERE (($1::integer = 6) AND ($2::integer < 10))) FROM "S 1"."T 1" WHERE (("C 1" = 6))
|
|
(13 rows)
|
|
|
|
select distinct (select count(t1.c1) filter (where t2.c2 = 6 and t2.c1 < 10) from ft1 t1 where t1.c1 = 6) from ft2 t2 order by 1;
|
|
count
|
|
-------
|
|
0
|
|
1
|
|
(2 rows)
|
|
|
|
-- Aggregate not pushed down as FILTER condition is not pushable
|
|
explain (verbose, costs off)
|
|
select sum(c1) filter (where (c1 / c1) * random() <= 1) from ft1 group by c2 order by 1;
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------------------------------------------------
|
|
Sort
|
|
Output: (sum(c1) FILTER (WHERE ((((c1 / c1))::double precision * random()) <= '1'::double precision))), c2
|
|
Sort Key: (sum(ft1.c1) FILTER (WHERE ((((ft1.c1 / ft1.c1))::double precision * random()) <= '1'::double precision)))
|
|
-> HashAggregate
|
|
Output: sum(c1) FILTER (WHERE ((((c1 / c1))::double precision * random()) <= '1'::double precision)), c2
|
|
Group Key: ft1.c2
|
|
-> Foreign Scan on public.ft1
|
|
Output: c2, c1
|
|
Remote SQL: SELECT "C 1", c2 FROM "S 1"."T 1"
|
|
(9 rows)
|
|
|
|
explain (verbose, costs off)
|
|
select sum(c2) filter (where c2 in (select c2 from ft1 where c2 < 5)) from ft1;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------
|
|
Aggregate
|
|
Output: sum(ft1.c2) FILTER (WHERE (hashed SubPlan 1))
|
|
-> Foreign Scan on public.ft1
|
|
Output: ft1.c2
|
|
Remote SQL: SELECT c2 FROM "S 1"."T 1"
|
|
SubPlan 1
|
|
-> Foreign Scan on public.ft1 ft1_1
|
|
Output: ft1_1.c2
|
|
Remote SQL: SELECT c2 FROM "S 1"."T 1" WHERE ((c2 < 5))
|
|
(9 rows)
|
|
|
|
-- Ordered-sets within aggregate
|
|
explain (verbose, costs off)
|
|
select c2, rank('10'::varchar) within group (order by c6), percentile_cont(c2/10::numeric) within group (order by c1) from ft1 where c2 < 10 group by c2 having percentile_cont(c2/10::numeric) within group (order by c1) < 500 order by c2;
|
|
QUERY PLAN
|
|
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Sort
|
|
Output: c2, (rank('10'::character varying) WITHIN GROUP (ORDER BY c6)), (percentile_cont((((c2)::numeric / '10'::numeric))::double precision) WITHIN GROUP (ORDER BY ((c1)::double precision)))
|
|
Sort Key: ft1.c2
|
|
-> Foreign Scan
|
|
Output: c2, (rank('10'::character varying) WITHIN GROUP (ORDER BY c6)), (percentile_cont((((c2)::numeric / '10'::numeric))::double precision) WITHIN GROUP (ORDER BY ((c1)::double precision)))
|
|
Relations: Aggregate on (public.ft1)
|
|
Remote SQL: SELECT c2, rank('10'::character varying) WITHIN GROUP (ORDER BY c6 ASC NULLS LAST), percentile_cont((c2 / 10::numeric)) WITHIN GROUP (ORDER BY ("C 1") ASC NULLS LAST) FROM "S 1"."T 1" WHERE ((c2 < 10)) GROUP BY c2 HAVING ((percentile_cont((c2 / 10::numeric)) WITHIN GROUP (ORDER BY ("C 1") ASC NULLS LAST) < 500::double precision))
|
|
(7 rows)
|
|
|
|
select c2, rank('10'::varchar) within group (order by c6), percentile_cont(c2/10::numeric) within group (order by c1) from ft1 where c2 < 10 group by c2 having percentile_cont(c2/10::numeric) within group (order by c1) < 500 order by c2;
|
|
c2 | rank | percentile_cont
|
|
----+------+-----------------
|
|
0 | 101 | 10
|
|
1 | 101 | 100
|
|
2 | 1 | 200
|
|
3 | 1 | 300
|
|
4 | 1 | 400
|
|
(5 rows)
|
|
|
|
-- Using multiple arguments within aggregates
|
|
explain (verbose, costs off)
|
|
select c1, rank(c1, c2) within group (order by c1, c2) from ft1 group by c1, c2 having c1 = 6 order by 1;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Foreign Scan
|
|
Output: c1, (rank(c1, c2) WITHIN GROUP (ORDER BY c1, c2)), c2
|
|
Relations: Aggregate on (public.ft1)
|
|
Remote SQL: SELECT "C 1", rank("C 1", c2) WITHIN GROUP (ORDER BY "C 1" ASC NULLS LAST, c2 ASC NULLS LAST), c2 FROM "S 1"."T 1" WHERE (("C 1" = 6)) GROUP BY "C 1", c2
|
|
(4 rows)
|
|
|
|
select c1, rank(c1, c2) within group (order by c1, c2) from ft1 group by c1, c2 having c1 = 6 order by 1;
|
|
c1 | rank
|
|
----+------
|
|
6 | 1
|
|
(1 row)
|
|
|
|
-- User defined function for user defined aggregate, VARIADIC
|
|
create function least_accum(anyelement, variadic anyarray)
|
|
returns anyelement language sql as
|
|
'select least($1, min($2[i])) from generate_subscripts($2,1) g(i)';
|
|
create aggregate least_agg(variadic items anyarray) (
|
|
stype = anyelement, sfunc = least_accum
|
|
);
|
|
-- Disable hash aggregation for plan stability.
|
|
set enable_hashagg to false;
|
|
-- Not pushed down due to user defined aggregate
|
|
explain (verbose, costs off)
|
|
select c2, least_agg(c1) from ft1 group by c2 order by c2;
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------------------
|
|
GroupAggregate
|
|
Output: c2, least_agg(VARIADIC ARRAY[c1])
|
|
Group Key: ft1.c2
|
|
-> Foreign Scan on public.ft1
|
|
Output: c2, c1
|
|
Remote SQL: SELECT "C 1", c2 FROM "S 1"."T 1" ORDER BY c2 ASC NULLS LAST
|
|
(6 rows)
|
|
|
|
-- Add function and aggregate into extension
|
|
alter extension postgres_fdw add function least_accum(anyelement, variadic anyarray);
|
|
alter extension postgres_fdw add aggregate least_agg(variadic items anyarray);
|
|
alter server loopback options (set extensions 'postgres_fdw');
|
|
-- Now aggregate will be pushed. Aggregate will display VARIADIC argument.
|
|
explain (verbose, costs off)
|
|
select c2, least_agg(c1) from ft1 where c2 < 100 group by c2 order by c2;
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------------------------------------------------
|
|
Sort
|
|
Output: c2, (least_agg(VARIADIC ARRAY[c1]))
|
|
Sort Key: ft1.c2
|
|
-> Foreign Scan
|
|
Output: c2, (least_agg(VARIADIC ARRAY[c1]))
|
|
Relations: Aggregate on (public.ft1)
|
|
Remote SQL: SELECT c2, public.least_agg(VARIADIC ARRAY["C 1"]) FROM "S 1"."T 1" WHERE ((c2 < 100)) GROUP BY c2
|
|
(7 rows)
|
|
|
|
select c2, least_agg(c1) from ft1 where c2 < 100 group by c2 order by c2;
|
|
c2 | least_agg
|
|
----+-----------
|
|
0 | 10
|
|
1 | 1
|
|
2 | 2
|
|
3 | 3
|
|
4 | 4
|
|
5 | 5
|
|
6 | 6
|
|
7 | 7
|
|
8 | 8
|
|
9 | 9
|
|
(10 rows)
|
|
|
|
-- Remove function and aggregate from extension
|
|
alter extension postgres_fdw drop function least_accum(anyelement, variadic anyarray);
|
|
alter extension postgres_fdw drop aggregate least_agg(variadic items anyarray);
|
|
alter server loopback options (set extensions 'postgres_fdw');
|
|
-- Not pushed down as we have dropped objects from extension.
|
|
explain (verbose, costs off)
|
|
select c2, least_agg(c1) from ft1 group by c2 order by c2;
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------------------
|
|
GroupAggregate
|
|
Output: c2, least_agg(VARIADIC ARRAY[c1])
|
|
Group Key: ft1.c2
|
|
-> Foreign Scan on public.ft1
|
|
Output: c2, c1
|
|
Remote SQL: SELECT "C 1", c2 FROM "S 1"."T 1" ORDER BY c2 ASC NULLS LAST
|
|
(6 rows)
|
|
|
|
-- Cleanup
|
|
reset enable_hashagg;
|
|
drop aggregate least_agg(variadic items anyarray);
|
|
drop function least_accum(anyelement, variadic anyarray);
|
|
-- Testing USING OPERATOR() in ORDER BY within aggregate.
|
|
-- For this, we need user defined operators along with operator family and
|
|
-- operator class. Create those and then add them in extension. Note that
|
|
-- user defined objects are considered unshippable unless they are part of
|
|
-- the extension.
|
|
create operator public.<^ (
|
|
leftarg = int4,
|
|
rightarg = int4,
|
|
procedure = int4eq
|
|
);
|
|
create operator public.=^ (
|
|
leftarg = int4,
|
|
rightarg = int4,
|
|
procedure = int4lt
|
|
);
|
|
create operator public.>^ (
|
|
leftarg = int4,
|
|
rightarg = int4,
|
|
procedure = int4gt
|
|
);
|
|
create operator family my_op_family using btree;
|
|
create function my_op_cmp(a int, b int) returns int as
|
|
$$begin return btint4cmp(a, b); end $$ language plpgsql;
|
|
create operator class my_op_class for type int using btree family my_op_family as
|
|
operator 1 public.<^,
|
|
operator 3 public.=^,
|
|
operator 5 public.>^,
|
|
function 1 my_op_cmp(int, int);
|
|
-- This will not be pushed as user defined sort operator is not part of the
|
|
-- extension yet.
|
|
explain (verbose, costs off)
|
|
select array_agg(c1 order by c1 using operator(public.<^)) from ft2 where c2 = 6 and c1 < 100 group by c2;
|
|
QUERY PLAN
|
|
--------------------------------------------------------------------------------------------
|
|
GroupAggregate
|
|
Output: array_agg(c1 ORDER BY c1 USING <^ NULLS LAST), c2
|
|
Group Key: ft2.c2
|
|
-> Foreign Scan on public.ft2
|
|
Output: c2, c1
|
|
Remote SQL: SELECT "C 1", c2 FROM "S 1"."T 1" WHERE (("C 1" < 100)) AND ((c2 = 6))
|
|
(6 rows)
|
|
|
|
-- Add into extension
|
|
alter extension postgres_fdw add operator class my_op_class using btree;
|
|
alter extension postgres_fdw add function my_op_cmp(a int, b int);
|
|
alter extension postgres_fdw add operator family my_op_family using btree;
|
|
alter extension postgres_fdw add operator public.<^(int, int);
|
|
alter extension postgres_fdw add operator public.=^(int, int);
|
|
alter extension postgres_fdw add operator public.>^(int, int);
|
|
alter server loopback options (set extensions 'postgres_fdw');
|
|
-- Now this will be pushed as sort operator is part of the extension.
|
|
explain (verbose, costs off)
|
|
select array_agg(c1 order by c1 using operator(public.<^)) from ft2 where c2 = 6 and c1 < 100 group by c2;
|
|
QUERY PLAN
|
|
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Foreign Scan
|
|
Output: (array_agg(c1 ORDER BY c1 USING <^ NULLS LAST)), c2
|
|
Relations: Aggregate on (public.ft2)
|
|
Remote SQL: SELECT array_agg("C 1" ORDER BY "C 1" USING OPERATOR(public.<^) NULLS LAST), c2 FROM "S 1"."T 1" WHERE (("C 1" < 100)) AND ((c2 = 6)) GROUP BY c2
|
|
(4 rows)
|
|
|
|
select array_agg(c1 order by c1 using operator(public.<^)) from ft2 where c2 = 6 and c1 < 100 group by c2;
|
|
array_agg
|
|
--------------------------------
|
|
{6,16,26,36,46,56,66,76,86,96}
|
|
(1 row)
|
|
|
|
-- Remove from extension
|
|
alter extension postgres_fdw drop operator class my_op_class using btree;
|
|
alter extension postgres_fdw drop function my_op_cmp(a int, b int);
|
|
alter extension postgres_fdw drop operator family my_op_family using btree;
|
|
alter extension postgres_fdw drop operator public.<^(int, int);
|
|
alter extension postgres_fdw drop operator public.=^(int, int);
|
|
alter extension postgres_fdw drop operator public.>^(int, int);
|
|
alter server loopback options (set extensions 'postgres_fdw');
|
|
-- This will not be pushed as sort operator is now removed from the extension.
|
|
explain (verbose, costs off)
|
|
select array_agg(c1 order by c1 using operator(public.<^)) from ft2 where c2 = 6 and c1 < 100 group by c2;
|
|
QUERY PLAN
|
|
--------------------------------------------------------------------------------------------
|
|
GroupAggregate
|
|
Output: array_agg(c1 ORDER BY c1 USING <^ NULLS LAST), c2
|
|
Group Key: ft2.c2
|
|
-> Foreign Scan on public.ft2
|
|
Output: c2, c1
|
|
Remote SQL: SELECT "C 1", c2 FROM "S 1"."T 1" WHERE (("C 1" < 100)) AND ((c2 = 6))
|
|
(6 rows)
|
|
|
|
-- Cleanup
|
|
drop operator class my_op_class using btree;
|
|
drop function my_op_cmp(a int, b int);
|
|
drop operator family my_op_family using btree;
|
|
drop operator public.>^(int, int);
|
|
drop operator public.=^(int, int);
|
|
drop operator public.<^(int, int);
|
|
-- Input relation to aggregate push down hook is not safe to pushdown and thus
|
|
-- the aggregate cannot be pushed down to foreign server.
|
|
explain (verbose, costs off)
|
|
select count(t1.c3) from ft1 t1, ft1 t2 where t1.c1 = postgres_fdw_abs(t1.c2);
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------------------------------------------
|
|
Aggregate
|
|
Output: count(t1.c3)
|
|
-> Nested Loop
|
|
Output: t1.c3
|
|
-> Foreign Scan on public.ft1 t2
|
|
Remote SQL: SELECT NULL FROM "S 1"."T 1"
|
|
-> Materialize
|
|
Output: t1.c3
|
|
-> Foreign Scan on public.ft1 t1
|
|
Output: t1.c3
|
|
Remote SQL: SELECT c3 FROM "S 1"."T 1" WHERE (("C 1" = public.postgres_fdw_abs(c2)))
|
|
(11 rows)
|
|
|
|
-- Subquery in FROM clause having aggregate
|
|
explain (verbose, costs off)
|
|
select count(*), x.b from ft1, (select c2 a, sum(c1) b from ft1 group by c2) x where ft1.c2 = x.a group by x.b order by 1, 2;
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------------------------
|
|
Sort
|
|
Output: (count(*)), x.b
|
|
Sort Key: (count(*)), x.b
|
|
-> HashAggregate
|
|
Output: count(*), x.b
|
|
Group Key: x.b
|
|
-> Hash Join
|
|
Output: x.b
|
|
Hash Cond: (ft1.c2 = x.a)
|
|
-> Foreign Scan on public.ft1
|
|
Output: ft1.c2
|
|
Remote SQL: SELECT c2 FROM "S 1"."T 1"
|
|
-> Hash
|
|
Output: x.b, x.a
|
|
-> Subquery Scan on x
|
|
Output: x.b, x.a
|
|
-> Foreign Scan
|
|
Output: ft1_1.c2, (sum(ft1_1.c1))
|
|
Relations: Aggregate on (public.ft1)
|
|
Remote SQL: SELECT c2, sum("C 1") FROM "S 1"."T 1" GROUP BY c2
|
|
(20 rows)
|
|
|
|
select count(*), x.b from ft1, (select c2 a, sum(c1) b from ft1 group by c2) x where ft1.c2 = x.a group by x.b order by 1, 2;
|
|
count | b
|
|
-------+-------
|
|
100 | 49600
|
|
100 | 49700
|
|
100 | 49800
|
|
100 | 49900
|
|
100 | 50000
|
|
100 | 50100
|
|
100 | 50200
|
|
100 | 50300
|
|
100 | 50400
|
|
100 | 50500
|
|
(10 rows)
|
|
|
|
-- FULL join with IS NULL check in HAVING
|
|
explain (verbose, costs off)
|
|
select avg(t1.c1), sum(t2.c1) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) group by t2.c1 having (avg(t1.c1) is null and sum(t2.c1) < 10) or sum(t2.c1) is null order by 1 nulls last, 2;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Sort
|
|
Output: (avg(t1.c1)), (sum(t2.c1)), t2.c1
|
|
Sort Key: (avg(t1.c1)), (sum(t2.c1))
|
|
-> Foreign Scan
|
|
Output: (avg(t1.c1)), (sum(t2.c1)), t2.c1
|
|
Relations: Aggregate on ((public.ft4 t1) FULL JOIN (public.ft5 t2))
|
|
Remote SQL: SELECT avg(r1.c1), sum(r2.c1), r2.c1 FROM ("S 1"."T 3" r1 FULL JOIN "S 1"."T 4" r2 ON (((r1.c1 = r2.c1)))) GROUP BY r2.c1 HAVING ((((avg(r1.c1) IS NULL) AND (sum(r2.c1) < 10)) OR (sum(r2.c1) IS NULL)))
|
|
(7 rows)
|
|
|
|
select avg(t1.c1), sum(t2.c1) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) group by t2.c1 having (avg(t1.c1) is null and sum(t2.c1) < 10) or sum(t2.c1) is null order by 1 nulls last, 2;
|
|
avg | sum
|
|
---------------------+-----
|
|
51.0000000000000000 |
|
|
| 3
|
|
| 9
|
|
(3 rows)
|
|
|
|
-- ORDER BY expression is part of the target list but not pushed down to
|
|
-- foreign server.
|
|
explain (verbose, costs off)
|
|
select sum(c2) * (random() <= 1)::int as sum from ft1 order by 1;
|
|
QUERY PLAN
|
|
--------------------------------------------------------------------------------
|
|
Sort
|
|
Output: (((sum(c2)) * ((random() <= '1'::double precision))::integer))
|
|
Sort Key: (((sum(ft1.c2)) * ((random() <= '1'::double precision))::integer))
|
|
-> Foreign Scan
|
|
Output: ((sum(c2)) * ((random() <= '1'::double precision))::integer)
|
|
Relations: Aggregate on (public.ft1)
|
|
Remote SQL: SELECT sum(c2) FROM "S 1"."T 1"
|
|
(7 rows)
|
|
|
|
select sum(c2) * (random() <= 1)::int as sum from ft1 order by 1;
|
|
sum
|
|
------
|
|
4500
|
|
(1 row)
|
|
|
|
-- LATERAL join, with parameterization
|
|
set enable_hashagg to false;
|
|
explain (verbose, costs off)
|
|
select c2, sum from "S 1"."T 1" t1, lateral (select sum(t2.c1 + t1."C 1") sum from ft2 t2 group by t2.c1) qry where t1.c2 * 2 = qry.sum and t1.c2 < 10 order by 1;
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------------------------------------------
|
|
Sort
|
|
Output: t1.c2, qry.sum
|
|
Sort Key: t1.c2
|
|
-> Nested Loop
|
|
Output: t1.c2, qry.sum
|
|
-> Seq Scan on "S 1"."T 1" t1
|
|
Output: t1."C 1", t1.c2, t1.c3, t1.c4, t1.c5, t1.c6, t1.c7, t1.c8
|
|
Filter: (t1.c2 < 10)
|
|
-> Subquery Scan on qry
|
|
Output: qry.sum, t2.c1
|
|
Filter: ((t1.c2 * 2) = qry.sum)
|
|
-> Foreign Scan
|
|
Output: (sum((t2.c1 + t1."C 1"))), t2.c1
|
|
Relations: Aggregate on (public.ft2 t2)
|
|
Remote SQL: SELECT sum(("C 1" + $1::integer)), "C 1" FROM "S 1"."T 1" GROUP BY "C 1"
|
|
(15 rows)
|
|
|
|
select c2, sum from "S 1"."T 1" t1, lateral (select sum(t2.c1 + t1."C 1") sum from ft2 t2 group by t2.c1) qry where t1.c2 * 2 = qry.sum and t1.c2 < 10 order by 1;
|
|
c2 | sum
|
|
----+-----
|
|
1 | 2
|
|
2 | 4
|
|
3 | 6
|
|
4 | 8
|
|
5 | 10
|
|
6 | 12
|
|
7 | 14
|
|
8 | 16
|
|
9 | 18
|
|
(9 rows)
|
|
|
|
reset enable_hashagg;
|
|
-- Check with placeHolderVars
|
|
explain (verbose, costs off)
|
|
select sum(q.a), count(q.b) from ft4 left join (select 13, avg(ft1.c1), sum(ft2.c1) from ft1 right join ft2 on (ft1.c1 = ft2.c1)) q(a, b, c) on (ft4.c1 <= q.b);
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Aggregate
|
|
Output: sum(q.a), count(q.b)
|
|
-> Nested Loop Left Join
|
|
Output: q.a, q.b
|
|
Join Filter: ((ft4.c1)::numeric <= q.b)
|
|
-> Foreign Scan on public.ft4
|
|
Output: ft4.c1, ft4.c2, ft4.c3
|
|
Remote SQL: SELECT c1 FROM "S 1"."T 3"
|
|
-> Materialize
|
|
Output: q.a, q.b
|
|
-> Subquery Scan on q
|
|
Output: q.a, q.b
|
|
-> Foreign Scan
|
|
Output: 13, (avg(ft1.c1)), NULL::bigint
|
|
Relations: Aggregate on ((public.ft2) LEFT JOIN (public.ft1))
|
|
Remote SQL: SELECT 13, avg(r1."C 1"), NULL::bigint FROM ("S 1"."T 1" r2 LEFT JOIN "S 1"."T 1" r1 ON (((r1."C 1" = r2."C 1"))))
|
|
(16 rows)
|
|
|
|
select sum(q.a), count(q.b) from ft4 left join (select 13, avg(ft1.c1), sum(ft2.c1) from ft1 right join ft2 on (ft1.c1 = ft2.c1)) q(a, b, c) on (ft4.c1 <= q.b);
|
|
sum | count
|
|
-----+-------
|
|
650 | 50
|
|
(1 row)
|
|
|
|
-- Not supported cases
|
|
-- Grouping sets
|
|
explain (verbose, costs off)
|
|
select c2, sum(c1) from ft1 where c2 < 3 group by rollup(c2) order by 1 nulls last;
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------------
|
|
GroupAggregate
|
|
Output: c2, sum(c1)
|
|
Group Key: ft1.c2
|
|
Group Key: ()
|
|
-> Foreign Scan on public.ft1
|
|
Output: c2, c1
|
|
Remote SQL: SELECT "C 1", c2 FROM "S 1"."T 1" WHERE ((c2 < 3)) ORDER BY c2 ASC NULLS LAST
|
|
(7 rows)
|
|
|
|
select c2, sum(c1) from ft1 where c2 < 3 group by rollup(c2) order by 1 nulls last;
|
|
c2 | sum
|
|
----+--------
|
|
0 | 50500
|
|
1 | 49600
|
|
2 | 49700
|
|
| 149800
|
|
(4 rows)
|
|
|
|
explain (verbose, costs off)
|
|
select c2, sum(c1) from ft1 where c2 < 3 group by cube(c2) order by 1 nulls last;
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------------
|
|
GroupAggregate
|
|
Output: c2, sum(c1)
|
|
Group Key: ft1.c2
|
|
Group Key: ()
|
|
-> Foreign Scan on public.ft1
|
|
Output: c2, c1
|
|
Remote SQL: SELECT "C 1", c2 FROM "S 1"."T 1" WHERE ((c2 < 3)) ORDER BY c2 ASC NULLS LAST
|
|
(7 rows)
|
|
|
|
select c2, sum(c1) from ft1 where c2 < 3 group by cube(c2) order by 1 nulls last;
|
|
c2 | sum
|
|
----+--------
|
|
0 | 50500
|
|
1 | 49600
|
|
2 | 49700
|
|
| 149800
|
|
(4 rows)
|
|
|
|
explain (verbose, costs off)
|
|
select c2, c6, sum(c1) from ft1 where c2 < 3 group by grouping sets(c2, c6) order by 1 nulls last, 2 nulls last;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------------------------------
|
|
Sort
|
|
Output: c2, c6, (sum(c1))
|
|
Sort Key: ft1.c2, ft1.c6
|
|
-> GroupAggregate
|
|
Output: c2, c6, sum(c1)
|
|
Group Key: ft1.c2
|
|
Sort Key: ft1.c6
|
|
Group Key: ft1.c6
|
|
-> Foreign Scan on public.ft1
|
|
Output: c2, c6, c1
|
|
Remote SQL: SELECT "C 1", c2, c6 FROM "S 1"."T 1" WHERE ((c2 < 3)) ORDER BY c2 ASC NULLS LAST
|
|
(11 rows)
|
|
|
|
select c2, c6, sum(c1) from ft1 where c2 < 3 group by grouping sets(c2, c6) order by 1 nulls last, 2 nulls last;
|
|
c2 | c6 | sum
|
|
----+----+-------
|
|
0 | | 50500
|
|
1 | | 49600
|
|
2 | | 49700
|
|
| 0 | 50500
|
|
| 1 | 49600
|
|
| 2 | 49700
|
|
(6 rows)
|
|
|
|
explain (verbose, costs off)
|
|
select c2, sum(c1), grouping(c2) from ft1 where c2 < 3 group by c2 order by 1 nulls last;
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------
|
|
Sort
|
|
Output: c2, (sum(c1)), (GROUPING(c2))
|
|
Sort Key: ft1.c2
|
|
-> HashAggregate
|
|
Output: c2, sum(c1), GROUPING(c2)
|
|
Group Key: ft1.c2
|
|
-> Foreign Scan on public.ft1
|
|
Output: c2, c1
|
|
Remote SQL: SELECT "C 1", c2 FROM "S 1"."T 1" WHERE ((c2 < 3))
|
|
(9 rows)
|
|
|
|
select c2, sum(c1), grouping(c2) from ft1 where c2 < 3 group by c2 order by 1 nulls last;
|
|
c2 | sum | grouping
|
|
----+-------+----------
|
|
0 | 50500 | 0
|
|
1 | 49600 | 0
|
|
2 | 49700 | 0
|
|
(3 rows)
|
|
|
|
-- DISTINCT itself is not pushed down, whereas underneath aggregate is pushed
|
|
explain (verbose, costs off)
|
|
select distinct sum(c1)/1000 s from ft2 where c2 < 6 group by c2 order by 1;
|
|
QUERY PLAN
|
|
--------------------------------------------------------------------------------------------------------
|
|
Unique
|
|
Output: ((sum(c1) / 1000)), c2
|
|
-> Sort
|
|
Output: ((sum(c1) / 1000)), c2
|
|
Sort Key: ((sum(ft2.c1) / 1000))
|
|
-> Foreign Scan
|
|
Output: ((sum(c1) / 1000)), c2
|
|
Relations: Aggregate on (public.ft2)
|
|
Remote SQL: SELECT (sum("C 1") / 1000), c2 FROM "S 1"."T 1" WHERE ((c2 < 6)) GROUP BY c2
|
|
(9 rows)
|
|
|
|
select distinct sum(c1)/1000 s from ft2 where c2 < 6 group by c2 order by 1;
|
|
s
|
|
----
|
|
49
|
|
50
|
|
(2 rows)
|
|
|
|
-- WindowAgg
|
|
explain (verbose, costs off)
|
|
select c2, sum(c2), count(c2) over (partition by c2%2) from ft2 where c2 < 10 group by c2 order by 1;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------------------------------
|
|
Sort
|
|
Output: c2, (sum(c2)), (count(c2) OVER (?)), ((c2 % 2))
|
|
Sort Key: ft2.c2
|
|
-> WindowAgg
|
|
Output: c2, (sum(c2)), count(c2) OVER (?), ((c2 % 2))
|
|
-> Sort
|
|
Output: c2, ((c2 % 2)), (sum(c2))
|
|
Sort Key: ((ft2.c2 % 2))
|
|
-> Foreign Scan
|
|
Output: c2, ((c2 % 2)), (sum(c2))
|
|
Relations: Aggregate on (public.ft2)
|
|
Remote SQL: SELECT c2, (c2 % 2), sum(c2) FROM "S 1"."T 1" WHERE ((c2 < 10)) GROUP BY c2
|
|
(12 rows)
|
|
|
|
select c2, sum(c2), count(c2) over (partition by c2%2) from ft2 where c2 < 10 group by c2 order by 1;
|
|
c2 | sum | count
|
|
----+-----+-------
|
|
0 | 0 | 5
|
|
1 | 100 | 5
|
|
2 | 200 | 5
|
|
3 | 300 | 5
|
|
4 | 400 | 5
|
|
5 | 500 | 5
|
|
6 | 600 | 5
|
|
7 | 700 | 5
|
|
8 | 800 | 5
|
|
9 | 900 | 5
|
|
(10 rows)
|
|
|
|
explain (verbose, costs off)
|
|
select c2, array_agg(c2) over (partition by c2%2 order by c2 desc) from ft1 where c2 < 10 group by c2 order by 1;
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------------------------------------
|
|
Sort
|
|
Output: c2, (array_agg(c2) OVER (?)), ((c2 % 2))
|
|
Sort Key: ft1.c2
|
|
-> WindowAgg
|
|
Output: c2, array_agg(c2) OVER (?), ((c2 % 2))
|
|
-> Sort
|
|
Output: c2, ((c2 % 2))
|
|
Sort Key: ((ft1.c2 % 2)), ft1.c2 DESC
|
|
-> Foreign Scan
|
|
Output: c2, ((c2 % 2))
|
|
Relations: Aggregate on (public.ft1)
|
|
Remote SQL: SELECT c2, (c2 % 2) FROM "S 1"."T 1" WHERE ((c2 < 10)) GROUP BY c2
|
|
(12 rows)
|
|
|
|
select c2, array_agg(c2) over (partition by c2%2 order by c2 desc) from ft1 where c2 < 10 group by c2 order by 1;
|
|
c2 | array_agg
|
|
----+-------------
|
|
0 | {8,6,4,2,0}
|
|
1 | {9,7,5,3,1}
|
|
2 | {8,6,4,2}
|
|
3 | {9,7,5,3}
|
|
4 | {8,6,4}
|
|
5 | {9,7,5}
|
|
6 | {8,6}
|
|
7 | {9,7}
|
|
8 | {8}
|
|
9 | {9}
|
|
(10 rows)
|
|
|
|
explain (verbose, costs off)
|
|
select c2, array_agg(c2) over (partition by c2%2 order by c2 range between current row and unbounded following) from ft1 where c2 < 10 group by c2 order by 1;
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------------------------------------
|
|
Sort
|
|
Output: c2, (array_agg(c2) OVER (?)), ((c2 % 2))
|
|
Sort Key: ft1.c2
|
|
-> WindowAgg
|
|
Output: c2, array_agg(c2) OVER (?), ((c2 % 2))
|
|
-> Sort
|
|
Output: c2, ((c2 % 2))
|
|
Sort Key: ((ft1.c2 % 2)), ft1.c2
|
|
-> Foreign Scan
|
|
Output: c2, ((c2 % 2))
|
|
Relations: Aggregate on (public.ft1)
|
|
Remote SQL: SELECT c2, (c2 % 2) FROM "S 1"."T 1" WHERE ((c2 < 10)) GROUP BY c2
|
|
(12 rows)
|
|
|
|
select c2, array_agg(c2) over (partition by c2%2 order by c2 range between current row and unbounded following) from ft1 where c2 < 10 group by c2 order by 1;
|
|
c2 | array_agg
|
|
----+-------------
|
|
0 | {0,2,4,6,8}
|
|
1 | {1,3,5,7,9}
|
|
2 | {2,4,6,8}
|
|
3 | {3,5,7,9}
|
|
4 | {4,6,8}
|
|
5 | {5,7,9}
|
|
6 | {6,8}
|
|
7 | {7,9}
|
|
8 | {8}
|
|
9 | {9}
|
|
(10 rows)
|
|
|
|
-- ===================================================================
|
|
-- parameterized queries
|
|
-- ===================================================================
|
|
-- simple join
|
|
PREPARE st1(int, int) AS SELECT t1.c3, t2.c3 FROM ft1 t1, ft2 t2 WHERE t1.c1 = $1 AND t2.c1 = $2;
|
|
EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st1(1, 2);
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------------------------------------------------------
|
|
Foreign Scan
|
|
Output: t1.c3, t2.c3
|
|
Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2)
|
|
Remote SQL: SELECT r1.c3, r2.c3 FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r2."C 1" = 2)) AND ((r1."C 1" = 1))))
|
|
(4 rows)
|
|
|
|
EXECUTE st1(1, 1);
|
|
c3 | c3
|
|
-------+-------
|
|
00001 | 00001
|
|
(1 row)
|
|
|
|
EXECUTE st1(101, 101);
|
|
c3 | c3
|
|
-------+-------
|
|
00101 | 00101
|
|
(1 row)
|
|
|
|
-- subquery using stable function (can't be sent to remote)
|
|
PREPARE st2(int) AS SELECT * FROM ft1 t1 WHERE t1.c1 < $2 AND t1.c3 IN (SELECT c3 FROM ft2 t2 WHERE c1 > $1 AND date(c4) = '1970-01-17'::date) ORDER BY c1;
|
|
EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st2(10, 20);
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------------------------------------------
|
|
Sort
|
|
Output: t1.c1, t1.c2, t1.c3, t1.c4, t1.c5, t1.c6, t1.c7, t1.c8
|
|
Sort Key: t1.c1
|
|
-> Nested Loop Semi Join
|
|
Output: t1.c1, t1.c2, t1.c3, t1.c4, t1.c5, t1.c6, t1.c7, t1.c8
|
|
Join Filter: (t1.c3 = t2.c3)
|
|
-> Foreign Scan on public.ft1 t1
|
|
Output: t1.c1, t1.c2, t1.c3, t1.c4, t1.c5, t1.c6, t1.c7, t1.c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" < 20))
|
|
-> Materialize
|
|
Output: t2.c3
|
|
-> Foreign Scan on public.ft2 t2
|
|
Output: t2.c3
|
|
Filter: (date(t2.c4) = '01-17-1970'::date)
|
|
Remote SQL: SELECT c3, c4 FROM "S 1"."T 1" WHERE (("C 1" > 10))
|
|
(15 rows)
|
|
|
|
EXECUTE st2(10, 20);
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
----+----+-------+------------------------------+--------------------------+----+------------+-----
|
|
16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo
|
|
(1 row)
|
|
|
|
EXECUTE st2(101, 121);
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
-----+----+-------+------------------------------+--------------------------+----+------------+-----
|
|
116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo
|
|
(1 row)
|
|
|
|
-- subquery using immutable function (can be sent to remote)
|
|
PREPARE st3(int) AS SELECT * FROM ft1 t1 WHERE t1.c1 < $2 AND t1.c3 IN (SELECT c3 FROM ft2 t2 WHERE c1 > $1 AND date(c5) = '1970-01-17'::date) ORDER BY c1;
|
|
EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st3(10, 20);
|
|
QUERY PLAN
|
|
-----------------------------------------------------------------------------------------------------------------------
|
|
Sort
|
|
Output: t1.c1, t1.c2, t1.c3, t1.c4, t1.c5, t1.c6, t1.c7, t1.c8
|
|
Sort Key: t1.c1
|
|
-> Nested Loop Semi Join
|
|
Output: t1.c1, t1.c2, t1.c3, t1.c4, t1.c5, t1.c6, t1.c7, t1.c8
|
|
Join Filter: (t1.c3 = t2.c3)
|
|
-> Foreign Scan on public.ft1 t1
|
|
Output: t1.c1, t1.c2, t1.c3, t1.c4, t1.c5, t1.c6, t1.c7, t1.c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" < 20))
|
|
-> Materialize
|
|
Output: t2.c3
|
|
-> Foreign Scan on public.ft2 t2
|
|
Output: t2.c3
|
|
Remote SQL: SELECT c3 FROM "S 1"."T 1" WHERE (("C 1" > 10)) AND ((date(c5) = '1970-01-17'::date))
|
|
(14 rows)
|
|
|
|
EXECUTE st3(10, 20);
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
----+----+-------+------------------------------+--------------------------+----+------------+-----
|
|
16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo
|
|
(1 row)
|
|
|
|
EXECUTE st3(20, 30);
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
----+----+----+----+----+----+----+----
|
|
(0 rows)
|
|
|
|
-- custom plan should be chosen initially
|
|
PREPARE st4(int) AS SELECT * FROM ft1 t1 WHERE t1.c1 = $1;
|
|
EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1);
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 1))
|
|
(3 rows)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1);
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 1))
|
|
(3 rows)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1);
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 1))
|
|
(3 rows)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1);
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 1))
|
|
(3 rows)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1);
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 1))
|
|
(3 rows)
|
|
|
|
-- once we try it enough times, should switch to generic plan
|
|
EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1);
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = $1::integer))
|
|
(3 rows)
|
|
|
|
-- value of $1 should not be sent to remote
|
|
PREPARE st5(user_enum,int) AS SELECT * FROM ft1 t1 WHERE c8 = $1 and c1 = $2;
|
|
EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1);
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Filter: (t1.c8 = 'foo'::user_enum)
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 1))
|
|
(4 rows)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1);
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Filter: (t1.c8 = 'foo'::user_enum)
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 1))
|
|
(4 rows)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1);
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Filter: (t1.c8 = 'foo'::user_enum)
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 1))
|
|
(4 rows)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1);
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Filter: (t1.c8 = 'foo'::user_enum)
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 1))
|
|
(4 rows)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1);
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Filter: (t1.c8 = 'foo'::user_enum)
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 1))
|
|
(4 rows)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1);
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Filter: (t1.c8 = $1)
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = $1::integer))
|
|
(4 rows)
|
|
|
|
EXECUTE st5('foo', 1);
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
----+----+-------+------------------------------+--------------------------+----+------------+-----
|
|
1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo
|
|
(1 row)
|
|
|
|
-- cleanup
|
|
DEALLOCATE st1;
|
|
DEALLOCATE st2;
|
|
DEALLOCATE st3;
|
|
DEALLOCATE st4;
|
|
DEALLOCATE st5;
|
|
-- System columns, except ctid and oid, should not be sent to remote
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT * FROM ft1 t1 WHERE t1.tableoid = 'pg_class'::regclass LIMIT 1;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------
|
|
Limit
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
-> Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Filter: (t1.tableoid = '1259'::oid)
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1"
|
|
(6 rows)
|
|
|
|
SELECT * FROM ft1 t1 WHERE t1.tableoid = 'ft1'::regclass LIMIT 1;
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
----+----+-------+------------------------------+--------------------------+----+------------+-----
|
|
1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo
|
|
(1 row)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT tableoid::regclass, * FROM ft1 t1 LIMIT 1;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------
|
|
Limit
|
|
Output: ((tableoid)::regclass), c1, c2, c3, c4, c5, c6, c7, c8
|
|
-> Foreign Scan on public.ft1 t1
|
|
Output: (tableoid)::regclass, c1, c2, c3, c4, c5, c6, c7, c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1"
|
|
(5 rows)
|
|
|
|
SELECT tableoid::regclass, * FROM ft1 t1 LIMIT 1;
|
|
tableoid | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
----------+----+----+-------+------------------------------+--------------------------+----+------------+-----
|
|
ft1 | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo
|
|
(1 row)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT * FROM ft1 t1 WHERE t1.ctid = '(0,2)';
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft1 t1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((ctid = '(0,2)'::tid))
|
|
(3 rows)
|
|
|
|
SELECT * FROM ft1 t1 WHERE t1.ctid = '(0,2)';
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
----+----+-------+------------------------------+--------------------------+----+------------+-----
|
|
2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo
|
|
(1 row)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT ctid, * FROM ft1 t1 LIMIT 1;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: ctid, c1, c2, c3, c4, c5, c6, c7, c8
|
|
-> Foreign Scan on public.ft1 t1
|
|
Output: ctid, c1, c2, c3, c4, c5, c6, c7, c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8, ctid FROM "S 1"."T 1"
|
|
(5 rows)
|
|
|
|
SELECT ctid, * FROM ft1 t1 LIMIT 1;
|
|
ctid | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
-------+----+----+-------+------------------------------+--------------------------+----+------------+-----
|
|
(0,1) | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo
|
|
(1 row)
|
|
|
|
EXPLAIN (VERBOSE, COSTS OFF)
|
|
SELECT oid, * FROM ft_pg_type WHERE typname = 'int4';
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft_pg_type
|
|
Output: oid, typname, typlen
|
|
Remote SQL: SELECT typname, typlen, oid FROM pg_catalog.pg_type WHERE ((typname = 'int4'::name))
|
|
(3 rows)
|
|
|
|
SELECT oid, * FROM ft_pg_type WHERE typname = 'int4';
|
|
oid | typname | typlen
|
|
-----+---------+--------
|
|
23 | int4 | 4
|
|
(1 row)
|
|
|
|
-- ===================================================================
|
|
-- used in pl/pgsql function
|
|
-- ===================================================================
|
|
CREATE OR REPLACE FUNCTION f_test(p_c1 int) RETURNS int AS $$
|
|
DECLARE
|
|
v_c1 int;
|
|
BEGIN
|
|
SELECT c1 INTO v_c1 FROM ft1 WHERE c1 = p_c1 LIMIT 1;
|
|
PERFORM c1 FROM ft1 WHERE c1 = p_c1 AND p_c1 = v_c1 LIMIT 1;
|
|
RETURN v_c1;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
SELECT f_test(100);
|
|
f_test
|
|
--------
|
|
100
|
|
(1 row)
|
|
|
|
DROP FUNCTION f_test(int);
|
|
-- ===================================================================
|
|
-- conversion error
|
|
-- ===================================================================
|
|
ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE int;
|
|
SELECT * FROM ft1 WHERE c1 = 1; -- ERROR
|
|
ERROR: invalid input syntax for integer: "foo"
|
|
CONTEXT: column "c8" of foreign table "ft1"
|
|
SELECT ft1.c1, ft2.c2, ft1.c8 FROM ft1, ft2 WHERE ft1.c1 = ft2.c1 AND ft1.c1 = 1; -- ERROR
|
|
ERROR: invalid input syntax for integer: "foo"
|
|
CONTEXT: column "c8" of foreign table "ft1"
|
|
SELECT ft1.c1, ft2.c2, ft1 FROM ft1, ft2 WHERE ft1.c1 = ft2.c1 AND ft1.c1 = 1; -- ERROR
|
|
ERROR: invalid input syntax for integer: "foo"
|
|
CONTEXT: whole-row reference to foreign table "ft1"
|
|
SELECT sum(c2), array_agg(c8) FROM ft1 GROUP BY c8; -- ERROR
|
|
ERROR: invalid input syntax for integer: "foo"
|
|
CONTEXT: processing expression at position 2 in select list
|
|
ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE user_enum;
|
|
-- ===================================================================
|
|
-- subtransaction
|
|
-- + local/remote error doesn't break cursor
|
|
-- ===================================================================
|
|
BEGIN;
|
|
DECLARE c CURSOR FOR SELECT * FROM ft1 ORDER BY c1;
|
|
FETCH c;
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
----+----+-------+------------------------------+--------------------------+----+------------+-----
|
|
1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo
|
|
(1 row)
|
|
|
|
SAVEPOINT s;
|
|
ERROR OUT; -- ERROR
|
|
ERROR: syntax error at or near "ERROR"
|
|
LINE 1: ERROR OUT;
|
|
^
|
|
ROLLBACK TO s;
|
|
FETCH c;
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
----+----+-------+------------------------------+--------------------------+----+------------+-----
|
|
2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo
|
|
(1 row)
|
|
|
|
SAVEPOINT s;
|
|
SELECT * FROM ft1 WHERE 1 / (c1 - 1) > 0; -- ERROR
|
|
ERROR: division by zero
|
|
CONTEXT: Remote SQL command: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (((1 / ("C 1" - 1)) > 0))
|
|
ROLLBACK TO s;
|
|
FETCH c;
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
----+----+-------+------------------------------+--------------------------+----+------------+-----
|
|
3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo
|
|
(1 row)
|
|
|
|
SELECT * FROM ft1 ORDER BY c1 LIMIT 1;
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
----+----+-------+------------------------------+--------------------------+----+------------+-----
|
|
1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo
|
|
(1 row)
|
|
|
|
COMMIT;
|
|
-- ===================================================================
|
|
-- test handling of collations
|
|
-- ===================================================================
|
|
create table loct3 (f1 text collate "C" unique, f2 text, f3 varchar(10) unique);
|
|
create foreign table ft3 (f1 text collate "C", f2 text, f3 varchar(10))
|
|
server loopback options (table_name 'loct3', use_remote_estimate 'true');
|
|
-- can be sent to remote
|
|
explain (verbose, costs off) select * from ft3 where f1 = 'foo';
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft3
|
|
Output: f1, f2, f3
|
|
Remote SQL: SELECT f1, f2, f3 FROM public.loct3 WHERE ((f1 = 'foo'::text))
|
|
(3 rows)
|
|
|
|
explain (verbose, costs off) select * from ft3 where f1 COLLATE "C" = 'foo';
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft3
|
|
Output: f1, f2, f3
|
|
Remote SQL: SELECT f1, f2, f3 FROM public.loct3 WHERE ((f1 = 'foo'::text))
|
|
(3 rows)
|
|
|
|
explain (verbose, costs off) select * from ft3 where f2 = 'foo';
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft3
|
|
Output: f1, f2, f3
|
|
Remote SQL: SELECT f1, f2, f3 FROM public.loct3 WHERE ((f2 = 'foo'::text))
|
|
(3 rows)
|
|
|
|
explain (verbose, costs off) select * from ft3 where f3 = 'foo';
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------
|
|
Foreign Scan on public.ft3
|
|
Output: f1, f2, f3
|
|
Remote SQL: SELECT f1, f2, f3 FROM public.loct3 WHERE ((f3 = 'foo'::text))
|
|
(3 rows)
|
|
|
|
explain (verbose, costs off) select * from ft3 f, loct3 l
|
|
where f.f3 = l.f3 and l.f1 = 'foo';
|
|
QUERY PLAN
|
|
--------------------------------------------------------------------------------------------------
|
|
Nested Loop
|
|
Output: f.f1, f.f2, f.f3, l.f1, l.f2, l.f3
|
|
-> Index Scan using loct3_f1_key on public.loct3 l
|
|
Output: l.f1, l.f2, l.f3
|
|
Index Cond: (l.f1 = 'foo'::text)
|
|
-> Foreign Scan on public.ft3 f
|
|
Output: f.f1, f.f2, f.f3
|
|
Remote SQL: SELECT f1, f2, f3 FROM public.loct3 WHERE (($1::character varying(10) = f3))
|
|
(8 rows)
|
|
|
|
-- can't be sent to remote
|
|
explain (verbose, costs off) select * from ft3 where f1 COLLATE "POSIX" = 'foo';
|
|
QUERY PLAN
|
|
---------------------------------------------------
|
|
Foreign Scan on public.ft3
|
|
Output: f1, f2, f3
|
|
Filter: ((ft3.f1)::text = 'foo'::text)
|
|
Remote SQL: SELECT f1, f2, f3 FROM public.loct3
|
|
(4 rows)
|
|
|
|
explain (verbose, costs off) select * from ft3 where f1 = 'foo' COLLATE "C";
|
|
QUERY PLAN
|
|
---------------------------------------------------
|
|
Foreign Scan on public.ft3
|
|
Output: f1, f2, f3
|
|
Filter: (ft3.f1 = 'foo'::text COLLATE "C")
|
|
Remote SQL: SELECT f1, f2, f3 FROM public.loct3
|
|
(4 rows)
|
|
|
|
explain (verbose, costs off) select * from ft3 where f2 COLLATE "C" = 'foo';
|
|
QUERY PLAN
|
|
---------------------------------------------------
|
|
Foreign Scan on public.ft3
|
|
Output: f1, f2, f3
|
|
Filter: ((ft3.f2)::text = 'foo'::text)
|
|
Remote SQL: SELECT f1, f2, f3 FROM public.loct3
|
|
(4 rows)
|
|
|
|
explain (verbose, costs off) select * from ft3 where f2 = 'foo' COLLATE "C";
|
|
QUERY PLAN
|
|
---------------------------------------------------
|
|
Foreign Scan on public.ft3
|
|
Output: f1, f2, f3
|
|
Filter: (ft3.f2 = 'foo'::text COLLATE "C")
|
|
Remote SQL: SELECT f1, f2, f3 FROM public.loct3
|
|
(4 rows)
|
|
|
|
explain (verbose, costs off) select * from ft3 f, loct3 l
|
|
where f.f3 = l.f3 COLLATE "POSIX" and l.f1 = 'foo';
|
|
QUERY PLAN
|
|
-------------------------------------------------------------
|
|
Hash Join
|
|
Output: f.f1, f.f2, f.f3, l.f1, l.f2, l.f3
|
|
Hash Cond: ((f.f3)::text = (l.f3)::text)
|
|
-> Foreign Scan on public.ft3 f
|
|
Output: f.f1, f.f2, f.f3
|
|
Remote SQL: SELECT f1, f2, f3 FROM public.loct3
|
|
-> Hash
|
|
Output: l.f1, l.f2, l.f3
|
|
-> Index Scan using loct3_f1_key on public.loct3 l
|
|
Output: l.f1, l.f2, l.f3
|
|
Index Cond: (l.f1 = 'foo'::text)
|
|
(11 rows)
|
|
|
|
-- ===================================================================
|
|
-- test writable foreign table stuff
|
|
-- ===================================================================
|
|
EXPLAIN (verbose, costs off)
|
|
INSERT INTO ft2 (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2 LIMIT 20;
|
|
QUERY PLAN
|
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Insert on public.ft2
|
|
Remote SQL: INSERT INTO "S 1"."T 1"("C 1", c2, c3, c4, c5, c6, c7, c8) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
|
-> Subquery Scan on "*SELECT*"
|
|
Output: "*SELECT*"."?column?", "*SELECT*"."?column?_1", NULL::integer, "*SELECT*"."?column?_2", NULL::timestamp with time zone, NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::user_enum
|
|
-> Limit
|
|
Output: ((ft2_1.c1 + 1000)), ((ft2_1.c2 + 100)), ((ft2_1.c3 || ft2_1.c3))
|
|
-> Foreign Scan on public.ft2 ft2_1
|
|
Output: (ft2_1.c1 + 1000), (ft2_1.c2 + 100), (ft2_1.c3 || ft2_1.c3)
|
|
Remote SQL: SELECT "C 1", c2, c3 FROM "S 1"."T 1"
|
|
(9 rows)
|
|
|
|
INSERT INTO ft2 (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2 LIMIT 20;
|
|
INSERT INTO ft2 (c1,c2,c3)
|
|
VALUES (1101,201,'aaa'), (1102,202,'bbb'), (1103,203,'ccc') RETURNING *;
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
------+-----+-----+----+----+----+------------+----
|
|
1101 | 201 | aaa | | | | ft2 |
|
|
1102 | 202 | bbb | | | | ft2 |
|
|
1103 | 203 | ccc | | | | ft2 |
|
|
(3 rows)
|
|
|
|
INSERT INTO ft2 (c1,c2,c3) VALUES (1104,204,'ddd'), (1105,205,'eee');
|
|
EXPLAIN (verbose, costs off)
|
|
UPDATE ft2 SET c2 = c2 + 300, c3 = c3 || '_update3' WHERE c1 % 10 = 3; -- can be pushed down
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------------------------------------------------------
|
|
Update on public.ft2
|
|
-> Foreign Update on public.ft2
|
|
Remote SQL: UPDATE "S 1"."T 1" SET c2 = (c2 + 300), c3 = (c3 || '_update3'::text) WHERE ((("C 1" % 10) = 3))
|
|
(3 rows)
|
|
|
|
UPDATE ft2 SET c2 = c2 + 300, c3 = c3 || '_update3' WHERE c1 % 10 = 3;
|
|
EXPLAIN (verbose, costs off)
|
|
UPDATE ft2 SET c2 = c2 + 400, c3 = c3 || '_update7' WHERE c1 % 10 = 7 RETURNING *; -- can be pushed down
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Update on public.ft2
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
-> Foreign Update on public.ft2
|
|
Remote SQL: UPDATE "S 1"."T 1" SET c2 = (c2 + 400), c3 = (c3 || '_update7'::text) WHERE ((("C 1" % 10) = 7)) RETURNING "C 1", c2, c3, c4, c5, c6, c7, c8
|
|
(4 rows)
|
|
|
|
UPDATE ft2 SET c2 = c2 + 400, c3 = c3 || '_update7' WHERE c1 % 10 = 7 RETURNING *;
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
------+-----+--------------------+------------------------------+--------------------------+----+------------+-----
|
|
7 | 407 | 00007_update7 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo
|
|
17 | 407 | 00017_update7 | Sun Jan 18 00:00:00 1970 PST | Sun Jan 18 00:00:00 1970 | 7 | 7 | foo
|
|
27 | 407 | 00027_update7 | Wed Jan 28 00:00:00 1970 PST | Wed Jan 28 00:00:00 1970 | 7 | 7 | foo
|
|
37 | 407 | 00037_update7 | Sat Feb 07 00:00:00 1970 PST | Sat Feb 07 00:00:00 1970 | 7 | 7 | foo
|
|
47 | 407 | 00047_update7 | Tue Feb 17 00:00:00 1970 PST | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo
|
|
57 | 407 | 00057_update7 | Fri Feb 27 00:00:00 1970 PST | Fri Feb 27 00:00:00 1970 | 7 | 7 | foo
|
|
67 | 407 | 00067_update7 | Mon Mar 09 00:00:00 1970 PST | Mon Mar 09 00:00:00 1970 | 7 | 7 | foo
|
|
77 | 407 | 00077_update7 | Thu Mar 19 00:00:00 1970 PST | Thu Mar 19 00:00:00 1970 | 7 | 7 | foo
|
|
87 | 407 | 00087_update7 | Sun Mar 29 00:00:00 1970 PST | Sun Mar 29 00:00:00 1970 | 7 | 7 | foo
|
|
97 | 407 | 00097_update7 | Wed Apr 08 00:00:00 1970 PST | Wed Apr 08 00:00:00 1970 | 7 | 7 | foo
|
|
107 | 407 | 00107_update7 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo
|
|
117 | 407 | 00117_update7 | Sun Jan 18 00:00:00 1970 PST | Sun Jan 18 00:00:00 1970 | 7 | 7 | foo
|
|
127 | 407 | 00127_update7 | Wed Jan 28 00:00:00 1970 PST | Wed Jan 28 00:00:00 1970 | 7 | 7 | foo
|
|
137 | 407 | 00137_update7 | Sat Feb 07 00:00:00 1970 PST | Sat Feb 07 00:00:00 1970 | 7 | 7 | foo
|
|
147 | 407 | 00147_update7 | Tue Feb 17 00:00:00 1970 PST | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo
|
|
157 | 407 | 00157_update7 | Fri Feb 27 00:00:00 1970 PST | Fri Feb 27 00:00:00 1970 | 7 | 7 | foo
|
|
167 | 407 | 00167_update7 | Mon Mar 09 00:00:00 1970 PST | Mon Mar 09 00:00:00 1970 | 7 | 7 | foo
|
|
177 | 407 | 00177_update7 | Thu Mar 19 00:00:00 1970 PST | Thu Mar 19 00:00:00 1970 | 7 | 7 | foo
|
|
187 | 407 | 00187_update7 | Sun Mar 29 00:00:00 1970 PST | Sun Mar 29 00:00:00 1970 | 7 | 7 | foo
|
|
197 | 407 | 00197_update7 | Wed Apr 08 00:00:00 1970 PST | Wed Apr 08 00:00:00 1970 | 7 | 7 | foo
|
|
207 | 407 | 00207_update7 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo
|
|
217 | 407 | 00217_update7 | Sun Jan 18 00:00:00 1970 PST | Sun Jan 18 00:00:00 1970 | 7 | 7 | foo
|
|
227 | 407 | 00227_update7 | Wed Jan 28 00:00:00 1970 PST | Wed Jan 28 00:00:00 1970 | 7 | 7 | foo
|
|
237 | 407 | 00237_update7 | Sat Feb 07 00:00:00 1970 PST | Sat Feb 07 00:00:00 1970 | 7 | 7 | foo
|
|
247 | 407 | 00247_update7 | Tue Feb 17 00:00:00 1970 PST | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo
|
|
257 | 407 | 00257_update7 | Fri Feb 27 00:00:00 1970 PST | Fri Feb 27 00:00:00 1970 | 7 | 7 | foo
|
|
267 | 407 | 00267_update7 | Mon Mar 09 00:00:00 1970 PST | Mon Mar 09 00:00:00 1970 | 7 | 7 | foo
|
|
277 | 407 | 00277_update7 | Thu Mar 19 00:00:00 1970 PST | Thu Mar 19 00:00:00 1970 | 7 | 7 | foo
|
|
287 | 407 | 00287_update7 | Sun Mar 29 00:00:00 1970 PST | Sun Mar 29 00:00:00 1970 | 7 | 7 | foo
|
|
297 | 407 | 00297_update7 | Wed Apr 08 00:00:00 1970 PST | Wed Apr 08 00:00:00 1970 | 7 | 7 | foo
|
|
307 | 407 | 00307_update7 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo
|
|
317 | 407 | 00317_update7 | Sun Jan 18 00:00:00 1970 PST | Sun Jan 18 00:00:00 1970 | 7 | 7 | foo
|
|
327 | 407 | 00327_update7 | Wed Jan 28 00:00:00 1970 PST | Wed Jan 28 00:00:00 1970 | 7 | 7 | foo
|
|
337 | 407 | 00337_update7 | Sat Feb 07 00:00:00 1970 PST | Sat Feb 07 00:00:00 1970 | 7 | 7 | foo
|
|
347 | 407 | 00347_update7 | Tue Feb 17 00:00:00 1970 PST | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo
|
|
357 | 407 | 00357_update7 | Fri Feb 27 00:00:00 1970 PST | Fri Feb 27 00:00:00 1970 | 7 | 7 | foo
|
|
367 | 407 | 00367_update7 | Mon Mar 09 00:00:00 1970 PST | Mon Mar 09 00:00:00 1970 | 7 | 7 | foo
|
|
377 | 407 | 00377_update7 | Thu Mar 19 00:00:00 1970 PST | Thu Mar 19 00:00:00 1970 | 7 | 7 | foo
|
|
387 | 407 | 00387_update7 | Sun Mar 29 00:00:00 1970 PST | Sun Mar 29 00:00:00 1970 | 7 | 7 | foo
|
|
397 | 407 | 00397_update7 | Wed Apr 08 00:00:00 1970 PST | Wed Apr 08 00:00:00 1970 | 7 | 7 | foo
|
|
407 | 407 | 00407_update7 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo
|
|
417 | 407 | 00417_update7 | Sun Jan 18 00:00:00 1970 PST | Sun Jan 18 00:00:00 1970 | 7 | 7 | foo
|
|
427 | 407 | 00427_update7 | Wed Jan 28 00:00:00 1970 PST | Wed Jan 28 00:00:00 1970 | 7 | 7 | foo
|
|
437 | 407 | 00437_update7 | Sat Feb 07 00:00:00 1970 PST | Sat Feb 07 00:00:00 1970 | 7 | 7 | foo
|
|
447 | 407 | 00447_update7 | Tue Feb 17 00:00:00 1970 PST | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo
|
|
457 | 407 | 00457_update7 | Fri Feb 27 00:00:00 1970 PST | Fri Feb 27 00:00:00 1970 | 7 | 7 | foo
|
|
467 | 407 | 00467_update7 | Mon Mar 09 00:00:00 1970 PST | Mon Mar 09 00:00:00 1970 | 7 | 7 | foo
|
|
477 | 407 | 00477_update7 | Thu Mar 19 00:00:00 1970 PST | Thu Mar 19 00:00:00 1970 | 7 | 7 | foo
|
|
487 | 407 | 00487_update7 | Sun Mar 29 00:00:00 1970 PST | Sun Mar 29 00:00:00 1970 | 7 | 7 | foo
|
|
497 | 407 | 00497_update7 | Wed Apr 08 00:00:00 1970 PST | Wed Apr 08 00:00:00 1970 | 7 | 7 | foo
|
|
507 | 407 | 00507_update7 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo
|
|
517 | 407 | 00517_update7 | Sun Jan 18 00:00:00 1970 PST | Sun Jan 18 00:00:00 1970 | 7 | 7 | foo
|
|
527 | 407 | 00527_update7 | Wed Jan 28 00:00:00 1970 PST | Wed Jan 28 00:00:00 1970 | 7 | 7 | foo
|
|
537 | 407 | 00537_update7 | Sat Feb 07 00:00:00 1970 PST | Sat Feb 07 00:00:00 1970 | 7 | 7 | foo
|
|
547 | 407 | 00547_update7 | Tue Feb 17 00:00:00 1970 PST | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo
|
|
557 | 407 | 00557_update7 | Fri Feb 27 00:00:00 1970 PST | Fri Feb 27 00:00:00 1970 | 7 | 7 | foo
|
|
567 | 407 | 00567_update7 | Mon Mar 09 00:00:00 1970 PST | Mon Mar 09 00:00:00 1970 | 7 | 7 | foo
|
|
577 | 407 | 00577_update7 | Thu Mar 19 00:00:00 1970 PST | Thu Mar 19 00:00:00 1970 | 7 | 7 | foo
|
|
587 | 407 | 00587_update7 | Sun Mar 29 00:00:00 1970 PST | Sun Mar 29 00:00:00 1970 | 7 | 7 | foo
|
|
597 | 407 | 00597_update7 | Wed Apr 08 00:00:00 1970 PST | Wed Apr 08 00:00:00 1970 | 7 | 7 | foo
|
|
607 | 407 | 00607_update7 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo
|
|
617 | 407 | 00617_update7 | Sun Jan 18 00:00:00 1970 PST | Sun Jan 18 00:00:00 1970 | 7 | 7 | foo
|
|
627 | 407 | 00627_update7 | Wed Jan 28 00:00:00 1970 PST | Wed Jan 28 00:00:00 1970 | 7 | 7 | foo
|
|
637 | 407 | 00637_update7 | Sat Feb 07 00:00:00 1970 PST | Sat Feb 07 00:00:00 1970 | 7 | 7 | foo
|
|
647 | 407 | 00647_update7 | Tue Feb 17 00:00:00 1970 PST | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo
|
|
657 | 407 | 00657_update7 | Fri Feb 27 00:00:00 1970 PST | Fri Feb 27 00:00:00 1970 | 7 | 7 | foo
|
|
667 | 407 | 00667_update7 | Mon Mar 09 00:00:00 1970 PST | Mon Mar 09 00:00:00 1970 | 7 | 7 | foo
|
|
677 | 407 | 00677_update7 | Thu Mar 19 00:00:00 1970 PST | Thu Mar 19 00:00:00 1970 | 7 | 7 | foo
|
|
687 | 407 | 00687_update7 | Sun Mar 29 00:00:00 1970 PST | Sun Mar 29 00:00:00 1970 | 7 | 7 | foo
|
|
697 | 407 | 00697_update7 | Wed Apr 08 00:00:00 1970 PST | Wed Apr 08 00:00:00 1970 | 7 | 7 | foo
|
|
707 | 407 | 00707_update7 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo
|
|
717 | 407 | 00717_update7 | Sun Jan 18 00:00:00 1970 PST | Sun Jan 18 00:00:00 1970 | 7 | 7 | foo
|
|
727 | 407 | 00727_update7 | Wed Jan 28 00:00:00 1970 PST | Wed Jan 28 00:00:00 1970 | 7 | 7 | foo
|
|
737 | 407 | 00737_update7 | Sat Feb 07 00:00:00 1970 PST | Sat Feb 07 00:00:00 1970 | 7 | 7 | foo
|
|
747 | 407 | 00747_update7 | Tue Feb 17 00:00:00 1970 PST | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo
|
|
757 | 407 | 00757_update7 | Fri Feb 27 00:00:00 1970 PST | Fri Feb 27 00:00:00 1970 | 7 | 7 | foo
|
|
767 | 407 | 00767_update7 | Mon Mar 09 00:00:00 1970 PST | Mon Mar 09 00:00:00 1970 | 7 | 7 | foo
|
|
777 | 407 | 00777_update7 | Thu Mar 19 00:00:00 1970 PST | Thu Mar 19 00:00:00 1970 | 7 | 7 | foo
|
|
787 | 407 | 00787_update7 | Sun Mar 29 00:00:00 1970 PST | Sun Mar 29 00:00:00 1970 | 7 | 7 | foo
|
|
797 | 407 | 00797_update7 | Wed Apr 08 00:00:00 1970 PST | Wed Apr 08 00:00:00 1970 | 7 | 7 | foo
|
|
807 | 407 | 00807_update7 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo
|
|
817 | 407 | 00817_update7 | Sun Jan 18 00:00:00 1970 PST | Sun Jan 18 00:00:00 1970 | 7 | 7 | foo
|
|
827 | 407 | 00827_update7 | Wed Jan 28 00:00:00 1970 PST | Wed Jan 28 00:00:00 1970 | 7 | 7 | foo
|
|
837 | 407 | 00837_update7 | Sat Feb 07 00:00:00 1970 PST | Sat Feb 07 00:00:00 1970 | 7 | 7 | foo
|
|
847 | 407 | 00847_update7 | Tue Feb 17 00:00:00 1970 PST | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo
|
|
857 | 407 | 00857_update7 | Fri Feb 27 00:00:00 1970 PST | Fri Feb 27 00:00:00 1970 | 7 | 7 | foo
|
|
867 | 407 | 00867_update7 | Mon Mar 09 00:00:00 1970 PST | Mon Mar 09 00:00:00 1970 | 7 | 7 | foo
|
|
877 | 407 | 00877_update7 | Thu Mar 19 00:00:00 1970 PST | Thu Mar 19 00:00:00 1970 | 7 | 7 | foo
|
|
887 | 407 | 00887_update7 | Sun Mar 29 00:00:00 1970 PST | Sun Mar 29 00:00:00 1970 | 7 | 7 | foo
|
|
897 | 407 | 00897_update7 | Wed Apr 08 00:00:00 1970 PST | Wed Apr 08 00:00:00 1970 | 7 | 7 | foo
|
|
907 | 407 | 00907_update7 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo
|
|
917 | 407 | 00917_update7 | Sun Jan 18 00:00:00 1970 PST | Sun Jan 18 00:00:00 1970 | 7 | 7 | foo
|
|
927 | 407 | 00927_update7 | Wed Jan 28 00:00:00 1970 PST | Wed Jan 28 00:00:00 1970 | 7 | 7 | foo
|
|
937 | 407 | 00937_update7 | Sat Feb 07 00:00:00 1970 PST | Sat Feb 07 00:00:00 1970 | 7 | 7 | foo
|
|
947 | 407 | 00947_update7 | Tue Feb 17 00:00:00 1970 PST | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo
|
|
957 | 407 | 00957_update7 | Fri Feb 27 00:00:00 1970 PST | Fri Feb 27 00:00:00 1970 | 7 | 7 | foo
|
|
967 | 407 | 00967_update7 | Mon Mar 09 00:00:00 1970 PST | Mon Mar 09 00:00:00 1970 | 7 | 7 | foo
|
|
977 | 407 | 00977_update7 | Thu Mar 19 00:00:00 1970 PST | Thu Mar 19 00:00:00 1970 | 7 | 7 | foo
|
|
987 | 407 | 00987_update7 | Sun Mar 29 00:00:00 1970 PST | Sun Mar 29 00:00:00 1970 | 7 | 7 | foo
|
|
997 | 407 | 00997_update7 | Wed Apr 08 00:00:00 1970 PST | Wed Apr 08 00:00:00 1970 | 7 | 7 | foo
|
|
1007 | 507 | 0000700007_update7 | | | | ft2 |
|
|
1017 | 507 | 0001700017_update7 | | | | ft2 |
|
|
(102 rows)
|
|
|
|
EXPLAIN (verbose, costs off)
|
|
UPDATE ft2 SET c2 = ft2.c2 + 500, c3 = ft2.c3 || '_update9', c7 = DEFAULT
|
|
FROM ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 9; -- can't be pushed down
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Update on public.ft2
|
|
Remote SQL: UPDATE "S 1"."T 1" SET c2 = $2, c3 = $3, c7 = $4 WHERE ctid = $1
|
|
-> Foreign Scan
|
|
Output: ft2.c1, (ft2.c2 + 500), NULL::integer, (ft2.c3 || '_update9'::text), ft2.c4, ft2.c5, ft2.c6, 'ft2 '::character(10), ft2.c8, ft2.ctid, ft1.*
|
|
Relations: (public.ft2) INNER JOIN (public.ft1)
|
|
Remote SQL: SELECT r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c8, r1.ctid, CASE WHEN (r2.*)::text IS NOT NULL THEN ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) END FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1.c2 = r2."C 1")) AND (((r2."C 1" % 10) = 9)))) FOR UPDATE OF r1
|
|
-> Hash Join
|
|
Output: ft2.c1, ft2.c2, ft2.c3, ft2.c4, ft2.c5, ft2.c6, ft2.c8, ft2.ctid, ft1.*
|
|
Hash Cond: (ft2.c2 = ft1.c1)
|
|
-> Foreign Scan on public.ft2
|
|
Output: ft2.c1, ft2.c2, ft2.c3, ft2.c4, ft2.c5, ft2.c6, ft2.c8, ft2.ctid
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c8, ctid FROM "S 1"."T 1" FOR UPDATE
|
|
-> Hash
|
|
Output: ft1.*, ft1.c1
|
|
-> Foreign Scan on public.ft1
|
|
Output: ft1.*, ft1.c1
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((("C 1" % 10) = 9))
|
|
(17 rows)
|
|
|
|
UPDATE ft2 SET c2 = ft2.c2 + 500, c3 = ft2.c3 || '_update9', c7 = DEFAULT
|
|
FROM ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 9;
|
|
EXPLAIN (verbose, costs off)
|
|
DELETE FROM ft2 WHERE c1 % 10 = 5 RETURNING c1, c4; -- can be pushed down
|
|
QUERY PLAN
|
|
--------------------------------------------------------------------------------------------
|
|
Delete on public.ft2
|
|
Output: c1, c4
|
|
-> Foreign Delete on public.ft2
|
|
Remote SQL: DELETE FROM "S 1"."T 1" WHERE ((("C 1" % 10) = 5)) RETURNING "C 1", c4
|
|
(4 rows)
|
|
|
|
DELETE FROM ft2 WHERE c1 % 10 = 5 RETURNING c1, c4;
|
|
c1 | c4
|
|
------+------------------------------
|
|
5 | Tue Jan 06 00:00:00 1970 PST
|
|
15 | Fri Jan 16 00:00:00 1970 PST
|
|
25 | Mon Jan 26 00:00:00 1970 PST
|
|
35 | Thu Feb 05 00:00:00 1970 PST
|
|
45 | Sun Feb 15 00:00:00 1970 PST
|
|
55 | Wed Feb 25 00:00:00 1970 PST
|
|
65 | Sat Mar 07 00:00:00 1970 PST
|
|
75 | Tue Mar 17 00:00:00 1970 PST
|
|
85 | Fri Mar 27 00:00:00 1970 PST
|
|
95 | Mon Apr 06 00:00:00 1970 PST
|
|
105 | Tue Jan 06 00:00:00 1970 PST
|
|
115 | Fri Jan 16 00:00:00 1970 PST
|
|
125 | Mon Jan 26 00:00:00 1970 PST
|
|
135 | Thu Feb 05 00:00:00 1970 PST
|
|
145 | Sun Feb 15 00:00:00 1970 PST
|
|
155 | Wed Feb 25 00:00:00 1970 PST
|
|
165 | Sat Mar 07 00:00:00 1970 PST
|
|
175 | Tue Mar 17 00:00:00 1970 PST
|
|
185 | Fri Mar 27 00:00:00 1970 PST
|
|
195 | Mon Apr 06 00:00:00 1970 PST
|
|
205 | Tue Jan 06 00:00:00 1970 PST
|
|
215 | Fri Jan 16 00:00:00 1970 PST
|
|
225 | Mon Jan 26 00:00:00 1970 PST
|
|
235 | Thu Feb 05 00:00:00 1970 PST
|
|
245 | Sun Feb 15 00:00:00 1970 PST
|
|
255 | Wed Feb 25 00:00:00 1970 PST
|
|
265 | Sat Mar 07 00:00:00 1970 PST
|
|
275 | Tue Mar 17 00:00:00 1970 PST
|
|
285 | Fri Mar 27 00:00:00 1970 PST
|
|
295 | Mon Apr 06 00:00:00 1970 PST
|
|
305 | Tue Jan 06 00:00:00 1970 PST
|
|
315 | Fri Jan 16 00:00:00 1970 PST
|
|
325 | Mon Jan 26 00:00:00 1970 PST
|
|
335 | Thu Feb 05 00:00:00 1970 PST
|
|
345 | Sun Feb 15 00:00:00 1970 PST
|
|
355 | Wed Feb 25 00:00:00 1970 PST
|
|
365 | Sat Mar 07 00:00:00 1970 PST
|
|
375 | Tue Mar 17 00:00:00 1970 PST
|
|
385 | Fri Mar 27 00:00:00 1970 PST
|
|
395 | Mon Apr 06 00:00:00 1970 PST
|
|
405 | Tue Jan 06 00:00:00 1970 PST
|
|
415 | Fri Jan 16 00:00:00 1970 PST
|
|
425 | Mon Jan 26 00:00:00 1970 PST
|
|
435 | Thu Feb 05 00:00:00 1970 PST
|
|
445 | Sun Feb 15 00:00:00 1970 PST
|
|
455 | Wed Feb 25 00:00:00 1970 PST
|
|
465 | Sat Mar 07 00:00:00 1970 PST
|
|
475 | Tue Mar 17 00:00:00 1970 PST
|
|
485 | Fri Mar 27 00:00:00 1970 PST
|
|
495 | Mon Apr 06 00:00:00 1970 PST
|
|
505 | Tue Jan 06 00:00:00 1970 PST
|
|
515 | Fri Jan 16 00:00:00 1970 PST
|
|
525 | Mon Jan 26 00:00:00 1970 PST
|
|
535 | Thu Feb 05 00:00:00 1970 PST
|
|
545 | Sun Feb 15 00:00:00 1970 PST
|
|
555 | Wed Feb 25 00:00:00 1970 PST
|
|
565 | Sat Mar 07 00:00:00 1970 PST
|
|
575 | Tue Mar 17 00:00:00 1970 PST
|
|
585 | Fri Mar 27 00:00:00 1970 PST
|
|
595 | Mon Apr 06 00:00:00 1970 PST
|
|
605 | Tue Jan 06 00:00:00 1970 PST
|
|
615 | Fri Jan 16 00:00:00 1970 PST
|
|
625 | Mon Jan 26 00:00:00 1970 PST
|
|
635 | Thu Feb 05 00:00:00 1970 PST
|
|
645 | Sun Feb 15 00:00:00 1970 PST
|
|
655 | Wed Feb 25 00:00:00 1970 PST
|
|
665 | Sat Mar 07 00:00:00 1970 PST
|
|
675 | Tue Mar 17 00:00:00 1970 PST
|
|
685 | Fri Mar 27 00:00:00 1970 PST
|
|
695 | Mon Apr 06 00:00:00 1970 PST
|
|
705 | Tue Jan 06 00:00:00 1970 PST
|
|
715 | Fri Jan 16 00:00:00 1970 PST
|
|
725 | Mon Jan 26 00:00:00 1970 PST
|
|
735 | Thu Feb 05 00:00:00 1970 PST
|
|
745 | Sun Feb 15 00:00:00 1970 PST
|
|
755 | Wed Feb 25 00:00:00 1970 PST
|
|
765 | Sat Mar 07 00:00:00 1970 PST
|
|
775 | Tue Mar 17 00:00:00 1970 PST
|
|
785 | Fri Mar 27 00:00:00 1970 PST
|
|
795 | Mon Apr 06 00:00:00 1970 PST
|
|
805 | Tue Jan 06 00:00:00 1970 PST
|
|
815 | Fri Jan 16 00:00:00 1970 PST
|
|
825 | Mon Jan 26 00:00:00 1970 PST
|
|
835 | Thu Feb 05 00:00:00 1970 PST
|
|
845 | Sun Feb 15 00:00:00 1970 PST
|
|
855 | Wed Feb 25 00:00:00 1970 PST
|
|
865 | Sat Mar 07 00:00:00 1970 PST
|
|
875 | Tue Mar 17 00:00:00 1970 PST
|
|
885 | Fri Mar 27 00:00:00 1970 PST
|
|
895 | Mon Apr 06 00:00:00 1970 PST
|
|
905 | Tue Jan 06 00:00:00 1970 PST
|
|
915 | Fri Jan 16 00:00:00 1970 PST
|
|
925 | Mon Jan 26 00:00:00 1970 PST
|
|
935 | Thu Feb 05 00:00:00 1970 PST
|
|
945 | Sun Feb 15 00:00:00 1970 PST
|
|
955 | Wed Feb 25 00:00:00 1970 PST
|
|
965 | Sat Mar 07 00:00:00 1970 PST
|
|
975 | Tue Mar 17 00:00:00 1970 PST
|
|
985 | Fri Mar 27 00:00:00 1970 PST
|
|
995 | Mon Apr 06 00:00:00 1970 PST
|
|
1005 |
|
|
1015 |
|
|
1105 |
|
|
(103 rows)
|
|
|
|
EXPLAIN (verbose, costs off)
|
|
DELETE FROM ft2 USING ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 2; -- can't be pushed down
|
|
QUERY PLAN
|
|
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Delete on public.ft2
|
|
Remote SQL: DELETE FROM "S 1"."T 1" WHERE ctid = $1
|
|
-> Foreign Scan
|
|
Output: ft2.ctid, ft1.*
|
|
Relations: (public.ft2) INNER JOIN (public.ft1)
|
|
Remote SQL: SELECT r1.ctid, CASE WHEN (r2.*)::text IS NOT NULL THEN ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) END FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1.c2 = r2."C 1")) AND (((r2."C 1" % 10) = 2)))) FOR UPDATE OF r1
|
|
-> Hash Join
|
|
Output: ft2.ctid, ft1.*
|
|
Hash Cond: (ft2.c2 = ft1.c1)
|
|
-> Foreign Scan on public.ft2
|
|
Output: ft2.ctid, ft2.c2
|
|
Remote SQL: SELECT c2, ctid FROM "S 1"."T 1" FOR UPDATE
|
|
-> Hash
|
|
Output: ft1.*, ft1.c1
|
|
-> Foreign Scan on public.ft1
|
|
Output: ft1.*, ft1.c1
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((("C 1" % 10) = 2))
|
|
(17 rows)
|
|
|
|
DELETE FROM ft2 USING ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 2;
|
|
SELECT c1,c2,c3,c4 FROM ft2 ORDER BY c1;
|
|
c1 | c2 | c3 | c4
|
|
------+-----+--------------------+------------------------------
|
|
1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST
|
|
3 | 303 | 00003_update3 | Sun Jan 04 00:00:00 1970 PST
|
|
4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST
|
|
6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST
|
|
7 | 407 | 00007_update7 | Thu Jan 08 00:00:00 1970 PST
|
|
8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 PST
|
|
9 | 509 | 00009_update9 | Sat Jan 10 00:00:00 1970 PST
|
|
10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 PST
|
|
11 | 1 | 00011 | Mon Jan 12 00:00:00 1970 PST
|
|
13 | 303 | 00013_update3 | Wed Jan 14 00:00:00 1970 PST
|
|
14 | 4 | 00014 | Thu Jan 15 00:00:00 1970 PST
|
|
16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST
|
|
17 | 407 | 00017_update7 | Sun Jan 18 00:00:00 1970 PST
|
|
18 | 8 | 00018 | Mon Jan 19 00:00:00 1970 PST
|
|
19 | 509 | 00019_update9 | Tue Jan 20 00:00:00 1970 PST
|
|
20 | 0 | 00020 | Wed Jan 21 00:00:00 1970 PST
|
|
21 | 1 | 00021 | Thu Jan 22 00:00:00 1970 PST
|
|
23 | 303 | 00023_update3 | Sat Jan 24 00:00:00 1970 PST
|
|
24 | 4 | 00024 | Sun Jan 25 00:00:00 1970 PST
|
|
26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST
|
|
27 | 407 | 00027_update7 | Wed Jan 28 00:00:00 1970 PST
|
|
28 | 8 | 00028 | Thu Jan 29 00:00:00 1970 PST
|
|
29 | 509 | 00029_update9 | Fri Jan 30 00:00:00 1970 PST
|
|
30 | 0 | 00030 | Sat Jan 31 00:00:00 1970 PST
|
|
31 | 1 | 00031 | Sun Feb 01 00:00:00 1970 PST
|
|
33 | 303 | 00033_update3 | Tue Feb 03 00:00:00 1970 PST
|
|
34 | 4 | 00034 | Wed Feb 04 00:00:00 1970 PST
|
|
36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST
|
|
37 | 407 | 00037_update7 | Sat Feb 07 00:00:00 1970 PST
|
|
38 | 8 | 00038 | Sun Feb 08 00:00:00 1970 PST
|
|
39 | 509 | 00039_update9 | Mon Feb 09 00:00:00 1970 PST
|
|
40 | 0 | 00040 | Tue Feb 10 00:00:00 1970 PST
|
|
41 | 1 | 00041 | Wed Feb 11 00:00:00 1970 PST
|
|
43 | 303 | 00043_update3 | Fri Feb 13 00:00:00 1970 PST
|
|
44 | 4 | 00044 | Sat Feb 14 00:00:00 1970 PST
|
|
46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST
|
|
47 | 407 | 00047_update7 | Tue Feb 17 00:00:00 1970 PST
|
|
48 | 8 | 00048 | Wed Feb 18 00:00:00 1970 PST
|
|
49 | 509 | 00049_update9 | Thu Feb 19 00:00:00 1970 PST
|
|
50 | 0 | 00050 | Fri Feb 20 00:00:00 1970 PST
|
|
51 | 1 | 00051 | Sat Feb 21 00:00:00 1970 PST
|
|
53 | 303 | 00053_update3 | Mon Feb 23 00:00:00 1970 PST
|
|
54 | 4 | 00054 | Tue Feb 24 00:00:00 1970 PST
|
|
56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST
|
|
57 | 407 | 00057_update7 | Fri Feb 27 00:00:00 1970 PST
|
|
58 | 8 | 00058 | Sat Feb 28 00:00:00 1970 PST
|
|
59 | 509 | 00059_update9 | Sun Mar 01 00:00:00 1970 PST
|
|
60 | 0 | 00060 | Mon Mar 02 00:00:00 1970 PST
|
|
61 | 1 | 00061 | Tue Mar 03 00:00:00 1970 PST
|
|
63 | 303 | 00063_update3 | Thu Mar 05 00:00:00 1970 PST
|
|
64 | 4 | 00064 | Fri Mar 06 00:00:00 1970 PST
|
|
66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST
|
|
67 | 407 | 00067_update7 | Mon Mar 09 00:00:00 1970 PST
|
|
68 | 8 | 00068 | Tue Mar 10 00:00:00 1970 PST
|
|
69 | 509 | 00069_update9 | Wed Mar 11 00:00:00 1970 PST
|
|
70 | 0 | 00070 | Thu Mar 12 00:00:00 1970 PST
|
|
71 | 1 | 00071 | Fri Mar 13 00:00:00 1970 PST
|
|
73 | 303 | 00073_update3 | Sun Mar 15 00:00:00 1970 PST
|
|
74 | 4 | 00074 | Mon Mar 16 00:00:00 1970 PST
|
|
76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST
|
|
77 | 407 | 00077_update7 | Thu Mar 19 00:00:00 1970 PST
|
|
78 | 8 | 00078 | Fri Mar 20 00:00:00 1970 PST
|
|
79 | 509 | 00079_update9 | Sat Mar 21 00:00:00 1970 PST
|
|
80 | 0 | 00080 | Sun Mar 22 00:00:00 1970 PST
|
|
81 | 1 | 00081 | Mon Mar 23 00:00:00 1970 PST
|
|
83 | 303 | 00083_update3 | Wed Mar 25 00:00:00 1970 PST
|
|
84 | 4 | 00084 | Thu Mar 26 00:00:00 1970 PST
|
|
86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST
|
|
87 | 407 | 00087_update7 | Sun Mar 29 00:00:00 1970 PST
|
|
88 | 8 | 00088 | Mon Mar 30 00:00:00 1970 PST
|
|
89 | 509 | 00089_update9 | Tue Mar 31 00:00:00 1970 PST
|
|
90 | 0 | 00090 | Wed Apr 01 00:00:00 1970 PST
|
|
91 | 1 | 00091 | Thu Apr 02 00:00:00 1970 PST
|
|
93 | 303 | 00093_update3 | Sat Apr 04 00:00:00 1970 PST
|
|
94 | 4 | 00094 | Sun Apr 05 00:00:00 1970 PST
|
|
96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST
|
|
97 | 407 | 00097_update7 | Wed Apr 08 00:00:00 1970 PST
|
|
98 | 8 | 00098 | Thu Apr 09 00:00:00 1970 PST
|
|
99 | 509 | 00099_update9 | Fri Apr 10 00:00:00 1970 PST
|
|
100 | 0 | 00100 | Thu Jan 01 00:00:00 1970 PST
|
|
101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST
|
|
103 | 303 | 00103_update3 | Sun Jan 04 00:00:00 1970 PST
|
|
104 | 4 | 00104 | Mon Jan 05 00:00:00 1970 PST
|
|
106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST
|
|
107 | 407 | 00107_update7 | Thu Jan 08 00:00:00 1970 PST
|
|
108 | 8 | 00108 | Fri Jan 09 00:00:00 1970 PST
|
|
109 | 509 | 00109_update9 | Sat Jan 10 00:00:00 1970 PST
|
|
110 | 0 | 00110 | Sun Jan 11 00:00:00 1970 PST
|
|
111 | 1 | 00111 | Mon Jan 12 00:00:00 1970 PST
|
|
113 | 303 | 00113_update3 | Wed Jan 14 00:00:00 1970 PST
|
|
114 | 4 | 00114 | Thu Jan 15 00:00:00 1970 PST
|
|
116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 PST
|
|
117 | 407 | 00117_update7 | Sun Jan 18 00:00:00 1970 PST
|
|
118 | 8 | 00118 | Mon Jan 19 00:00:00 1970 PST
|
|
119 | 509 | 00119_update9 | Tue Jan 20 00:00:00 1970 PST
|
|
120 | 0 | 00120 | Wed Jan 21 00:00:00 1970 PST
|
|
121 | 1 | 00121 | Thu Jan 22 00:00:00 1970 PST
|
|
123 | 303 | 00123_update3 | Sat Jan 24 00:00:00 1970 PST
|
|
124 | 4 | 00124 | Sun Jan 25 00:00:00 1970 PST
|
|
126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 PST
|
|
127 | 407 | 00127_update7 | Wed Jan 28 00:00:00 1970 PST
|
|
128 | 8 | 00128 | Thu Jan 29 00:00:00 1970 PST
|
|
129 | 509 | 00129_update9 | Fri Jan 30 00:00:00 1970 PST
|
|
130 | 0 | 00130 | Sat Jan 31 00:00:00 1970 PST
|
|
131 | 1 | 00131 | Sun Feb 01 00:00:00 1970 PST
|
|
133 | 303 | 00133_update3 | Tue Feb 03 00:00:00 1970 PST
|
|
134 | 4 | 00134 | Wed Feb 04 00:00:00 1970 PST
|
|
136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 PST
|
|
137 | 407 | 00137_update7 | Sat Feb 07 00:00:00 1970 PST
|
|
138 | 8 | 00138 | Sun Feb 08 00:00:00 1970 PST
|
|
139 | 509 | 00139_update9 | Mon Feb 09 00:00:00 1970 PST
|
|
140 | 0 | 00140 | Tue Feb 10 00:00:00 1970 PST
|
|
141 | 1 | 00141 | Wed Feb 11 00:00:00 1970 PST
|
|
143 | 303 | 00143_update3 | Fri Feb 13 00:00:00 1970 PST
|
|
144 | 4 | 00144 | Sat Feb 14 00:00:00 1970 PST
|
|
146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 PST
|
|
147 | 407 | 00147_update7 | Tue Feb 17 00:00:00 1970 PST
|
|
148 | 8 | 00148 | Wed Feb 18 00:00:00 1970 PST
|
|
149 | 509 | 00149_update9 | Thu Feb 19 00:00:00 1970 PST
|
|
150 | 0 | 00150 | Fri Feb 20 00:00:00 1970 PST
|
|
151 | 1 | 00151 | Sat Feb 21 00:00:00 1970 PST
|
|
153 | 303 | 00153_update3 | Mon Feb 23 00:00:00 1970 PST
|
|
154 | 4 | 00154 | Tue Feb 24 00:00:00 1970 PST
|
|
156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 PST
|
|
157 | 407 | 00157_update7 | Fri Feb 27 00:00:00 1970 PST
|
|
158 | 8 | 00158 | Sat Feb 28 00:00:00 1970 PST
|
|
159 | 509 | 00159_update9 | Sun Mar 01 00:00:00 1970 PST
|
|
160 | 0 | 00160 | Mon Mar 02 00:00:00 1970 PST
|
|
161 | 1 | 00161 | Tue Mar 03 00:00:00 1970 PST
|
|
163 | 303 | 00163_update3 | Thu Mar 05 00:00:00 1970 PST
|
|
164 | 4 | 00164 | Fri Mar 06 00:00:00 1970 PST
|
|
166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 PST
|
|
167 | 407 | 00167_update7 | Mon Mar 09 00:00:00 1970 PST
|
|
168 | 8 | 00168 | Tue Mar 10 00:00:00 1970 PST
|
|
169 | 509 | 00169_update9 | Wed Mar 11 00:00:00 1970 PST
|
|
170 | 0 | 00170 | Thu Mar 12 00:00:00 1970 PST
|
|
171 | 1 | 00171 | Fri Mar 13 00:00:00 1970 PST
|
|
173 | 303 | 00173_update3 | Sun Mar 15 00:00:00 1970 PST
|
|
174 | 4 | 00174 | Mon Mar 16 00:00:00 1970 PST
|
|
176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 PST
|
|
177 | 407 | 00177_update7 | Thu Mar 19 00:00:00 1970 PST
|
|
178 | 8 | 00178 | Fri Mar 20 00:00:00 1970 PST
|
|
179 | 509 | 00179_update9 | Sat Mar 21 00:00:00 1970 PST
|
|
180 | 0 | 00180 | Sun Mar 22 00:00:00 1970 PST
|
|
181 | 1 | 00181 | Mon Mar 23 00:00:00 1970 PST
|
|
183 | 303 | 00183_update3 | Wed Mar 25 00:00:00 1970 PST
|
|
184 | 4 | 00184 | Thu Mar 26 00:00:00 1970 PST
|
|
186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 PST
|
|
187 | 407 | 00187_update7 | Sun Mar 29 00:00:00 1970 PST
|
|
188 | 8 | 00188 | Mon Mar 30 00:00:00 1970 PST
|
|
189 | 509 | 00189_update9 | Tue Mar 31 00:00:00 1970 PST
|
|
190 | 0 | 00190 | Wed Apr 01 00:00:00 1970 PST
|
|
191 | 1 | 00191 | Thu Apr 02 00:00:00 1970 PST
|
|
193 | 303 | 00193_update3 | Sat Apr 04 00:00:00 1970 PST
|
|
194 | 4 | 00194 | Sun Apr 05 00:00:00 1970 PST
|
|
196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 PST
|
|
197 | 407 | 00197_update7 | Wed Apr 08 00:00:00 1970 PST
|
|
198 | 8 | 00198 | Thu Apr 09 00:00:00 1970 PST
|
|
199 | 509 | 00199_update9 | Fri Apr 10 00:00:00 1970 PST
|
|
200 | 0 | 00200 | Thu Jan 01 00:00:00 1970 PST
|
|
201 | 1 | 00201 | Fri Jan 02 00:00:00 1970 PST
|
|
203 | 303 | 00203_update3 | Sun Jan 04 00:00:00 1970 PST
|
|
204 | 4 | 00204 | Mon Jan 05 00:00:00 1970 PST
|
|
206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 PST
|
|
207 | 407 | 00207_update7 | Thu Jan 08 00:00:00 1970 PST
|
|
208 | 8 | 00208 | Fri Jan 09 00:00:00 1970 PST
|
|
209 | 509 | 00209_update9 | Sat Jan 10 00:00:00 1970 PST
|
|
210 | 0 | 00210 | Sun Jan 11 00:00:00 1970 PST
|
|
211 | 1 | 00211 | Mon Jan 12 00:00:00 1970 PST
|
|
213 | 303 | 00213_update3 | Wed Jan 14 00:00:00 1970 PST
|
|
214 | 4 | 00214 | Thu Jan 15 00:00:00 1970 PST
|
|
216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 PST
|
|
217 | 407 | 00217_update7 | Sun Jan 18 00:00:00 1970 PST
|
|
218 | 8 | 00218 | Mon Jan 19 00:00:00 1970 PST
|
|
219 | 509 | 00219_update9 | Tue Jan 20 00:00:00 1970 PST
|
|
220 | 0 | 00220 | Wed Jan 21 00:00:00 1970 PST
|
|
221 | 1 | 00221 | Thu Jan 22 00:00:00 1970 PST
|
|
223 | 303 | 00223_update3 | Sat Jan 24 00:00:00 1970 PST
|
|
224 | 4 | 00224 | Sun Jan 25 00:00:00 1970 PST
|
|
226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 PST
|
|
227 | 407 | 00227_update7 | Wed Jan 28 00:00:00 1970 PST
|
|
228 | 8 | 00228 | Thu Jan 29 00:00:00 1970 PST
|
|
229 | 509 | 00229_update9 | Fri Jan 30 00:00:00 1970 PST
|
|
230 | 0 | 00230 | Sat Jan 31 00:00:00 1970 PST
|
|
231 | 1 | 00231 | Sun Feb 01 00:00:00 1970 PST
|
|
233 | 303 | 00233_update3 | Tue Feb 03 00:00:00 1970 PST
|
|
234 | 4 | 00234 | Wed Feb 04 00:00:00 1970 PST
|
|
236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 PST
|
|
237 | 407 | 00237_update7 | Sat Feb 07 00:00:00 1970 PST
|
|
238 | 8 | 00238 | Sun Feb 08 00:00:00 1970 PST
|
|
239 | 509 | 00239_update9 | Mon Feb 09 00:00:00 1970 PST
|
|
240 | 0 | 00240 | Tue Feb 10 00:00:00 1970 PST
|
|
241 | 1 | 00241 | Wed Feb 11 00:00:00 1970 PST
|
|
243 | 303 | 00243_update3 | Fri Feb 13 00:00:00 1970 PST
|
|
244 | 4 | 00244 | Sat Feb 14 00:00:00 1970 PST
|
|
246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 PST
|
|
247 | 407 | 00247_update7 | Tue Feb 17 00:00:00 1970 PST
|
|
248 | 8 | 00248 | Wed Feb 18 00:00:00 1970 PST
|
|
249 | 509 | 00249_update9 | Thu Feb 19 00:00:00 1970 PST
|
|
250 | 0 | 00250 | Fri Feb 20 00:00:00 1970 PST
|
|
251 | 1 | 00251 | Sat Feb 21 00:00:00 1970 PST
|
|
253 | 303 | 00253_update3 | Mon Feb 23 00:00:00 1970 PST
|
|
254 | 4 | 00254 | Tue Feb 24 00:00:00 1970 PST
|
|
256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 PST
|
|
257 | 407 | 00257_update7 | Fri Feb 27 00:00:00 1970 PST
|
|
258 | 8 | 00258 | Sat Feb 28 00:00:00 1970 PST
|
|
259 | 509 | 00259_update9 | Sun Mar 01 00:00:00 1970 PST
|
|
260 | 0 | 00260 | Mon Mar 02 00:00:00 1970 PST
|
|
261 | 1 | 00261 | Tue Mar 03 00:00:00 1970 PST
|
|
263 | 303 | 00263_update3 | Thu Mar 05 00:00:00 1970 PST
|
|
264 | 4 | 00264 | Fri Mar 06 00:00:00 1970 PST
|
|
266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 PST
|
|
267 | 407 | 00267_update7 | Mon Mar 09 00:00:00 1970 PST
|
|
268 | 8 | 00268 | Tue Mar 10 00:00:00 1970 PST
|
|
269 | 509 | 00269_update9 | Wed Mar 11 00:00:00 1970 PST
|
|
270 | 0 | 00270 | Thu Mar 12 00:00:00 1970 PST
|
|
271 | 1 | 00271 | Fri Mar 13 00:00:00 1970 PST
|
|
273 | 303 | 00273_update3 | Sun Mar 15 00:00:00 1970 PST
|
|
274 | 4 | 00274 | Mon Mar 16 00:00:00 1970 PST
|
|
276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 PST
|
|
277 | 407 | 00277_update7 | Thu Mar 19 00:00:00 1970 PST
|
|
278 | 8 | 00278 | Fri Mar 20 00:00:00 1970 PST
|
|
279 | 509 | 00279_update9 | Sat Mar 21 00:00:00 1970 PST
|
|
280 | 0 | 00280 | Sun Mar 22 00:00:00 1970 PST
|
|
281 | 1 | 00281 | Mon Mar 23 00:00:00 1970 PST
|
|
283 | 303 | 00283_update3 | Wed Mar 25 00:00:00 1970 PST
|
|
284 | 4 | 00284 | Thu Mar 26 00:00:00 1970 PST
|
|
286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 PST
|
|
287 | 407 | 00287_update7 | Sun Mar 29 00:00:00 1970 PST
|
|
288 | 8 | 00288 | Mon Mar 30 00:00:00 1970 PST
|
|
289 | 509 | 00289_update9 | Tue Mar 31 00:00:00 1970 PST
|
|
290 | 0 | 00290 | Wed Apr 01 00:00:00 1970 PST
|
|
291 | 1 | 00291 | Thu Apr 02 00:00:00 1970 PST
|
|
293 | 303 | 00293_update3 | Sat Apr 04 00:00:00 1970 PST
|
|
294 | 4 | 00294 | Sun Apr 05 00:00:00 1970 PST
|
|
296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 PST
|
|
297 | 407 | 00297_update7 | Wed Apr 08 00:00:00 1970 PST
|
|
298 | 8 | 00298 | Thu Apr 09 00:00:00 1970 PST
|
|
299 | 509 | 00299_update9 | Fri Apr 10 00:00:00 1970 PST
|
|
300 | 0 | 00300 | Thu Jan 01 00:00:00 1970 PST
|
|
301 | 1 | 00301 | Fri Jan 02 00:00:00 1970 PST
|
|
303 | 303 | 00303_update3 | Sun Jan 04 00:00:00 1970 PST
|
|
304 | 4 | 00304 | Mon Jan 05 00:00:00 1970 PST
|
|
306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 PST
|
|
307 | 407 | 00307_update7 | Thu Jan 08 00:00:00 1970 PST
|
|
308 | 8 | 00308 | Fri Jan 09 00:00:00 1970 PST
|
|
309 | 509 | 00309_update9 | Sat Jan 10 00:00:00 1970 PST
|
|
310 | 0 | 00310 | Sun Jan 11 00:00:00 1970 PST
|
|
311 | 1 | 00311 | Mon Jan 12 00:00:00 1970 PST
|
|
313 | 303 | 00313_update3 | Wed Jan 14 00:00:00 1970 PST
|
|
314 | 4 | 00314 | Thu Jan 15 00:00:00 1970 PST
|
|
316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 PST
|
|
317 | 407 | 00317_update7 | Sun Jan 18 00:00:00 1970 PST
|
|
318 | 8 | 00318 | Mon Jan 19 00:00:00 1970 PST
|
|
319 | 509 | 00319_update9 | Tue Jan 20 00:00:00 1970 PST
|
|
320 | 0 | 00320 | Wed Jan 21 00:00:00 1970 PST
|
|
321 | 1 | 00321 | Thu Jan 22 00:00:00 1970 PST
|
|
323 | 303 | 00323_update3 | Sat Jan 24 00:00:00 1970 PST
|
|
324 | 4 | 00324 | Sun Jan 25 00:00:00 1970 PST
|
|
326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 PST
|
|
327 | 407 | 00327_update7 | Wed Jan 28 00:00:00 1970 PST
|
|
328 | 8 | 00328 | Thu Jan 29 00:00:00 1970 PST
|
|
329 | 509 | 00329_update9 | Fri Jan 30 00:00:00 1970 PST
|
|
330 | 0 | 00330 | Sat Jan 31 00:00:00 1970 PST
|
|
331 | 1 | 00331 | Sun Feb 01 00:00:00 1970 PST
|
|
333 | 303 | 00333_update3 | Tue Feb 03 00:00:00 1970 PST
|
|
334 | 4 | 00334 | Wed Feb 04 00:00:00 1970 PST
|
|
336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 PST
|
|
337 | 407 | 00337_update7 | Sat Feb 07 00:00:00 1970 PST
|
|
338 | 8 | 00338 | Sun Feb 08 00:00:00 1970 PST
|
|
339 | 509 | 00339_update9 | Mon Feb 09 00:00:00 1970 PST
|
|
340 | 0 | 00340 | Tue Feb 10 00:00:00 1970 PST
|
|
341 | 1 | 00341 | Wed Feb 11 00:00:00 1970 PST
|
|
343 | 303 | 00343_update3 | Fri Feb 13 00:00:00 1970 PST
|
|
344 | 4 | 00344 | Sat Feb 14 00:00:00 1970 PST
|
|
346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 PST
|
|
347 | 407 | 00347_update7 | Tue Feb 17 00:00:00 1970 PST
|
|
348 | 8 | 00348 | Wed Feb 18 00:00:00 1970 PST
|
|
349 | 509 | 00349_update9 | Thu Feb 19 00:00:00 1970 PST
|
|
350 | 0 | 00350 | Fri Feb 20 00:00:00 1970 PST
|
|
351 | 1 | 00351 | Sat Feb 21 00:00:00 1970 PST
|
|
353 | 303 | 00353_update3 | Mon Feb 23 00:00:00 1970 PST
|
|
354 | 4 | 00354 | Tue Feb 24 00:00:00 1970 PST
|
|
356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 PST
|
|
357 | 407 | 00357_update7 | Fri Feb 27 00:00:00 1970 PST
|
|
358 | 8 | 00358 | Sat Feb 28 00:00:00 1970 PST
|
|
359 | 509 | 00359_update9 | Sun Mar 01 00:00:00 1970 PST
|
|
360 | 0 | 00360 | Mon Mar 02 00:00:00 1970 PST
|
|
361 | 1 | 00361 | Tue Mar 03 00:00:00 1970 PST
|
|
363 | 303 | 00363_update3 | Thu Mar 05 00:00:00 1970 PST
|
|
364 | 4 | 00364 | Fri Mar 06 00:00:00 1970 PST
|
|
366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 PST
|
|
367 | 407 | 00367_update7 | Mon Mar 09 00:00:00 1970 PST
|
|
368 | 8 | 00368 | Tue Mar 10 00:00:00 1970 PST
|
|
369 | 509 | 00369_update9 | Wed Mar 11 00:00:00 1970 PST
|
|
370 | 0 | 00370 | Thu Mar 12 00:00:00 1970 PST
|
|
371 | 1 | 00371 | Fri Mar 13 00:00:00 1970 PST
|
|
373 | 303 | 00373_update3 | Sun Mar 15 00:00:00 1970 PST
|
|
374 | 4 | 00374 | Mon Mar 16 00:00:00 1970 PST
|
|
376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 PST
|
|
377 | 407 | 00377_update7 | Thu Mar 19 00:00:00 1970 PST
|
|
378 | 8 | 00378 | Fri Mar 20 00:00:00 1970 PST
|
|
379 | 509 | 00379_update9 | Sat Mar 21 00:00:00 1970 PST
|
|
380 | 0 | 00380 | Sun Mar 22 00:00:00 1970 PST
|
|
381 | 1 | 00381 | Mon Mar 23 00:00:00 1970 PST
|
|
383 | 303 | 00383_update3 | Wed Mar 25 00:00:00 1970 PST
|
|
384 | 4 | 00384 | Thu Mar 26 00:00:00 1970 PST
|
|
386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 PST
|
|
387 | 407 | 00387_update7 | Sun Mar 29 00:00:00 1970 PST
|
|
388 | 8 | 00388 | Mon Mar 30 00:00:00 1970 PST
|
|
389 | 509 | 00389_update9 | Tue Mar 31 00:00:00 1970 PST
|
|
390 | 0 | 00390 | Wed Apr 01 00:00:00 1970 PST
|
|
391 | 1 | 00391 | Thu Apr 02 00:00:00 1970 PST
|
|
393 | 303 | 00393_update3 | Sat Apr 04 00:00:00 1970 PST
|
|
394 | 4 | 00394 | Sun Apr 05 00:00:00 1970 PST
|
|
396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 PST
|
|
397 | 407 | 00397_update7 | Wed Apr 08 00:00:00 1970 PST
|
|
398 | 8 | 00398 | Thu Apr 09 00:00:00 1970 PST
|
|
399 | 509 | 00399_update9 | Fri Apr 10 00:00:00 1970 PST
|
|
400 | 0 | 00400 | Thu Jan 01 00:00:00 1970 PST
|
|
401 | 1 | 00401 | Fri Jan 02 00:00:00 1970 PST
|
|
403 | 303 | 00403_update3 | Sun Jan 04 00:00:00 1970 PST
|
|
404 | 4 | 00404 | Mon Jan 05 00:00:00 1970 PST
|
|
406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 PST
|
|
407 | 407 | 00407_update7 | Thu Jan 08 00:00:00 1970 PST
|
|
408 | 8 | 00408 | Fri Jan 09 00:00:00 1970 PST
|
|
409 | 509 | 00409_update9 | Sat Jan 10 00:00:00 1970 PST
|
|
410 | 0 | 00410 | Sun Jan 11 00:00:00 1970 PST
|
|
411 | 1 | 00411 | Mon Jan 12 00:00:00 1970 PST
|
|
413 | 303 | 00413_update3 | Wed Jan 14 00:00:00 1970 PST
|
|
414 | 4 | 00414 | Thu Jan 15 00:00:00 1970 PST
|
|
416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 PST
|
|
417 | 407 | 00417_update7 | Sun Jan 18 00:00:00 1970 PST
|
|
418 | 8 | 00418 | Mon Jan 19 00:00:00 1970 PST
|
|
419 | 509 | 00419_update9 | Tue Jan 20 00:00:00 1970 PST
|
|
420 | 0 | 00420 | Wed Jan 21 00:00:00 1970 PST
|
|
421 | 1 | 00421 | Thu Jan 22 00:00:00 1970 PST
|
|
423 | 303 | 00423_update3 | Sat Jan 24 00:00:00 1970 PST
|
|
424 | 4 | 00424 | Sun Jan 25 00:00:00 1970 PST
|
|
426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 PST
|
|
427 | 407 | 00427_update7 | Wed Jan 28 00:00:00 1970 PST
|
|
428 | 8 | 00428 | Thu Jan 29 00:00:00 1970 PST
|
|
429 | 509 | 00429_update9 | Fri Jan 30 00:00:00 1970 PST
|
|
430 | 0 | 00430 | Sat Jan 31 00:00:00 1970 PST
|
|
431 | 1 | 00431 | Sun Feb 01 00:00:00 1970 PST
|
|
433 | 303 | 00433_update3 | Tue Feb 03 00:00:00 1970 PST
|
|
434 | 4 | 00434 | Wed Feb 04 00:00:00 1970 PST
|
|
436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 PST
|
|
437 | 407 | 00437_update7 | Sat Feb 07 00:00:00 1970 PST
|
|
438 | 8 | 00438 | Sun Feb 08 00:00:00 1970 PST
|
|
439 | 509 | 00439_update9 | Mon Feb 09 00:00:00 1970 PST
|
|
440 | 0 | 00440 | Tue Feb 10 00:00:00 1970 PST
|
|
441 | 1 | 00441 | Wed Feb 11 00:00:00 1970 PST
|
|
443 | 303 | 00443_update3 | Fri Feb 13 00:00:00 1970 PST
|
|
444 | 4 | 00444 | Sat Feb 14 00:00:00 1970 PST
|
|
446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 PST
|
|
447 | 407 | 00447_update7 | Tue Feb 17 00:00:00 1970 PST
|
|
448 | 8 | 00448 | Wed Feb 18 00:00:00 1970 PST
|
|
449 | 509 | 00449_update9 | Thu Feb 19 00:00:00 1970 PST
|
|
450 | 0 | 00450 | Fri Feb 20 00:00:00 1970 PST
|
|
451 | 1 | 00451 | Sat Feb 21 00:00:00 1970 PST
|
|
453 | 303 | 00453_update3 | Mon Feb 23 00:00:00 1970 PST
|
|
454 | 4 | 00454 | Tue Feb 24 00:00:00 1970 PST
|
|
456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 PST
|
|
457 | 407 | 00457_update7 | Fri Feb 27 00:00:00 1970 PST
|
|
458 | 8 | 00458 | Sat Feb 28 00:00:00 1970 PST
|
|
459 | 509 | 00459_update9 | Sun Mar 01 00:00:00 1970 PST
|
|
460 | 0 | 00460 | Mon Mar 02 00:00:00 1970 PST
|
|
461 | 1 | 00461 | Tue Mar 03 00:00:00 1970 PST
|
|
463 | 303 | 00463_update3 | Thu Mar 05 00:00:00 1970 PST
|
|
464 | 4 | 00464 | Fri Mar 06 00:00:00 1970 PST
|
|
466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 PST
|
|
467 | 407 | 00467_update7 | Mon Mar 09 00:00:00 1970 PST
|
|
468 | 8 | 00468 | Tue Mar 10 00:00:00 1970 PST
|
|
469 | 509 | 00469_update9 | Wed Mar 11 00:00:00 1970 PST
|
|
470 | 0 | 00470 | Thu Mar 12 00:00:00 1970 PST
|
|
471 | 1 | 00471 | Fri Mar 13 00:00:00 1970 PST
|
|
473 | 303 | 00473_update3 | Sun Mar 15 00:00:00 1970 PST
|
|
474 | 4 | 00474 | Mon Mar 16 00:00:00 1970 PST
|
|
476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 PST
|
|
477 | 407 | 00477_update7 | Thu Mar 19 00:00:00 1970 PST
|
|
478 | 8 | 00478 | Fri Mar 20 00:00:00 1970 PST
|
|
479 | 509 | 00479_update9 | Sat Mar 21 00:00:00 1970 PST
|
|
480 | 0 | 00480 | Sun Mar 22 00:00:00 1970 PST
|
|
481 | 1 | 00481 | Mon Mar 23 00:00:00 1970 PST
|
|
483 | 303 | 00483_update3 | Wed Mar 25 00:00:00 1970 PST
|
|
484 | 4 | 00484 | Thu Mar 26 00:00:00 1970 PST
|
|
486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 PST
|
|
487 | 407 | 00487_update7 | Sun Mar 29 00:00:00 1970 PST
|
|
488 | 8 | 00488 | Mon Mar 30 00:00:00 1970 PST
|
|
489 | 509 | 00489_update9 | Tue Mar 31 00:00:00 1970 PST
|
|
490 | 0 | 00490 | Wed Apr 01 00:00:00 1970 PST
|
|
491 | 1 | 00491 | Thu Apr 02 00:00:00 1970 PST
|
|
493 | 303 | 00493_update3 | Sat Apr 04 00:00:00 1970 PST
|
|
494 | 4 | 00494 | Sun Apr 05 00:00:00 1970 PST
|
|
496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 PST
|
|
497 | 407 | 00497_update7 | Wed Apr 08 00:00:00 1970 PST
|
|
498 | 8 | 00498 | Thu Apr 09 00:00:00 1970 PST
|
|
499 | 509 | 00499_update9 | Fri Apr 10 00:00:00 1970 PST
|
|
500 | 0 | 00500 | Thu Jan 01 00:00:00 1970 PST
|
|
501 | 1 | 00501 | Fri Jan 02 00:00:00 1970 PST
|
|
503 | 303 | 00503_update3 | Sun Jan 04 00:00:00 1970 PST
|
|
504 | 4 | 00504 | Mon Jan 05 00:00:00 1970 PST
|
|
506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 PST
|
|
507 | 407 | 00507_update7 | Thu Jan 08 00:00:00 1970 PST
|
|
508 | 8 | 00508 | Fri Jan 09 00:00:00 1970 PST
|
|
509 | 509 | 00509_update9 | Sat Jan 10 00:00:00 1970 PST
|
|
510 | 0 | 00510 | Sun Jan 11 00:00:00 1970 PST
|
|
511 | 1 | 00511 | Mon Jan 12 00:00:00 1970 PST
|
|
513 | 303 | 00513_update3 | Wed Jan 14 00:00:00 1970 PST
|
|
514 | 4 | 00514 | Thu Jan 15 00:00:00 1970 PST
|
|
516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 PST
|
|
517 | 407 | 00517_update7 | Sun Jan 18 00:00:00 1970 PST
|
|
518 | 8 | 00518 | Mon Jan 19 00:00:00 1970 PST
|
|
519 | 509 | 00519_update9 | Tue Jan 20 00:00:00 1970 PST
|
|
520 | 0 | 00520 | Wed Jan 21 00:00:00 1970 PST
|
|
521 | 1 | 00521 | Thu Jan 22 00:00:00 1970 PST
|
|
523 | 303 | 00523_update3 | Sat Jan 24 00:00:00 1970 PST
|
|
524 | 4 | 00524 | Sun Jan 25 00:00:00 1970 PST
|
|
526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 PST
|
|
527 | 407 | 00527_update7 | Wed Jan 28 00:00:00 1970 PST
|
|
528 | 8 | 00528 | Thu Jan 29 00:00:00 1970 PST
|
|
529 | 509 | 00529_update9 | Fri Jan 30 00:00:00 1970 PST
|
|
530 | 0 | 00530 | Sat Jan 31 00:00:00 1970 PST
|
|
531 | 1 | 00531 | Sun Feb 01 00:00:00 1970 PST
|
|
533 | 303 | 00533_update3 | Tue Feb 03 00:00:00 1970 PST
|
|
534 | 4 | 00534 | Wed Feb 04 00:00:00 1970 PST
|
|
536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 PST
|
|
537 | 407 | 00537_update7 | Sat Feb 07 00:00:00 1970 PST
|
|
538 | 8 | 00538 | Sun Feb 08 00:00:00 1970 PST
|
|
539 | 509 | 00539_update9 | Mon Feb 09 00:00:00 1970 PST
|
|
540 | 0 | 00540 | Tue Feb 10 00:00:00 1970 PST
|
|
541 | 1 | 00541 | Wed Feb 11 00:00:00 1970 PST
|
|
543 | 303 | 00543_update3 | Fri Feb 13 00:00:00 1970 PST
|
|
544 | 4 | 00544 | Sat Feb 14 00:00:00 1970 PST
|
|
546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 PST
|
|
547 | 407 | 00547_update7 | Tue Feb 17 00:00:00 1970 PST
|
|
548 | 8 | 00548 | Wed Feb 18 00:00:00 1970 PST
|
|
549 | 509 | 00549_update9 | Thu Feb 19 00:00:00 1970 PST
|
|
550 | 0 | 00550 | Fri Feb 20 00:00:00 1970 PST
|
|
551 | 1 | 00551 | Sat Feb 21 00:00:00 1970 PST
|
|
553 | 303 | 00553_update3 | Mon Feb 23 00:00:00 1970 PST
|
|
554 | 4 | 00554 | Tue Feb 24 00:00:00 1970 PST
|
|
556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 PST
|
|
557 | 407 | 00557_update7 | Fri Feb 27 00:00:00 1970 PST
|
|
558 | 8 | 00558 | Sat Feb 28 00:00:00 1970 PST
|
|
559 | 509 | 00559_update9 | Sun Mar 01 00:00:00 1970 PST
|
|
560 | 0 | 00560 | Mon Mar 02 00:00:00 1970 PST
|
|
561 | 1 | 00561 | Tue Mar 03 00:00:00 1970 PST
|
|
563 | 303 | 00563_update3 | Thu Mar 05 00:00:00 1970 PST
|
|
564 | 4 | 00564 | Fri Mar 06 00:00:00 1970 PST
|
|
566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 PST
|
|
567 | 407 | 00567_update7 | Mon Mar 09 00:00:00 1970 PST
|
|
568 | 8 | 00568 | Tue Mar 10 00:00:00 1970 PST
|
|
569 | 509 | 00569_update9 | Wed Mar 11 00:00:00 1970 PST
|
|
570 | 0 | 00570 | Thu Mar 12 00:00:00 1970 PST
|
|
571 | 1 | 00571 | Fri Mar 13 00:00:00 1970 PST
|
|
573 | 303 | 00573_update3 | Sun Mar 15 00:00:00 1970 PST
|
|
574 | 4 | 00574 | Mon Mar 16 00:00:00 1970 PST
|
|
576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 PST
|
|
577 | 407 | 00577_update7 | Thu Mar 19 00:00:00 1970 PST
|
|
578 | 8 | 00578 | Fri Mar 20 00:00:00 1970 PST
|
|
579 | 509 | 00579_update9 | Sat Mar 21 00:00:00 1970 PST
|
|
580 | 0 | 00580 | Sun Mar 22 00:00:00 1970 PST
|
|
581 | 1 | 00581 | Mon Mar 23 00:00:00 1970 PST
|
|
583 | 303 | 00583_update3 | Wed Mar 25 00:00:00 1970 PST
|
|
584 | 4 | 00584 | Thu Mar 26 00:00:00 1970 PST
|
|
586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 PST
|
|
587 | 407 | 00587_update7 | Sun Mar 29 00:00:00 1970 PST
|
|
588 | 8 | 00588 | Mon Mar 30 00:00:00 1970 PST
|
|
589 | 509 | 00589_update9 | Tue Mar 31 00:00:00 1970 PST
|
|
590 | 0 | 00590 | Wed Apr 01 00:00:00 1970 PST
|
|
591 | 1 | 00591 | Thu Apr 02 00:00:00 1970 PST
|
|
593 | 303 | 00593_update3 | Sat Apr 04 00:00:00 1970 PST
|
|
594 | 4 | 00594 | Sun Apr 05 00:00:00 1970 PST
|
|
596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 PST
|
|
597 | 407 | 00597_update7 | Wed Apr 08 00:00:00 1970 PST
|
|
598 | 8 | 00598 | Thu Apr 09 00:00:00 1970 PST
|
|
599 | 509 | 00599_update9 | Fri Apr 10 00:00:00 1970 PST
|
|
600 | 0 | 00600 | Thu Jan 01 00:00:00 1970 PST
|
|
601 | 1 | 00601 | Fri Jan 02 00:00:00 1970 PST
|
|
603 | 303 | 00603_update3 | Sun Jan 04 00:00:00 1970 PST
|
|
604 | 4 | 00604 | Mon Jan 05 00:00:00 1970 PST
|
|
606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 PST
|
|
607 | 407 | 00607_update7 | Thu Jan 08 00:00:00 1970 PST
|
|
608 | 8 | 00608 | Fri Jan 09 00:00:00 1970 PST
|
|
609 | 509 | 00609_update9 | Sat Jan 10 00:00:00 1970 PST
|
|
610 | 0 | 00610 | Sun Jan 11 00:00:00 1970 PST
|
|
611 | 1 | 00611 | Mon Jan 12 00:00:00 1970 PST
|
|
613 | 303 | 00613_update3 | Wed Jan 14 00:00:00 1970 PST
|
|
614 | 4 | 00614 | Thu Jan 15 00:00:00 1970 PST
|
|
616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 PST
|
|
617 | 407 | 00617_update7 | Sun Jan 18 00:00:00 1970 PST
|
|
618 | 8 | 00618 | Mon Jan 19 00:00:00 1970 PST
|
|
619 | 509 | 00619_update9 | Tue Jan 20 00:00:00 1970 PST
|
|
620 | 0 | 00620 | Wed Jan 21 00:00:00 1970 PST
|
|
621 | 1 | 00621 | Thu Jan 22 00:00:00 1970 PST
|
|
623 | 303 | 00623_update3 | Sat Jan 24 00:00:00 1970 PST
|
|
624 | 4 | 00624 | Sun Jan 25 00:00:00 1970 PST
|
|
626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 PST
|
|
627 | 407 | 00627_update7 | Wed Jan 28 00:00:00 1970 PST
|
|
628 | 8 | 00628 | Thu Jan 29 00:00:00 1970 PST
|
|
629 | 509 | 00629_update9 | Fri Jan 30 00:00:00 1970 PST
|
|
630 | 0 | 00630 | Sat Jan 31 00:00:00 1970 PST
|
|
631 | 1 | 00631 | Sun Feb 01 00:00:00 1970 PST
|
|
633 | 303 | 00633_update3 | Tue Feb 03 00:00:00 1970 PST
|
|
634 | 4 | 00634 | Wed Feb 04 00:00:00 1970 PST
|
|
636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 PST
|
|
637 | 407 | 00637_update7 | Sat Feb 07 00:00:00 1970 PST
|
|
638 | 8 | 00638 | Sun Feb 08 00:00:00 1970 PST
|
|
639 | 509 | 00639_update9 | Mon Feb 09 00:00:00 1970 PST
|
|
640 | 0 | 00640 | Tue Feb 10 00:00:00 1970 PST
|
|
641 | 1 | 00641 | Wed Feb 11 00:00:00 1970 PST
|
|
643 | 303 | 00643_update3 | Fri Feb 13 00:00:00 1970 PST
|
|
644 | 4 | 00644 | Sat Feb 14 00:00:00 1970 PST
|
|
646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 PST
|
|
647 | 407 | 00647_update7 | Tue Feb 17 00:00:00 1970 PST
|
|
648 | 8 | 00648 | Wed Feb 18 00:00:00 1970 PST
|
|
649 | 509 | 00649_update9 | Thu Feb 19 00:00:00 1970 PST
|
|
650 | 0 | 00650 | Fri Feb 20 00:00:00 1970 PST
|
|
651 | 1 | 00651 | Sat Feb 21 00:00:00 1970 PST
|
|
653 | 303 | 00653_update3 | Mon Feb 23 00:00:00 1970 PST
|
|
654 | 4 | 00654 | Tue Feb 24 00:00:00 1970 PST
|
|
656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 PST
|
|
657 | 407 | 00657_update7 | Fri Feb 27 00:00:00 1970 PST
|
|
658 | 8 | 00658 | Sat Feb 28 00:00:00 1970 PST
|
|
659 | 509 | 00659_update9 | Sun Mar 01 00:00:00 1970 PST
|
|
660 | 0 | 00660 | Mon Mar 02 00:00:00 1970 PST
|
|
661 | 1 | 00661 | Tue Mar 03 00:00:00 1970 PST
|
|
663 | 303 | 00663_update3 | Thu Mar 05 00:00:00 1970 PST
|
|
664 | 4 | 00664 | Fri Mar 06 00:00:00 1970 PST
|
|
666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 PST
|
|
667 | 407 | 00667_update7 | Mon Mar 09 00:00:00 1970 PST
|
|
668 | 8 | 00668 | Tue Mar 10 00:00:00 1970 PST
|
|
669 | 509 | 00669_update9 | Wed Mar 11 00:00:00 1970 PST
|
|
670 | 0 | 00670 | Thu Mar 12 00:00:00 1970 PST
|
|
671 | 1 | 00671 | Fri Mar 13 00:00:00 1970 PST
|
|
673 | 303 | 00673_update3 | Sun Mar 15 00:00:00 1970 PST
|
|
674 | 4 | 00674 | Mon Mar 16 00:00:00 1970 PST
|
|
676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 PST
|
|
677 | 407 | 00677_update7 | Thu Mar 19 00:00:00 1970 PST
|
|
678 | 8 | 00678 | Fri Mar 20 00:00:00 1970 PST
|
|
679 | 509 | 00679_update9 | Sat Mar 21 00:00:00 1970 PST
|
|
680 | 0 | 00680 | Sun Mar 22 00:00:00 1970 PST
|
|
681 | 1 | 00681 | Mon Mar 23 00:00:00 1970 PST
|
|
683 | 303 | 00683_update3 | Wed Mar 25 00:00:00 1970 PST
|
|
684 | 4 | 00684 | Thu Mar 26 00:00:00 1970 PST
|
|
686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 PST
|
|
687 | 407 | 00687_update7 | Sun Mar 29 00:00:00 1970 PST
|
|
688 | 8 | 00688 | Mon Mar 30 00:00:00 1970 PST
|
|
689 | 509 | 00689_update9 | Tue Mar 31 00:00:00 1970 PST
|
|
690 | 0 | 00690 | Wed Apr 01 00:00:00 1970 PST
|
|
691 | 1 | 00691 | Thu Apr 02 00:00:00 1970 PST
|
|
693 | 303 | 00693_update3 | Sat Apr 04 00:00:00 1970 PST
|
|
694 | 4 | 00694 | Sun Apr 05 00:00:00 1970 PST
|
|
696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 PST
|
|
697 | 407 | 00697_update7 | Wed Apr 08 00:00:00 1970 PST
|
|
698 | 8 | 00698 | Thu Apr 09 00:00:00 1970 PST
|
|
699 | 509 | 00699_update9 | Fri Apr 10 00:00:00 1970 PST
|
|
700 | 0 | 00700 | Thu Jan 01 00:00:00 1970 PST
|
|
701 | 1 | 00701 | Fri Jan 02 00:00:00 1970 PST
|
|
703 | 303 | 00703_update3 | Sun Jan 04 00:00:00 1970 PST
|
|
704 | 4 | 00704 | Mon Jan 05 00:00:00 1970 PST
|
|
706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 PST
|
|
707 | 407 | 00707_update7 | Thu Jan 08 00:00:00 1970 PST
|
|
708 | 8 | 00708 | Fri Jan 09 00:00:00 1970 PST
|
|
709 | 509 | 00709_update9 | Sat Jan 10 00:00:00 1970 PST
|
|
710 | 0 | 00710 | Sun Jan 11 00:00:00 1970 PST
|
|
711 | 1 | 00711 | Mon Jan 12 00:00:00 1970 PST
|
|
713 | 303 | 00713_update3 | Wed Jan 14 00:00:00 1970 PST
|
|
714 | 4 | 00714 | Thu Jan 15 00:00:00 1970 PST
|
|
716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 PST
|
|
717 | 407 | 00717_update7 | Sun Jan 18 00:00:00 1970 PST
|
|
718 | 8 | 00718 | Mon Jan 19 00:00:00 1970 PST
|
|
719 | 509 | 00719_update9 | Tue Jan 20 00:00:00 1970 PST
|
|
720 | 0 | 00720 | Wed Jan 21 00:00:00 1970 PST
|
|
721 | 1 | 00721 | Thu Jan 22 00:00:00 1970 PST
|
|
723 | 303 | 00723_update3 | Sat Jan 24 00:00:00 1970 PST
|
|
724 | 4 | 00724 | Sun Jan 25 00:00:00 1970 PST
|
|
726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 PST
|
|
727 | 407 | 00727_update7 | Wed Jan 28 00:00:00 1970 PST
|
|
728 | 8 | 00728 | Thu Jan 29 00:00:00 1970 PST
|
|
729 | 509 | 00729_update9 | Fri Jan 30 00:00:00 1970 PST
|
|
730 | 0 | 00730 | Sat Jan 31 00:00:00 1970 PST
|
|
731 | 1 | 00731 | Sun Feb 01 00:00:00 1970 PST
|
|
733 | 303 | 00733_update3 | Tue Feb 03 00:00:00 1970 PST
|
|
734 | 4 | 00734 | Wed Feb 04 00:00:00 1970 PST
|
|
736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 PST
|
|
737 | 407 | 00737_update7 | Sat Feb 07 00:00:00 1970 PST
|
|
738 | 8 | 00738 | Sun Feb 08 00:00:00 1970 PST
|
|
739 | 509 | 00739_update9 | Mon Feb 09 00:00:00 1970 PST
|
|
740 | 0 | 00740 | Tue Feb 10 00:00:00 1970 PST
|
|
741 | 1 | 00741 | Wed Feb 11 00:00:00 1970 PST
|
|
743 | 303 | 00743_update3 | Fri Feb 13 00:00:00 1970 PST
|
|
744 | 4 | 00744 | Sat Feb 14 00:00:00 1970 PST
|
|
746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 PST
|
|
747 | 407 | 00747_update7 | Tue Feb 17 00:00:00 1970 PST
|
|
748 | 8 | 00748 | Wed Feb 18 00:00:00 1970 PST
|
|
749 | 509 | 00749_update9 | Thu Feb 19 00:00:00 1970 PST
|
|
750 | 0 | 00750 | Fri Feb 20 00:00:00 1970 PST
|
|
751 | 1 | 00751 | Sat Feb 21 00:00:00 1970 PST
|
|
753 | 303 | 00753_update3 | Mon Feb 23 00:00:00 1970 PST
|
|
754 | 4 | 00754 | Tue Feb 24 00:00:00 1970 PST
|
|
756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 PST
|
|
757 | 407 | 00757_update7 | Fri Feb 27 00:00:00 1970 PST
|
|
758 | 8 | 00758 | Sat Feb 28 00:00:00 1970 PST
|
|
759 | 509 | 00759_update9 | Sun Mar 01 00:00:00 1970 PST
|
|
760 | 0 | 00760 | Mon Mar 02 00:00:00 1970 PST
|
|
761 | 1 | 00761 | Tue Mar 03 00:00:00 1970 PST
|
|
763 | 303 | 00763_update3 | Thu Mar 05 00:00:00 1970 PST
|
|
764 | 4 | 00764 | Fri Mar 06 00:00:00 1970 PST
|
|
766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 PST
|
|
767 | 407 | 00767_update7 | Mon Mar 09 00:00:00 1970 PST
|
|
768 | 8 | 00768 | Tue Mar 10 00:00:00 1970 PST
|
|
769 | 509 | 00769_update9 | Wed Mar 11 00:00:00 1970 PST
|
|
770 | 0 | 00770 | Thu Mar 12 00:00:00 1970 PST
|
|
771 | 1 | 00771 | Fri Mar 13 00:00:00 1970 PST
|
|
773 | 303 | 00773_update3 | Sun Mar 15 00:00:00 1970 PST
|
|
774 | 4 | 00774 | Mon Mar 16 00:00:00 1970 PST
|
|
776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 PST
|
|
777 | 407 | 00777_update7 | Thu Mar 19 00:00:00 1970 PST
|
|
778 | 8 | 00778 | Fri Mar 20 00:00:00 1970 PST
|
|
779 | 509 | 00779_update9 | Sat Mar 21 00:00:00 1970 PST
|
|
780 | 0 | 00780 | Sun Mar 22 00:00:00 1970 PST
|
|
781 | 1 | 00781 | Mon Mar 23 00:00:00 1970 PST
|
|
783 | 303 | 00783_update3 | Wed Mar 25 00:00:00 1970 PST
|
|
784 | 4 | 00784 | Thu Mar 26 00:00:00 1970 PST
|
|
786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 PST
|
|
787 | 407 | 00787_update7 | Sun Mar 29 00:00:00 1970 PST
|
|
788 | 8 | 00788 | Mon Mar 30 00:00:00 1970 PST
|
|
789 | 509 | 00789_update9 | Tue Mar 31 00:00:00 1970 PST
|
|
790 | 0 | 00790 | Wed Apr 01 00:00:00 1970 PST
|
|
791 | 1 | 00791 | Thu Apr 02 00:00:00 1970 PST
|
|
793 | 303 | 00793_update3 | Sat Apr 04 00:00:00 1970 PST
|
|
794 | 4 | 00794 | Sun Apr 05 00:00:00 1970 PST
|
|
796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 PST
|
|
797 | 407 | 00797_update7 | Wed Apr 08 00:00:00 1970 PST
|
|
798 | 8 | 00798 | Thu Apr 09 00:00:00 1970 PST
|
|
799 | 509 | 00799_update9 | Fri Apr 10 00:00:00 1970 PST
|
|
800 | 0 | 00800 | Thu Jan 01 00:00:00 1970 PST
|
|
801 | 1 | 00801 | Fri Jan 02 00:00:00 1970 PST
|
|
803 | 303 | 00803_update3 | Sun Jan 04 00:00:00 1970 PST
|
|
804 | 4 | 00804 | Mon Jan 05 00:00:00 1970 PST
|
|
806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 PST
|
|
807 | 407 | 00807_update7 | Thu Jan 08 00:00:00 1970 PST
|
|
808 | 8 | 00808 | Fri Jan 09 00:00:00 1970 PST
|
|
809 | 509 | 00809_update9 | Sat Jan 10 00:00:00 1970 PST
|
|
810 | 0 | 00810 | Sun Jan 11 00:00:00 1970 PST
|
|
811 | 1 | 00811 | Mon Jan 12 00:00:00 1970 PST
|
|
813 | 303 | 00813_update3 | Wed Jan 14 00:00:00 1970 PST
|
|
814 | 4 | 00814 | Thu Jan 15 00:00:00 1970 PST
|
|
816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 PST
|
|
817 | 407 | 00817_update7 | Sun Jan 18 00:00:00 1970 PST
|
|
818 | 8 | 00818 | Mon Jan 19 00:00:00 1970 PST
|
|
819 | 509 | 00819_update9 | Tue Jan 20 00:00:00 1970 PST
|
|
820 | 0 | 00820 | Wed Jan 21 00:00:00 1970 PST
|
|
821 | 1 | 00821 | Thu Jan 22 00:00:00 1970 PST
|
|
823 | 303 | 00823_update3 | Sat Jan 24 00:00:00 1970 PST
|
|
824 | 4 | 00824 | Sun Jan 25 00:00:00 1970 PST
|
|
826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 PST
|
|
827 | 407 | 00827_update7 | Wed Jan 28 00:00:00 1970 PST
|
|
828 | 8 | 00828 | Thu Jan 29 00:00:00 1970 PST
|
|
829 | 509 | 00829_update9 | Fri Jan 30 00:00:00 1970 PST
|
|
830 | 0 | 00830 | Sat Jan 31 00:00:00 1970 PST
|
|
831 | 1 | 00831 | Sun Feb 01 00:00:00 1970 PST
|
|
833 | 303 | 00833_update3 | Tue Feb 03 00:00:00 1970 PST
|
|
834 | 4 | 00834 | Wed Feb 04 00:00:00 1970 PST
|
|
836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 PST
|
|
837 | 407 | 00837_update7 | Sat Feb 07 00:00:00 1970 PST
|
|
838 | 8 | 00838 | Sun Feb 08 00:00:00 1970 PST
|
|
839 | 509 | 00839_update9 | Mon Feb 09 00:00:00 1970 PST
|
|
840 | 0 | 00840 | Tue Feb 10 00:00:00 1970 PST
|
|
841 | 1 | 00841 | Wed Feb 11 00:00:00 1970 PST
|
|
843 | 303 | 00843_update3 | Fri Feb 13 00:00:00 1970 PST
|
|
844 | 4 | 00844 | Sat Feb 14 00:00:00 1970 PST
|
|
846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 PST
|
|
847 | 407 | 00847_update7 | Tue Feb 17 00:00:00 1970 PST
|
|
848 | 8 | 00848 | Wed Feb 18 00:00:00 1970 PST
|
|
849 | 509 | 00849_update9 | Thu Feb 19 00:00:00 1970 PST
|
|
850 | 0 | 00850 | Fri Feb 20 00:00:00 1970 PST
|
|
851 | 1 | 00851 | Sat Feb 21 00:00:00 1970 PST
|
|
853 | 303 | 00853_update3 | Mon Feb 23 00:00:00 1970 PST
|
|
854 | 4 | 00854 | Tue Feb 24 00:00:00 1970 PST
|
|
856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 PST
|
|
857 | 407 | 00857_update7 | Fri Feb 27 00:00:00 1970 PST
|
|
858 | 8 | 00858 | Sat Feb 28 00:00:00 1970 PST
|
|
859 | 509 | 00859_update9 | Sun Mar 01 00:00:00 1970 PST
|
|
860 | 0 | 00860 | Mon Mar 02 00:00:00 1970 PST
|
|
861 | 1 | 00861 | Tue Mar 03 00:00:00 1970 PST
|
|
863 | 303 | 00863_update3 | Thu Mar 05 00:00:00 1970 PST
|
|
864 | 4 | 00864 | Fri Mar 06 00:00:00 1970 PST
|
|
866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 PST
|
|
867 | 407 | 00867_update7 | Mon Mar 09 00:00:00 1970 PST
|
|
868 | 8 | 00868 | Tue Mar 10 00:00:00 1970 PST
|
|
869 | 509 | 00869_update9 | Wed Mar 11 00:00:00 1970 PST
|
|
870 | 0 | 00870 | Thu Mar 12 00:00:00 1970 PST
|
|
871 | 1 | 00871 | Fri Mar 13 00:00:00 1970 PST
|
|
873 | 303 | 00873_update3 | Sun Mar 15 00:00:00 1970 PST
|
|
874 | 4 | 00874 | Mon Mar 16 00:00:00 1970 PST
|
|
876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 PST
|
|
877 | 407 | 00877_update7 | Thu Mar 19 00:00:00 1970 PST
|
|
878 | 8 | 00878 | Fri Mar 20 00:00:00 1970 PST
|
|
879 | 509 | 00879_update9 | Sat Mar 21 00:00:00 1970 PST
|
|
880 | 0 | 00880 | Sun Mar 22 00:00:00 1970 PST
|
|
881 | 1 | 00881 | Mon Mar 23 00:00:00 1970 PST
|
|
883 | 303 | 00883_update3 | Wed Mar 25 00:00:00 1970 PST
|
|
884 | 4 | 00884 | Thu Mar 26 00:00:00 1970 PST
|
|
886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 PST
|
|
887 | 407 | 00887_update7 | Sun Mar 29 00:00:00 1970 PST
|
|
888 | 8 | 00888 | Mon Mar 30 00:00:00 1970 PST
|
|
889 | 509 | 00889_update9 | Tue Mar 31 00:00:00 1970 PST
|
|
890 | 0 | 00890 | Wed Apr 01 00:00:00 1970 PST
|
|
891 | 1 | 00891 | Thu Apr 02 00:00:00 1970 PST
|
|
893 | 303 | 00893_update3 | Sat Apr 04 00:00:00 1970 PST
|
|
894 | 4 | 00894 | Sun Apr 05 00:00:00 1970 PST
|
|
896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 PST
|
|
897 | 407 | 00897_update7 | Wed Apr 08 00:00:00 1970 PST
|
|
898 | 8 | 00898 | Thu Apr 09 00:00:00 1970 PST
|
|
899 | 509 | 00899_update9 | Fri Apr 10 00:00:00 1970 PST
|
|
900 | 0 | 00900 | Thu Jan 01 00:00:00 1970 PST
|
|
901 | 1 | 00901 | Fri Jan 02 00:00:00 1970 PST
|
|
903 | 303 | 00903_update3 | Sun Jan 04 00:00:00 1970 PST
|
|
904 | 4 | 00904 | Mon Jan 05 00:00:00 1970 PST
|
|
906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 PST
|
|
907 | 407 | 00907_update7 | Thu Jan 08 00:00:00 1970 PST
|
|
908 | 8 | 00908 | Fri Jan 09 00:00:00 1970 PST
|
|
909 | 509 | 00909_update9 | Sat Jan 10 00:00:00 1970 PST
|
|
910 | 0 | 00910 | Sun Jan 11 00:00:00 1970 PST
|
|
911 | 1 | 00911 | Mon Jan 12 00:00:00 1970 PST
|
|
913 | 303 | 00913_update3 | Wed Jan 14 00:00:00 1970 PST
|
|
914 | 4 | 00914 | Thu Jan 15 00:00:00 1970 PST
|
|
916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 PST
|
|
917 | 407 | 00917_update7 | Sun Jan 18 00:00:00 1970 PST
|
|
918 | 8 | 00918 | Mon Jan 19 00:00:00 1970 PST
|
|
919 | 509 | 00919_update9 | Tue Jan 20 00:00:00 1970 PST
|
|
920 | 0 | 00920 | Wed Jan 21 00:00:00 1970 PST
|
|
921 | 1 | 00921 | Thu Jan 22 00:00:00 1970 PST
|
|
923 | 303 | 00923_update3 | Sat Jan 24 00:00:00 1970 PST
|
|
924 | 4 | 00924 | Sun Jan 25 00:00:00 1970 PST
|
|
926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 PST
|
|
927 | 407 | 00927_update7 | Wed Jan 28 00:00:00 1970 PST
|
|
928 | 8 | 00928 | Thu Jan 29 00:00:00 1970 PST
|
|
929 | 509 | 00929_update9 | Fri Jan 30 00:00:00 1970 PST
|
|
930 | 0 | 00930 | Sat Jan 31 00:00:00 1970 PST
|
|
931 | 1 | 00931 | Sun Feb 01 00:00:00 1970 PST
|
|
933 | 303 | 00933_update3 | Tue Feb 03 00:00:00 1970 PST
|
|
934 | 4 | 00934 | Wed Feb 04 00:00:00 1970 PST
|
|
936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 PST
|
|
937 | 407 | 00937_update7 | Sat Feb 07 00:00:00 1970 PST
|
|
938 | 8 | 00938 | Sun Feb 08 00:00:00 1970 PST
|
|
939 | 509 | 00939_update9 | Mon Feb 09 00:00:00 1970 PST
|
|
940 | 0 | 00940 | Tue Feb 10 00:00:00 1970 PST
|
|
941 | 1 | 00941 | Wed Feb 11 00:00:00 1970 PST
|
|
943 | 303 | 00943_update3 | Fri Feb 13 00:00:00 1970 PST
|
|
944 | 4 | 00944 | Sat Feb 14 00:00:00 1970 PST
|
|
946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 PST
|
|
947 | 407 | 00947_update7 | Tue Feb 17 00:00:00 1970 PST
|
|
948 | 8 | 00948 | Wed Feb 18 00:00:00 1970 PST
|
|
949 | 509 | 00949_update9 | Thu Feb 19 00:00:00 1970 PST
|
|
950 | 0 | 00950 | Fri Feb 20 00:00:00 1970 PST
|
|
951 | 1 | 00951 | Sat Feb 21 00:00:00 1970 PST
|
|
953 | 303 | 00953_update3 | Mon Feb 23 00:00:00 1970 PST
|
|
954 | 4 | 00954 | Tue Feb 24 00:00:00 1970 PST
|
|
956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 PST
|
|
957 | 407 | 00957_update7 | Fri Feb 27 00:00:00 1970 PST
|
|
958 | 8 | 00958 | Sat Feb 28 00:00:00 1970 PST
|
|
959 | 509 | 00959_update9 | Sun Mar 01 00:00:00 1970 PST
|
|
960 | 0 | 00960 | Mon Mar 02 00:00:00 1970 PST
|
|
961 | 1 | 00961 | Tue Mar 03 00:00:00 1970 PST
|
|
963 | 303 | 00963_update3 | Thu Mar 05 00:00:00 1970 PST
|
|
964 | 4 | 00964 | Fri Mar 06 00:00:00 1970 PST
|
|
966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 PST
|
|
967 | 407 | 00967_update7 | Mon Mar 09 00:00:00 1970 PST
|
|
968 | 8 | 00968 | Tue Mar 10 00:00:00 1970 PST
|
|
969 | 509 | 00969_update9 | Wed Mar 11 00:00:00 1970 PST
|
|
970 | 0 | 00970 | Thu Mar 12 00:00:00 1970 PST
|
|
971 | 1 | 00971 | Fri Mar 13 00:00:00 1970 PST
|
|
973 | 303 | 00973_update3 | Sun Mar 15 00:00:00 1970 PST
|
|
974 | 4 | 00974 | Mon Mar 16 00:00:00 1970 PST
|
|
976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 PST
|
|
977 | 407 | 00977_update7 | Thu Mar 19 00:00:00 1970 PST
|
|
978 | 8 | 00978 | Fri Mar 20 00:00:00 1970 PST
|
|
979 | 509 | 00979_update9 | Sat Mar 21 00:00:00 1970 PST
|
|
980 | 0 | 00980 | Sun Mar 22 00:00:00 1970 PST
|
|
981 | 1 | 00981 | Mon Mar 23 00:00:00 1970 PST
|
|
983 | 303 | 00983_update3 | Wed Mar 25 00:00:00 1970 PST
|
|
984 | 4 | 00984 | Thu Mar 26 00:00:00 1970 PST
|
|
986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 PST
|
|
987 | 407 | 00987_update7 | Sun Mar 29 00:00:00 1970 PST
|
|
988 | 8 | 00988 | Mon Mar 30 00:00:00 1970 PST
|
|
989 | 509 | 00989_update9 | Tue Mar 31 00:00:00 1970 PST
|
|
990 | 0 | 00990 | Wed Apr 01 00:00:00 1970 PST
|
|
991 | 1 | 00991 | Thu Apr 02 00:00:00 1970 PST
|
|
993 | 303 | 00993_update3 | Sat Apr 04 00:00:00 1970 PST
|
|
994 | 4 | 00994 | Sun Apr 05 00:00:00 1970 PST
|
|
996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 PST
|
|
997 | 407 | 00997_update7 | Wed Apr 08 00:00:00 1970 PST
|
|
998 | 8 | 00998 | Thu Apr 09 00:00:00 1970 PST
|
|
999 | 509 | 00999_update9 | Fri Apr 10 00:00:00 1970 PST
|
|
1000 | 0 | 01000 | Thu Jan 01 00:00:00 1970 PST
|
|
1001 | 101 | 0000100001 |
|
|
1003 | 403 | 0000300003_update3 |
|
|
1004 | 104 | 0000400004 |
|
|
1006 | 106 | 0000600006 |
|
|
1007 | 507 | 0000700007_update7 |
|
|
1008 | 108 | 0000800008 |
|
|
1009 | 609 | 0000900009_update9 |
|
|
1010 | 100 | 0001000010 |
|
|
1011 | 101 | 0001100011 |
|
|
1013 | 403 | 0001300013_update3 |
|
|
1014 | 104 | 0001400014 |
|
|
1016 | 106 | 0001600016 |
|
|
1017 | 507 | 0001700017_update7 |
|
|
1018 | 108 | 0001800018 |
|
|
1019 | 609 | 0001900019_update9 |
|
|
1020 | 100 | 0002000020 |
|
|
1101 | 201 | aaa |
|
|
1103 | 503 | ccc_update3 |
|
|
1104 | 204 | ddd |
|
|
(819 rows)
|
|
|
|
EXPLAIN (verbose, costs off)
|
|
INSERT INTO ft2 (c1,c2,c3) VALUES (9999,999,'foo') RETURNING tableoid::regclass;
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
Insert on public.ft2
|
|
Output: (tableoid)::regclass
|
|
Remote SQL: INSERT INTO "S 1"."T 1"("C 1", c2, c3, c4, c5, c6, c7, c8) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
|
-> Result
|
|
Output: 9999, 999, NULL::integer, 'foo'::text, NULL::timestamp with time zone, NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::user_enum
|
|
(5 rows)
|
|
|
|
INSERT INTO ft2 (c1,c2,c3) VALUES (9999,999,'foo') RETURNING tableoid::regclass;
|
|
tableoid
|
|
----------
|
|
ft2
|
|
(1 row)
|
|
|
|
EXPLAIN (verbose, costs off)
|
|
UPDATE ft2 SET c3 = 'bar' WHERE c1 = 9999 RETURNING tableoid::regclass; -- can be pushed down
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------------
|
|
Update on public.ft2
|
|
Output: (tableoid)::regclass
|
|
-> Foreign Update on public.ft2
|
|
Remote SQL: UPDATE "S 1"."T 1" SET c3 = 'bar'::text WHERE (("C 1" = 9999))
|
|
(4 rows)
|
|
|
|
UPDATE ft2 SET c3 = 'bar' WHERE c1 = 9999 RETURNING tableoid::regclass;
|
|
tableoid
|
|
----------
|
|
ft2
|
|
(1 row)
|
|
|
|
EXPLAIN (verbose, costs off)
|
|
DELETE FROM ft2 WHERE c1 = 9999 RETURNING tableoid::regclass; -- can be pushed down
|
|
QUERY PLAN
|
|
--------------------------------------------------------------------
|
|
Delete on public.ft2
|
|
Output: (tableoid)::regclass
|
|
-> Foreign Delete on public.ft2
|
|
Remote SQL: DELETE FROM "S 1"."T 1" WHERE (("C 1" = 9999))
|
|
(4 rows)
|
|
|
|
DELETE FROM ft2 WHERE c1 = 9999 RETURNING tableoid::regclass;
|
|
tableoid
|
|
----------
|
|
ft2
|
|
(1 row)
|
|
|
|
-- Test that trigger on remote table works as expected
|
|
CREATE OR REPLACE FUNCTION "S 1".F_BRTRIG() RETURNS trigger AS $$
|
|
BEGIN
|
|
NEW.c3 = NEW.c3 || '_trig_update';
|
|
RETURN NEW;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
CREATE TRIGGER t1_br_insert BEFORE INSERT OR UPDATE
|
|
ON "S 1"."T 1" FOR EACH ROW EXECUTE PROCEDURE "S 1".F_BRTRIG();
|
|
INSERT INTO ft2 (c1,c2,c3) VALUES (1208, 818, 'fff') RETURNING *;
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
------+-----+-----------------+----+----+----+------------+----
|
|
1208 | 818 | fff_trig_update | | | | ft2 |
|
|
(1 row)
|
|
|
|
INSERT INTO ft2 (c1,c2,c3,c6) VALUES (1218, 818, 'ggg', '(--;') RETURNING *;
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
------+-----+-----------------+----+----+------+------------+----
|
|
1218 | 818 | ggg_trig_update | | | (--; | ft2 |
|
|
(1 row)
|
|
|
|
UPDATE ft2 SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1200 RETURNING *;
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
------+-----+------------------------+------------------------------+--------------------------+----+------------+-----
|
|
8 | 608 | 00008_trig_update | Fri Jan 09 00:00:00 1970 PST | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo
|
|
18 | 608 | 00018_trig_update | Mon Jan 19 00:00:00 1970 PST | Mon Jan 19 00:00:00 1970 | 8 | 8 | foo
|
|
28 | 608 | 00028_trig_update | Thu Jan 29 00:00:00 1970 PST | Thu Jan 29 00:00:00 1970 | 8 | 8 | foo
|
|
38 | 608 | 00038_trig_update | Sun Feb 08 00:00:00 1970 PST | Sun Feb 08 00:00:00 1970 | 8 | 8 | foo
|
|
48 | 608 | 00048_trig_update | Wed Feb 18 00:00:00 1970 PST | Wed Feb 18 00:00:00 1970 | 8 | 8 | foo
|
|
58 | 608 | 00058_trig_update | Sat Feb 28 00:00:00 1970 PST | Sat Feb 28 00:00:00 1970 | 8 | 8 | foo
|
|
68 | 608 | 00068_trig_update | Tue Mar 10 00:00:00 1970 PST | Tue Mar 10 00:00:00 1970 | 8 | 8 | foo
|
|
78 | 608 | 00078_trig_update | Fri Mar 20 00:00:00 1970 PST | Fri Mar 20 00:00:00 1970 | 8 | 8 | foo
|
|
88 | 608 | 00088_trig_update | Mon Mar 30 00:00:00 1970 PST | Mon Mar 30 00:00:00 1970 | 8 | 8 | foo
|
|
98 | 608 | 00098_trig_update | Thu Apr 09 00:00:00 1970 PST | Thu Apr 09 00:00:00 1970 | 8 | 8 | foo
|
|
108 | 608 | 00108_trig_update | Fri Jan 09 00:00:00 1970 PST | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo
|
|
118 | 608 | 00118_trig_update | Mon Jan 19 00:00:00 1970 PST | Mon Jan 19 00:00:00 1970 | 8 | 8 | foo
|
|
128 | 608 | 00128_trig_update | Thu Jan 29 00:00:00 1970 PST | Thu Jan 29 00:00:00 1970 | 8 | 8 | foo
|
|
138 | 608 | 00138_trig_update | Sun Feb 08 00:00:00 1970 PST | Sun Feb 08 00:00:00 1970 | 8 | 8 | foo
|
|
148 | 608 | 00148_trig_update | Wed Feb 18 00:00:00 1970 PST | Wed Feb 18 00:00:00 1970 | 8 | 8 | foo
|
|
158 | 608 | 00158_trig_update | Sat Feb 28 00:00:00 1970 PST | Sat Feb 28 00:00:00 1970 | 8 | 8 | foo
|
|
168 | 608 | 00168_trig_update | Tue Mar 10 00:00:00 1970 PST | Tue Mar 10 00:00:00 1970 | 8 | 8 | foo
|
|
178 | 608 | 00178_trig_update | Fri Mar 20 00:00:00 1970 PST | Fri Mar 20 00:00:00 1970 | 8 | 8 | foo
|
|
188 | 608 | 00188_trig_update | Mon Mar 30 00:00:00 1970 PST | Mon Mar 30 00:00:00 1970 | 8 | 8 | foo
|
|
198 | 608 | 00198_trig_update | Thu Apr 09 00:00:00 1970 PST | Thu Apr 09 00:00:00 1970 | 8 | 8 | foo
|
|
208 | 608 | 00208_trig_update | Fri Jan 09 00:00:00 1970 PST | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo
|
|
218 | 608 | 00218_trig_update | Mon Jan 19 00:00:00 1970 PST | Mon Jan 19 00:00:00 1970 | 8 | 8 | foo
|
|
228 | 608 | 00228_trig_update | Thu Jan 29 00:00:00 1970 PST | Thu Jan 29 00:00:00 1970 | 8 | 8 | foo
|
|
238 | 608 | 00238_trig_update | Sun Feb 08 00:00:00 1970 PST | Sun Feb 08 00:00:00 1970 | 8 | 8 | foo
|
|
248 | 608 | 00248_trig_update | Wed Feb 18 00:00:00 1970 PST | Wed Feb 18 00:00:00 1970 | 8 | 8 | foo
|
|
258 | 608 | 00258_trig_update | Sat Feb 28 00:00:00 1970 PST | Sat Feb 28 00:00:00 1970 | 8 | 8 | foo
|
|
268 | 608 | 00268_trig_update | Tue Mar 10 00:00:00 1970 PST | Tue Mar 10 00:00:00 1970 | 8 | 8 | foo
|
|
278 | 608 | 00278_trig_update | Fri Mar 20 00:00:00 1970 PST | Fri Mar 20 00:00:00 1970 | 8 | 8 | foo
|
|
288 | 608 | 00288_trig_update | Mon Mar 30 00:00:00 1970 PST | Mon Mar 30 00:00:00 1970 | 8 | 8 | foo
|
|
298 | 608 | 00298_trig_update | Thu Apr 09 00:00:00 1970 PST | Thu Apr 09 00:00:00 1970 | 8 | 8 | foo
|
|
308 | 608 | 00308_trig_update | Fri Jan 09 00:00:00 1970 PST | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo
|
|
318 | 608 | 00318_trig_update | Mon Jan 19 00:00:00 1970 PST | Mon Jan 19 00:00:00 1970 | 8 | 8 | foo
|
|
328 | 608 | 00328_trig_update | Thu Jan 29 00:00:00 1970 PST | Thu Jan 29 00:00:00 1970 | 8 | 8 | foo
|
|
338 | 608 | 00338_trig_update | Sun Feb 08 00:00:00 1970 PST | Sun Feb 08 00:00:00 1970 | 8 | 8 | foo
|
|
348 | 608 | 00348_trig_update | Wed Feb 18 00:00:00 1970 PST | Wed Feb 18 00:00:00 1970 | 8 | 8 | foo
|
|
358 | 608 | 00358_trig_update | Sat Feb 28 00:00:00 1970 PST | Sat Feb 28 00:00:00 1970 | 8 | 8 | foo
|
|
368 | 608 | 00368_trig_update | Tue Mar 10 00:00:00 1970 PST | Tue Mar 10 00:00:00 1970 | 8 | 8 | foo
|
|
378 | 608 | 00378_trig_update | Fri Mar 20 00:00:00 1970 PST | Fri Mar 20 00:00:00 1970 | 8 | 8 | foo
|
|
388 | 608 | 00388_trig_update | Mon Mar 30 00:00:00 1970 PST | Mon Mar 30 00:00:00 1970 | 8 | 8 | foo
|
|
398 | 608 | 00398_trig_update | Thu Apr 09 00:00:00 1970 PST | Thu Apr 09 00:00:00 1970 | 8 | 8 | foo
|
|
408 | 608 | 00408_trig_update | Fri Jan 09 00:00:00 1970 PST | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo
|
|
418 | 608 | 00418_trig_update | Mon Jan 19 00:00:00 1970 PST | Mon Jan 19 00:00:00 1970 | 8 | 8 | foo
|
|
428 | 608 | 00428_trig_update | Thu Jan 29 00:00:00 1970 PST | Thu Jan 29 00:00:00 1970 | 8 | 8 | foo
|
|
438 | 608 | 00438_trig_update | Sun Feb 08 00:00:00 1970 PST | Sun Feb 08 00:00:00 1970 | 8 | 8 | foo
|
|
448 | 608 | 00448_trig_update | Wed Feb 18 00:00:00 1970 PST | Wed Feb 18 00:00:00 1970 | 8 | 8 | foo
|
|
458 | 608 | 00458_trig_update | Sat Feb 28 00:00:00 1970 PST | Sat Feb 28 00:00:00 1970 | 8 | 8 | foo
|
|
468 | 608 | 00468_trig_update | Tue Mar 10 00:00:00 1970 PST | Tue Mar 10 00:00:00 1970 | 8 | 8 | foo
|
|
478 | 608 | 00478_trig_update | Fri Mar 20 00:00:00 1970 PST | Fri Mar 20 00:00:00 1970 | 8 | 8 | foo
|
|
488 | 608 | 00488_trig_update | Mon Mar 30 00:00:00 1970 PST | Mon Mar 30 00:00:00 1970 | 8 | 8 | foo
|
|
498 | 608 | 00498_trig_update | Thu Apr 09 00:00:00 1970 PST | Thu Apr 09 00:00:00 1970 | 8 | 8 | foo
|
|
508 | 608 | 00508_trig_update | Fri Jan 09 00:00:00 1970 PST | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo
|
|
518 | 608 | 00518_trig_update | Mon Jan 19 00:00:00 1970 PST | Mon Jan 19 00:00:00 1970 | 8 | 8 | foo
|
|
528 | 608 | 00528_trig_update | Thu Jan 29 00:00:00 1970 PST | Thu Jan 29 00:00:00 1970 | 8 | 8 | foo
|
|
538 | 608 | 00538_trig_update | Sun Feb 08 00:00:00 1970 PST | Sun Feb 08 00:00:00 1970 | 8 | 8 | foo
|
|
548 | 608 | 00548_trig_update | Wed Feb 18 00:00:00 1970 PST | Wed Feb 18 00:00:00 1970 | 8 | 8 | foo
|
|
558 | 608 | 00558_trig_update | Sat Feb 28 00:00:00 1970 PST | Sat Feb 28 00:00:00 1970 | 8 | 8 | foo
|
|
568 | 608 | 00568_trig_update | Tue Mar 10 00:00:00 1970 PST | Tue Mar 10 00:00:00 1970 | 8 | 8 | foo
|
|
578 | 608 | 00578_trig_update | Fri Mar 20 00:00:00 1970 PST | Fri Mar 20 00:00:00 1970 | 8 | 8 | foo
|
|
588 | 608 | 00588_trig_update | Mon Mar 30 00:00:00 1970 PST | Mon Mar 30 00:00:00 1970 | 8 | 8 | foo
|
|
598 | 608 | 00598_trig_update | Thu Apr 09 00:00:00 1970 PST | Thu Apr 09 00:00:00 1970 | 8 | 8 | foo
|
|
608 | 608 | 00608_trig_update | Fri Jan 09 00:00:00 1970 PST | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo
|
|
618 | 608 | 00618_trig_update | Mon Jan 19 00:00:00 1970 PST | Mon Jan 19 00:00:00 1970 | 8 | 8 | foo
|
|
628 | 608 | 00628_trig_update | Thu Jan 29 00:00:00 1970 PST | Thu Jan 29 00:00:00 1970 | 8 | 8 | foo
|
|
638 | 608 | 00638_trig_update | Sun Feb 08 00:00:00 1970 PST | Sun Feb 08 00:00:00 1970 | 8 | 8 | foo
|
|
648 | 608 | 00648_trig_update | Wed Feb 18 00:00:00 1970 PST | Wed Feb 18 00:00:00 1970 | 8 | 8 | foo
|
|
658 | 608 | 00658_trig_update | Sat Feb 28 00:00:00 1970 PST | Sat Feb 28 00:00:00 1970 | 8 | 8 | foo
|
|
668 | 608 | 00668_trig_update | Tue Mar 10 00:00:00 1970 PST | Tue Mar 10 00:00:00 1970 | 8 | 8 | foo
|
|
678 | 608 | 00678_trig_update | Fri Mar 20 00:00:00 1970 PST | Fri Mar 20 00:00:00 1970 | 8 | 8 | foo
|
|
688 | 608 | 00688_trig_update | Mon Mar 30 00:00:00 1970 PST | Mon Mar 30 00:00:00 1970 | 8 | 8 | foo
|
|
698 | 608 | 00698_trig_update | Thu Apr 09 00:00:00 1970 PST | Thu Apr 09 00:00:00 1970 | 8 | 8 | foo
|
|
708 | 608 | 00708_trig_update | Fri Jan 09 00:00:00 1970 PST | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo
|
|
718 | 608 | 00718_trig_update | Mon Jan 19 00:00:00 1970 PST | Mon Jan 19 00:00:00 1970 | 8 | 8 | foo
|
|
728 | 608 | 00728_trig_update | Thu Jan 29 00:00:00 1970 PST | Thu Jan 29 00:00:00 1970 | 8 | 8 | foo
|
|
738 | 608 | 00738_trig_update | Sun Feb 08 00:00:00 1970 PST | Sun Feb 08 00:00:00 1970 | 8 | 8 | foo
|
|
748 | 608 | 00748_trig_update | Wed Feb 18 00:00:00 1970 PST | Wed Feb 18 00:00:00 1970 | 8 | 8 | foo
|
|
758 | 608 | 00758_trig_update | Sat Feb 28 00:00:00 1970 PST | Sat Feb 28 00:00:00 1970 | 8 | 8 | foo
|
|
768 | 608 | 00768_trig_update | Tue Mar 10 00:00:00 1970 PST | Tue Mar 10 00:00:00 1970 | 8 | 8 | foo
|
|
778 | 608 | 00778_trig_update | Fri Mar 20 00:00:00 1970 PST | Fri Mar 20 00:00:00 1970 | 8 | 8 | foo
|
|
788 | 608 | 00788_trig_update | Mon Mar 30 00:00:00 1970 PST | Mon Mar 30 00:00:00 1970 | 8 | 8 | foo
|
|
798 | 608 | 00798_trig_update | Thu Apr 09 00:00:00 1970 PST | Thu Apr 09 00:00:00 1970 | 8 | 8 | foo
|
|
808 | 608 | 00808_trig_update | Fri Jan 09 00:00:00 1970 PST | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo
|
|
818 | 608 | 00818_trig_update | Mon Jan 19 00:00:00 1970 PST | Mon Jan 19 00:00:00 1970 | 8 | 8 | foo
|
|
828 | 608 | 00828_trig_update | Thu Jan 29 00:00:00 1970 PST | Thu Jan 29 00:00:00 1970 | 8 | 8 | foo
|
|
838 | 608 | 00838_trig_update | Sun Feb 08 00:00:00 1970 PST | Sun Feb 08 00:00:00 1970 | 8 | 8 | foo
|
|
848 | 608 | 00848_trig_update | Wed Feb 18 00:00:00 1970 PST | Wed Feb 18 00:00:00 1970 | 8 | 8 | foo
|
|
858 | 608 | 00858_trig_update | Sat Feb 28 00:00:00 1970 PST | Sat Feb 28 00:00:00 1970 | 8 | 8 | foo
|
|
868 | 608 | 00868_trig_update | Tue Mar 10 00:00:00 1970 PST | Tue Mar 10 00:00:00 1970 | 8 | 8 | foo
|
|
878 | 608 | 00878_trig_update | Fri Mar 20 00:00:00 1970 PST | Fri Mar 20 00:00:00 1970 | 8 | 8 | foo
|
|
888 | 608 | 00888_trig_update | Mon Mar 30 00:00:00 1970 PST | Mon Mar 30 00:00:00 1970 | 8 | 8 | foo
|
|
898 | 608 | 00898_trig_update | Thu Apr 09 00:00:00 1970 PST | Thu Apr 09 00:00:00 1970 | 8 | 8 | foo
|
|
908 | 608 | 00908_trig_update | Fri Jan 09 00:00:00 1970 PST | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo
|
|
918 | 608 | 00918_trig_update | Mon Jan 19 00:00:00 1970 PST | Mon Jan 19 00:00:00 1970 | 8 | 8 | foo
|
|
928 | 608 | 00928_trig_update | Thu Jan 29 00:00:00 1970 PST | Thu Jan 29 00:00:00 1970 | 8 | 8 | foo
|
|
938 | 608 | 00938_trig_update | Sun Feb 08 00:00:00 1970 PST | Sun Feb 08 00:00:00 1970 | 8 | 8 | foo
|
|
948 | 608 | 00948_trig_update | Wed Feb 18 00:00:00 1970 PST | Wed Feb 18 00:00:00 1970 | 8 | 8 | foo
|
|
958 | 608 | 00958_trig_update | Sat Feb 28 00:00:00 1970 PST | Sat Feb 28 00:00:00 1970 | 8 | 8 | foo
|
|
968 | 608 | 00968_trig_update | Tue Mar 10 00:00:00 1970 PST | Tue Mar 10 00:00:00 1970 | 8 | 8 | foo
|
|
978 | 608 | 00978_trig_update | Fri Mar 20 00:00:00 1970 PST | Fri Mar 20 00:00:00 1970 | 8 | 8 | foo
|
|
988 | 608 | 00988_trig_update | Mon Mar 30 00:00:00 1970 PST | Mon Mar 30 00:00:00 1970 | 8 | 8 | foo
|
|
998 | 608 | 00998_trig_update | Thu Apr 09 00:00:00 1970 PST | Thu Apr 09 00:00:00 1970 | 8 | 8 | foo
|
|
1008 | 708 | 0000800008_trig_update | | | | ft2 |
|
|
1018 | 708 | 0001800018_trig_update | | | | ft2 |
|
|
(102 rows)
|
|
|
|
-- Test errors thrown on remote side during update
|
|
ALTER TABLE "S 1"."T 1" ADD CONSTRAINT c2positive CHECK (c2 >= 0);
|
|
INSERT INTO ft1(c1, c2) VALUES(11, 12); -- duplicate key
|
|
ERROR: duplicate key value violates unique constraint "t1_pkey"
|
|
DETAIL: Key ("C 1")=(11) already exists.
|
|
CONTEXT: Remote SQL command: INSERT INTO "S 1"."T 1"("C 1", c2, c3, c4, c5, c6, c7, c8) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
|
INSERT INTO ft1(c1, c2) VALUES(11, 12) ON CONFLICT DO NOTHING; -- works
|
|
INSERT INTO ft1(c1, c2) VALUES(11, 12) ON CONFLICT (c1, c2) DO NOTHING; -- unsupported
|
|
ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification
|
|
INSERT INTO ft1(c1, c2) VALUES(11, 12) ON CONFLICT (c1, c2) DO UPDATE SET c3 = 'ffg'; -- unsupported
|
|
ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification
|
|
INSERT INTO ft1(c1, c2) VALUES(1111, -2); -- c2positive
|
|
ERROR: new row for relation "T 1" violates check constraint "c2positive"
|
|
DETAIL: Failing row contains (1111, -2, null, null, null, null, ft1 , null).
|
|
CONTEXT: Remote SQL command: INSERT INTO "S 1"."T 1"("C 1", c2, c3, c4, c5, c6, c7, c8) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
|
UPDATE ft1 SET c2 = -c2 WHERE c1 = 1; -- c2positive
|
|
ERROR: new row for relation "T 1" violates check constraint "c2positive"
|
|
DETAIL: Failing row contains (1, -1, 00001_trig_update, 1970-01-02 08:00:00+00, 1970-01-02 00:00:00, 1, 1 , foo).
|
|
CONTEXT: Remote SQL command: UPDATE "S 1"."T 1" SET c2 = (- c2) WHERE (("C 1" = 1))
|
|
-- Test savepoint/rollback behavior
|
|
select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1;
|
|
c2 | count
|
|
-----+-------
|
|
0 | 100
|
|
1 | 100
|
|
4 | 100
|
|
6 | 100
|
|
100 | 2
|
|
101 | 2
|
|
104 | 2
|
|
106 | 2
|
|
201 | 1
|
|
204 | 1
|
|
303 | 100
|
|
403 | 2
|
|
407 | 100
|
|
(13 rows)
|
|
|
|
select c2, count(*) from "S 1"."T 1" where c2 < 500 group by 1 order by 1;
|
|
c2 | count
|
|
-----+-------
|
|
0 | 100
|
|
1 | 100
|
|
4 | 100
|
|
6 | 100
|
|
100 | 2
|
|
101 | 2
|
|
104 | 2
|
|
106 | 2
|
|
201 | 1
|
|
204 | 1
|
|
303 | 100
|
|
403 | 2
|
|
407 | 100
|
|
(13 rows)
|
|
|
|
begin;
|
|
update ft2 set c2 = 42 where c2 = 0;
|
|
select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1;
|
|
c2 | count
|
|
-----+-------
|
|
1 | 100
|
|
4 | 100
|
|
6 | 100
|
|
42 | 100
|
|
100 | 2
|
|
101 | 2
|
|
104 | 2
|
|
106 | 2
|
|
201 | 1
|
|
204 | 1
|
|
303 | 100
|
|
403 | 2
|
|
407 | 100
|
|
(13 rows)
|
|
|
|
savepoint s1;
|
|
update ft2 set c2 = 44 where c2 = 4;
|
|
select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1;
|
|
c2 | count
|
|
-----+-------
|
|
1 | 100
|
|
6 | 100
|
|
42 | 100
|
|
44 | 100
|
|
100 | 2
|
|
101 | 2
|
|
104 | 2
|
|
106 | 2
|
|
201 | 1
|
|
204 | 1
|
|
303 | 100
|
|
403 | 2
|
|
407 | 100
|
|
(13 rows)
|
|
|
|
release savepoint s1;
|
|
select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1;
|
|
c2 | count
|
|
-----+-------
|
|
1 | 100
|
|
6 | 100
|
|
42 | 100
|
|
44 | 100
|
|
100 | 2
|
|
101 | 2
|
|
104 | 2
|
|
106 | 2
|
|
201 | 1
|
|
204 | 1
|
|
303 | 100
|
|
403 | 2
|
|
407 | 100
|
|
(13 rows)
|
|
|
|
savepoint s2;
|
|
update ft2 set c2 = 46 where c2 = 6;
|
|
select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1;
|
|
c2 | count
|
|
-----+-------
|
|
1 | 100
|
|
42 | 100
|
|
44 | 100
|
|
46 | 100
|
|
100 | 2
|
|
101 | 2
|
|
104 | 2
|
|
106 | 2
|
|
201 | 1
|
|
204 | 1
|
|
303 | 100
|
|
403 | 2
|
|
407 | 100
|
|
(13 rows)
|
|
|
|
rollback to savepoint s2;
|
|
select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1;
|
|
c2 | count
|
|
-----+-------
|
|
1 | 100
|
|
6 | 100
|
|
42 | 100
|
|
44 | 100
|
|
100 | 2
|
|
101 | 2
|
|
104 | 2
|
|
106 | 2
|
|
201 | 1
|
|
204 | 1
|
|
303 | 100
|
|
403 | 2
|
|
407 | 100
|
|
(13 rows)
|
|
|
|
release savepoint s2;
|
|
select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1;
|
|
c2 | count
|
|
-----+-------
|
|
1 | 100
|
|
6 | 100
|
|
42 | 100
|
|
44 | 100
|
|
100 | 2
|
|
101 | 2
|
|
104 | 2
|
|
106 | 2
|
|
201 | 1
|
|
204 | 1
|
|
303 | 100
|
|
403 | 2
|
|
407 | 100
|
|
(13 rows)
|
|
|
|
savepoint s3;
|
|
update ft2 set c2 = -2 where c2 = 42 and c1 = 10; -- fail on remote side
|
|
ERROR: new row for relation "T 1" violates check constraint "c2positive"
|
|
DETAIL: Failing row contains (10, -2, 00010_trig_update_trig_update, 1970-01-11 08:00:00+00, 1970-01-11 00:00:00, 0, 0 , foo).
|
|
CONTEXT: Remote SQL command: UPDATE "S 1"."T 1" SET c2 = (-2) WHERE ((c2 = 42)) AND (("C 1" = 10))
|
|
rollback to savepoint s3;
|
|
select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1;
|
|
c2 | count
|
|
-----+-------
|
|
1 | 100
|
|
6 | 100
|
|
42 | 100
|
|
44 | 100
|
|
100 | 2
|
|
101 | 2
|
|
104 | 2
|
|
106 | 2
|
|
201 | 1
|
|
204 | 1
|
|
303 | 100
|
|
403 | 2
|
|
407 | 100
|
|
(13 rows)
|
|
|
|
release savepoint s3;
|
|
select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1;
|
|
c2 | count
|
|
-----+-------
|
|
1 | 100
|
|
6 | 100
|
|
42 | 100
|
|
44 | 100
|
|
100 | 2
|
|
101 | 2
|
|
104 | 2
|
|
106 | 2
|
|
201 | 1
|
|
204 | 1
|
|
303 | 100
|
|
403 | 2
|
|
407 | 100
|
|
(13 rows)
|
|
|
|
-- none of the above is committed yet remotely
|
|
select c2, count(*) from "S 1"."T 1" where c2 < 500 group by 1 order by 1;
|
|
c2 | count
|
|
-----+-------
|
|
0 | 100
|
|
1 | 100
|
|
4 | 100
|
|
6 | 100
|
|
100 | 2
|
|
101 | 2
|
|
104 | 2
|
|
106 | 2
|
|
201 | 1
|
|
204 | 1
|
|
303 | 100
|
|
403 | 2
|
|
407 | 100
|
|
(13 rows)
|
|
|
|
commit;
|
|
select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1;
|
|
c2 | count
|
|
-----+-------
|
|
1 | 100
|
|
6 | 100
|
|
42 | 100
|
|
44 | 100
|
|
100 | 2
|
|
101 | 2
|
|
104 | 2
|
|
106 | 2
|
|
201 | 1
|
|
204 | 1
|
|
303 | 100
|
|
403 | 2
|
|
407 | 100
|
|
(13 rows)
|
|
|
|
select c2, count(*) from "S 1"."T 1" where c2 < 500 group by 1 order by 1;
|
|
c2 | count
|
|
-----+-------
|
|
1 | 100
|
|
6 | 100
|
|
42 | 100
|
|
44 | 100
|
|
100 | 2
|
|
101 | 2
|
|
104 | 2
|
|
106 | 2
|
|
201 | 1
|
|
204 | 1
|
|
303 | 100
|
|
403 | 2
|
|
407 | 100
|
|
(13 rows)
|
|
|
|
-- Above DMLs add data with c6 as NULL in ft1, so test ORDER BY NULLS LAST and NULLs
|
|
-- FIRST behavior here.
|
|
-- ORDER BY DESC NULLS LAST options
|
|
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 ORDER BY c6 DESC NULLS LAST, c1 OFFSET 795 LIMIT 10;
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
-> Foreign Scan on public.ft1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ORDER BY c6 DESC NULLS LAST, "C 1" ASC NULLS LAST
|
|
(5 rows)
|
|
|
|
SELECT * FROM ft1 ORDER BY c6 DESC NULLS LAST, c1 OFFSET 795 LIMIT 10;
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
------+-----+--------------------+------------------------------+--------------------------+------+------------+-----
|
|
960 | 42 | 00960_trig_update | Mon Mar 02 00:00:00 1970 PST | Mon Mar 02 00:00:00 1970 | 0 | 0 | foo
|
|
970 | 42 | 00970_trig_update | Thu Mar 12 00:00:00 1970 PST | Thu Mar 12 00:00:00 1970 | 0 | 0 | foo
|
|
980 | 42 | 00980_trig_update | Sun Mar 22 00:00:00 1970 PST | Sun Mar 22 00:00:00 1970 | 0 | 0 | foo
|
|
990 | 42 | 00990_trig_update | Wed Apr 01 00:00:00 1970 PST | Wed Apr 01 00:00:00 1970 | 0 | 0 | foo
|
|
1000 | 42 | 01000_trig_update | Thu Jan 01 00:00:00 1970 PST | Thu Jan 01 00:00:00 1970 | 0 | 0 | foo
|
|
1218 | 818 | ggg_trig_update | | | (--; | ft2 |
|
|
1001 | 101 | 0000100001 | | | | ft2 |
|
|
1003 | 403 | 0000300003_update3 | | | | ft2 |
|
|
1004 | 104 | 0000400004 | | | | ft2 |
|
|
1006 | 106 | 0000600006 | | | | ft2 |
|
|
(10 rows)
|
|
|
|
-- ORDER BY DESC NULLS FIRST options
|
|
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 ORDER BY c6 DESC NULLS FIRST, c1 OFFSET 15 LIMIT 10;
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
-> Foreign Scan on public.ft1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ORDER BY c6 DESC NULLS FIRST, "C 1" ASC NULLS LAST
|
|
(5 rows)
|
|
|
|
SELECT * FROM ft1 ORDER BY c6 DESC NULLS FIRST, c1 OFFSET 15 LIMIT 10;
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
------+-----+-----------------+------------------------------+--------------------------+----+------------+-----
|
|
1020 | 100 | 0002000020 | | | | ft2 |
|
|
1101 | 201 | aaa | | | | ft2 |
|
|
1103 | 503 | ccc_update3 | | | | ft2 |
|
|
1104 | 204 | ddd | | | | ft2 |
|
|
1208 | 818 | fff_trig_update | | | | ft2 |
|
|
9 | 509 | 00009_update9 | Sat Jan 10 00:00:00 1970 PST | Sat Jan 10 00:00:00 1970 | 9 | ft2 | foo
|
|
19 | 509 | 00019_update9 | Tue Jan 20 00:00:00 1970 PST | Tue Jan 20 00:00:00 1970 | 9 | ft2 | foo
|
|
29 | 509 | 00029_update9 | Fri Jan 30 00:00:00 1970 PST | Fri Jan 30 00:00:00 1970 | 9 | ft2 | foo
|
|
39 | 509 | 00039_update9 | Mon Feb 09 00:00:00 1970 PST | Mon Feb 09 00:00:00 1970 | 9 | ft2 | foo
|
|
49 | 509 | 00049_update9 | Thu Feb 19 00:00:00 1970 PST | Thu Feb 19 00:00:00 1970 | 9 | ft2 | foo
|
|
(10 rows)
|
|
|
|
-- ORDER BY ASC NULLS FIRST options
|
|
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 ORDER BY c6 ASC NULLS FIRST, c1 OFFSET 15 LIMIT 10;
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
-> Foreign Scan on public.ft1
|
|
Output: c1, c2, c3, c4, c5, c6, c7, c8
|
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ORDER BY c6 ASC NULLS FIRST, "C 1" ASC NULLS LAST
|
|
(5 rows)
|
|
|
|
SELECT * FROM ft1 ORDER BY c6 ASC NULLS FIRST, c1 OFFSET 15 LIMIT 10;
|
|
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
|
------+-----+-------------------+------------------------------+--------------------------+------+------------+-----
|
|
1020 | 100 | 0002000020 | | | | ft2 |
|
|
1101 | 201 | aaa | | | | ft2 |
|
|
1103 | 503 | ccc_update3 | | | | ft2 |
|
|
1104 | 204 | ddd | | | | ft2 |
|
|
1208 | 818 | fff_trig_update | | | | ft2 |
|
|
1218 | 818 | ggg_trig_update | | | (--; | ft2 |
|
|
10 | 42 | 00010_trig_update | Sun Jan 11 00:00:00 1970 PST | Sun Jan 11 00:00:00 1970 | 0 | 0 | foo
|
|
20 | 42 | 00020_trig_update | Wed Jan 21 00:00:00 1970 PST | Wed Jan 21 00:00:00 1970 | 0 | 0 | foo
|
|
30 | 42 | 00030_trig_update | Sat Jan 31 00:00:00 1970 PST | Sat Jan 31 00:00:00 1970 | 0 | 0 | foo
|
|
40 | 42 | 00040_trig_update | Tue Feb 10 00:00:00 1970 PST | Tue Feb 10 00:00:00 1970 | 0 | 0 | foo
|
|
(10 rows)
|
|
|
|
-- ===================================================================
|
|
-- test check constraints
|
|
-- ===================================================================
|
|
-- Consistent check constraints provide consistent results
|
|
ALTER FOREIGN TABLE ft1 ADD CONSTRAINT ft1_c2positive CHECK (c2 >= 0);
|
|
EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE c2 < 0;
|
|
QUERY PLAN
|
|
-----------------------------------------------------------------
|
|
Foreign Scan
|
|
Output: (count(*))
|
|
Relations: Aggregate on (public.ft1)
|
|
Remote SQL: SELECT count(*) FROM "S 1"."T 1" WHERE ((c2 < 0))
|
|
(4 rows)
|
|
|
|
SELECT count(*) FROM ft1 WHERE c2 < 0;
|
|
count
|
|
-------
|
|
0
|
|
(1 row)
|
|
|
|
SET constraint_exclusion = 'on';
|
|
EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE c2 < 0;
|
|
QUERY PLAN
|
|
--------------------------------
|
|
Aggregate
|
|
Output: count(*)
|
|
-> Result
|
|
One-Time Filter: false
|
|
(4 rows)
|
|
|
|
SELECT count(*) FROM ft1 WHERE c2 < 0;
|
|
count
|
|
-------
|
|
0
|
|
(1 row)
|
|
|
|
RESET constraint_exclusion;
|
|
-- check constraint is enforced on the remote side, not locally
|
|
INSERT INTO ft1(c1, c2) VALUES(1111, -2); -- c2positive
|
|
ERROR: new row for relation "T 1" violates check constraint "c2positive"
|
|
DETAIL: Failing row contains (1111, -2, null, null, null, null, ft1 , null).
|
|
CONTEXT: Remote SQL command: INSERT INTO "S 1"."T 1"("C 1", c2, c3, c4, c5, c6, c7, c8) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
|
UPDATE ft1 SET c2 = -c2 WHERE c1 = 1; -- c2positive
|
|
ERROR: new row for relation "T 1" violates check constraint "c2positive"
|
|
DETAIL: Failing row contains (1, -1, 00001_trig_update, 1970-01-02 08:00:00+00, 1970-01-02 00:00:00, 1, 1 , foo).
|
|
CONTEXT: Remote SQL command: UPDATE "S 1"."T 1" SET c2 = (- c2) WHERE (("C 1" = 1))
|
|
ALTER FOREIGN TABLE ft1 DROP CONSTRAINT ft1_c2positive;
|
|
-- But inconsistent check constraints provide inconsistent results
|
|
ALTER FOREIGN TABLE ft1 ADD CONSTRAINT ft1_c2negative CHECK (c2 < 0);
|
|
EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE c2 >= 0;
|
|
QUERY PLAN
|
|
------------------------------------------------------------------
|
|
Foreign Scan
|
|
Output: (count(*))
|
|
Relations: Aggregate on (public.ft1)
|
|
Remote SQL: SELECT count(*) FROM "S 1"."T 1" WHERE ((c2 >= 0))
|
|
(4 rows)
|
|
|
|
SELECT count(*) FROM ft1 WHERE c2 >= 0;
|
|
count
|
|
-------
|
|
821
|
|
(1 row)
|
|
|
|
SET constraint_exclusion = 'on';
|
|
EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE c2 >= 0;
|
|
QUERY PLAN
|
|
--------------------------------
|
|
Aggregate
|
|
Output: count(*)
|
|
-> Result
|
|
One-Time Filter: false
|
|
(4 rows)
|
|
|
|
SELECT count(*) FROM ft1 WHERE c2 >= 0;
|
|
count
|
|
-------
|
|
0
|
|
(1 row)
|
|
|
|
RESET constraint_exclusion;
|
|
-- local check constraint is not actually enforced
|
|
INSERT INTO ft1(c1, c2) VALUES(1111, 2);
|
|
UPDATE ft1 SET c2 = c2 + 1 WHERE c1 = 1;
|
|
ALTER FOREIGN TABLE ft1 DROP CONSTRAINT ft1_c2negative;
|
|
-- ===================================================================
|
|
-- test serial columns (ie, sequence-based defaults)
|
|
-- ===================================================================
|
|
create table loc1 (f1 serial, f2 text);
|
|
create foreign table rem1 (f1 serial, f2 text)
|
|
server loopback options(table_name 'loc1');
|
|
select pg_catalog.setval('rem1_f1_seq', 10, false);
|
|
setval
|
|
--------
|
|
10
|
|
(1 row)
|
|
|
|
insert into loc1(f2) values('hi');
|
|
insert into rem1(f2) values('hi remote');
|
|
insert into loc1(f2) values('bye');
|
|
insert into rem1(f2) values('bye remote');
|
|
select * from loc1;
|
|
f1 | f2
|
|
----+------------
|
|
1 | hi
|
|
10 | hi remote
|
|
2 | bye
|
|
11 | bye remote
|
|
(4 rows)
|
|
|
|
select * from rem1;
|
|
f1 | f2
|
|
----+------------
|
|
1 | hi
|
|
10 | hi remote
|
|
2 | bye
|
|
11 | bye remote
|
|
(4 rows)
|
|
|
|
-- ===================================================================
|
|
-- test local triggers
|
|
-- ===================================================================
|
|
-- Trigger functions "borrowed" from triggers regress test.
|
|
CREATE FUNCTION trigger_func() RETURNS trigger LANGUAGE plpgsql AS $$
|
|
BEGIN
|
|
RAISE NOTICE 'trigger_func(%) called: action = %, when = %, level = %',
|
|
TG_ARGV[0], TG_OP, TG_WHEN, TG_LEVEL;
|
|
RETURN NULL;
|
|
END;$$;
|
|
CREATE TRIGGER trig_stmt_before BEFORE DELETE OR INSERT OR UPDATE ON rem1
|
|
FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func();
|
|
CREATE TRIGGER trig_stmt_after AFTER DELETE OR INSERT OR UPDATE ON rem1
|
|
FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func();
|
|
CREATE OR REPLACE FUNCTION trigger_data() RETURNS trigger
|
|
LANGUAGE plpgsql AS $$
|
|
|
|
declare
|
|
oldnew text[];
|
|
relid text;
|
|
argstr text;
|
|
begin
|
|
|
|
relid := TG_relid::regclass;
|
|
argstr := '';
|
|
for i in 0 .. TG_nargs - 1 loop
|
|
if i > 0 then
|
|
argstr := argstr || ', ';
|
|
end if;
|
|
argstr := argstr || TG_argv[i];
|
|
end loop;
|
|
|
|
RAISE NOTICE '%(%) % % % ON %',
|
|
tg_name, argstr, TG_when, TG_level, TG_OP, relid;
|
|
oldnew := '{}'::text[];
|
|
if TG_OP != 'INSERT' then
|
|
oldnew := array_append(oldnew, format('OLD: %s', OLD));
|
|
end if;
|
|
|
|
if TG_OP != 'DELETE' then
|
|
oldnew := array_append(oldnew, format('NEW: %s', NEW));
|
|
end if;
|
|
|
|
RAISE NOTICE '%', array_to_string(oldnew, ',');
|
|
|
|
if TG_OP = 'DELETE' then
|
|
return OLD;
|
|
else
|
|
return NEW;
|
|
end if;
|
|
end;
|
|
$$;
|
|
-- Test basic functionality
|
|
CREATE TRIGGER trig_row_before
|
|
BEFORE INSERT OR UPDATE OR DELETE ON rem1
|
|
FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo');
|
|
CREATE TRIGGER trig_row_after
|
|
AFTER INSERT OR UPDATE OR DELETE ON rem1
|
|
FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo');
|
|
delete from rem1;
|
|
NOTICE: trigger_func(<NULL>) called: action = DELETE, when = BEFORE, level = STATEMENT
|
|
NOTICE: trig_row_before(23, skidoo) BEFORE ROW DELETE ON rem1
|
|
NOTICE: OLD: (1,hi)
|
|
NOTICE: trig_row_before(23, skidoo) BEFORE ROW DELETE ON rem1
|
|
NOTICE: OLD: (10,"hi remote")
|
|
NOTICE: trig_row_before(23, skidoo) BEFORE ROW DELETE ON rem1
|
|
NOTICE: OLD: (2,bye)
|
|
NOTICE: trig_row_before(23, skidoo) BEFORE ROW DELETE ON rem1
|
|
NOTICE: OLD: (11,"bye remote")
|
|
NOTICE: trig_row_after(23, skidoo) AFTER ROW DELETE ON rem1
|
|
NOTICE: OLD: (1,hi)
|
|
NOTICE: trig_row_after(23, skidoo) AFTER ROW DELETE ON rem1
|
|
NOTICE: OLD: (10,"hi remote")
|
|
NOTICE: trig_row_after(23, skidoo) AFTER ROW DELETE ON rem1
|
|
NOTICE: OLD: (2,bye)
|
|
NOTICE: trig_row_after(23, skidoo) AFTER ROW DELETE ON rem1
|
|
NOTICE: OLD: (11,"bye remote")
|
|
NOTICE: trigger_func(<NULL>) called: action = DELETE, when = AFTER, level = STATEMENT
|
|
insert into rem1 values(1,'insert');
|
|
NOTICE: trigger_func(<NULL>) called: action = INSERT, when = BEFORE, level = STATEMENT
|
|
NOTICE: trig_row_before(23, skidoo) BEFORE ROW INSERT ON rem1
|
|
NOTICE: NEW: (1,insert)
|
|
NOTICE: trig_row_after(23, skidoo) AFTER ROW INSERT ON rem1
|
|
NOTICE: NEW: (1,insert)
|
|
NOTICE: trigger_func(<NULL>) called: action = INSERT, when = AFTER, level = STATEMENT
|
|
update rem1 set f2 = 'update' where f1 = 1;
|
|
NOTICE: trigger_func(<NULL>) called: action = UPDATE, when = BEFORE, level = STATEMENT
|
|
NOTICE: trig_row_before(23, skidoo) BEFORE ROW UPDATE ON rem1
|
|
NOTICE: OLD: (1,insert),NEW: (1,update)
|
|
NOTICE: trig_row_after(23, skidoo) AFTER ROW UPDATE ON rem1
|
|
NOTICE: OLD: (1,insert),NEW: (1,update)
|
|
NOTICE: trigger_func(<NULL>) called: action = UPDATE, when = AFTER, level = STATEMENT
|
|
update rem1 set f2 = f2 || f2;
|
|
NOTICE: trigger_func(<NULL>) called: action = UPDATE, when = BEFORE, level = STATEMENT
|
|
NOTICE: trig_row_before(23, skidoo) BEFORE ROW UPDATE ON rem1
|
|
NOTICE: OLD: (1,update),NEW: (1,updateupdate)
|
|
NOTICE: trig_row_after(23, skidoo) AFTER ROW UPDATE ON rem1
|
|
NOTICE: OLD: (1,update),NEW: (1,updateupdate)
|
|
NOTICE: trigger_func(<NULL>) called: action = UPDATE, when = AFTER, level = STATEMENT
|
|
-- cleanup
|
|
DROP TRIGGER trig_row_before ON rem1;
|
|
DROP TRIGGER trig_row_after ON rem1;
|
|
DROP TRIGGER trig_stmt_before ON rem1;
|
|
DROP TRIGGER trig_stmt_after ON rem1;
|
|
DELETE from rem1;
|
|
-- Test WHEN conditions
|
|
CREATE TRIGGER trig_row_before_insupd
|
|
BEFORE INSERT OR UPDATE ON rem1
|
|
FOR EACH ROW
|
|
WHEN (NEW.f2 like '%update%')
|
|
EXECUTE PROCEDURE trigger_data(23,'skidoo');
|
|
CREATE TRIGGER trig_row_after_insupd
|
|
AFTER INSERT OR UPDATE ON rem1
|
|
FOR EACH ROW
|
|
WHEN (NEW.f2 like '%update%')
|
|
EXECUTE PROCEDURE trigger_data(23,'skidoo');
|
|
-- Insert or update not matching: nothing happens
|
|
INSERT INTO rem1 values(1, 'insert');
|
|
UPDATE rem1 set f2 = 'test';
|
|
-- Insert or update matching: triggers are fired
|
|
INSERT INTO rem1 values(2, 'update');
|
|
NOTICE: trig_row_before_insupd(23, skidoo) BEFORE ROW INSERT ON rem1
|
|
NOTICE: NEW: (2,update)
|
|
NOTICE: trig_row_after_insupd(23, skidoo) AFTER ROW INSERT ON rem1
|
|
NOTICE: NEW: (2,update)
|
|
UPDATE rem1 set f2 = 'update update' where f1 = '2';
|
|
NOTICE: trig_row_before_insupd(23, skidoo) BEFORE ROW UPDATE ON rem1
|
|
NOTICE: OLD: (2,update),NEW: (2,"update update")
|
|
NOTICE: trig_row_after_insupd(23, skidoo) AFTER ROW UPDATE ON rem1
|
|
NOTICE: OLD: (2,update),NEW: (2,"update update")
|
|
CREATE TRIGGER trig_row_before_delete
|
|
BEFORE DELETE ON rem1
|
|
FOR EACH ROW
|
|
WHEN (OLD.f2 like '%update%')
|
|
EXECUTE PROCEDURE trigger_data(23,'skidoo');
|
|
CREATE TRIGGER trig_row_after_delete
|
|
AFTER DELETE ON rem1
|
|
FOR EACH ROW
|
|
WHEN (OLD.f2 like '%update%')
|
|
EXECUTE PROCEDURE trigger_data(23,'skidoo');
|
|
-- Trigger is fired for f1=2, not for f1=1
|
|
DELETE FROM rem1;
|
|
NOTICE: trig_row_before_delete(23, skidoo) BEFORE ROW DELETE ON rem1
|
|
NOTICE: OLD: (2,"update update")
|
|
NOTICE: trig_row_after_delete(23, skidoo) AFTER ROW DELETE ON rem1
|
|
NOTICE: OLD: (2,"update update")
|
|
-- cleanup
|
|
DROP TRIGGER trig_row_before_insupd ON rem1;
|
|
DROP TRIGGER trig_row_after_insupd ON rem1;
|
|
DROP TRIGGER trig_row_before_delete ON rem1;
|
|
DROP TRIGGER trig_row_after_delete ON rem1;
|
|
-- Test various RETURN statements in BEFORE triggers.
|
|
CREATE FUNCTION trig_row_before_insupdate() RETURNS TRIGGER AS $$
|
|
BEGIN
|
|
NEW.f2 := NEW.f2 || ' triggered !';
|
|
RETURN NEW;
|
|
END
|
|
$$ language plpgsql;
|
|
CREATE TRIGGER trig_row_before_insupd
|
|
BEFORE INSERT OR UPDATE ON rem1
|
|
FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate();
|
|
-- The new values should have 'triggered' appended
|
|
INSERT INTO rem1 values(1, 'insert');
|
|
SELECT * from loc1;
|
|
f1 | f2
|
|
----+--------------------
|
|
1 | insert triggered !
|
|
(1 row)
|
|
|
|
INSERT INTO rem1 values(2, 'insert') RETURNING f2;
|
|
f2
|
|
--------------------
|
|
insert triggered !
|
|
(1 row)
|
|
|
|
SELECT * from loc1;
|
|
f1 | f2
|
|
----+--------------------
|
|
1 | insert triggered !
|
|
2 | insert triggered !
|
|
(2 rows)
|
|
|
|
UPDATE rem1 set f2 = '';
|
|
SELECT * from loc1;
|
|
f1 | f2
|
|
----+--------------
|
|
1 | triggered !
|
|
2 | triggered !
|
|
(2 rows)
|
|
|
|
UPDATE rem1 set f2 = 'skidoo' RETURNING f2;
|
|
f2
|
|
--------------------
|
|
skidoo triggered !
|
|
skidoo triggered !
|
|
(2 rows)
|
|
|
|
SELECT * from loc1;
|
|
f1 | f2
|
|
----+--------------------
|
|
1 | skidoo triggered !
|
|
2 | skidoo triggered !
|
|
(2 rows)
|
|
|
|
DELETE FROM rem1;
|
|
-- Add a second trigger, to check that the changes are propagated correctly
|
|
-- from trigger to trigger
|
|
CREATE TRIGGER trig_row_before_insupd2
|
|
BEFORE INSERT OR UPDATE ON rem1
|
|
FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate();
|
|
INSERT INTO rem1 values(1, 'insert');
|
|
SELECT * from loc1;
|
|
f1 | f2
|
|
----+--------------------------------
|
|
1 | insert triggered ! triggered !
|
|
(1 row)
|
|
|
|
INSERT INTO rem1 values(2, 'insert') RETURNING f2;
|
|
f2
|
|
--------------------------------
|
|
insert triggered ! triggered !
|
|
(1 row)
|
|
|
|
SELECT * from loc1;
|
|
f1 | f2
|
|
----+--------------------------------
|
|
1 | insert triggered ! triggered !
|
|
2 | insert triggered ! triggered !
|
|
(2 rows)
|
|
|
|
UPDATE rem1 set f2 = '';
|
|
SELECT * from loc1;
|
|
f1 | f2
|
|
----+--------------------------
|
|
1 | triggered ! triggered !
|
|
2 | triggered ! triggered !
|
|
(2 rows)
|
|
|
|
UPDATE rem1 set f2 = 'skidoo' RETURNING f2;
|
|
f2
|
|
--------------------------------
|
|
skidoo triggered ! triggered !
|
|
skidoo triggered ! triggered !
|
|
(2 rows)
|
|
|
|
SELECT * from loc1;
|
|
f1 | f2
|
|
----+--------------------------------
|
|
1 | skidoo triggered ! triggered !
|
|
2 | skidoo triggered ! triggered !
|
|
(2 rows)
|
|
|
|
DROP TRIGGER trig_row_before_insupd ON rem1;
|
|
DROP TRIGGER trig_row_before_insupd2 ON rem1;
|
|
DELETE from rem1;
|
|
INSERT INTO rem1 VALUES (1, 'test');
|
|
-- Test with a trigger returning NULL
|
|
CREATE FUNCTION trig_null() RETURNS TRIGGER AS $$
|
|
BEGIN
|
|
RETURN NULL;
|
|
END
|
|
$$ language plpgsql;
|
|
CREATE TRIGGER trig_null
|
|
BEFORE INSERT OR UPDATE OR DELETE ON rem1
|
|
FOR EACH ROW EXECUTE PROCEDURE trig_null();
|
|
-- Nothing should have changed.
|
|
INSERT INTO rem1 VALUES (2, 'test2');
|
|
SELECT * from loc1;
|
|
f1 | f2
|
|
----+------
|
|
1 | test
|
|
(1 row)
|
|
|
|
UPDATE rem1 SET f2 = 'test2';
|
|
SELECT * from loc1;
|
|
f1 | f2
|
|
----+------
|
|
1 | test
|
|
(1 row)
|
|
|
|
DELETE from rem1;
|
|
SELECT * from loc1;
|
|
f1 | f2
|
|
----+------
|
|
1 | test
|
|
(1 row)
|
|
|
|
DROP TRIGGER trig_null ON rem1;
|
|
DELETE from rem1;
|
|
-- Test a combination of local and remote triggers
|
|
CREATE TRIGGER trig_row_before
|
|
BEFORE INSERT OR UPDATE OR DELETE ON rem1
|
|
FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo');
|
|
CREATE TRIGGER trig_row_after
|
|
AFTER INSERT OR UPDATE OR DELETE ON rem1
|
|
FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo');
|
|
CREATE TRIGGER trig_local_before BEFORE INSERT OR UPDATE ON loc1
|
|
FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate();
|
|
INSERT INTO rem1(f2) VALUES ('test');
|
|
NOTICE: trig_row_before(23, skidoo) BEFORE ROW INSERT ON rem1
|
|
NOTICE: NEW: (12,test)
|
|
NOTICE: trig_row_after(23, skidoo) AFTER ROW INSERT ON rem1
|
|
NOTICE: NEW: (12,"test triggered !")
|
|
UPDATE rem1 SET f2 = 'testo';
|
|
NOTICE: trig_row_before(23, skidoo) BEFORE ROW UPDATE ON rem1
|
|
NOTICE: OLD: (12,"test triggered !"),NEW: (12,testo)
|
|
NOTICE: trig_row_after(23, skidoo) AFTER ROW UPDATE ON rem1
|
|
NOTICE: OLD: (12,"test triggered !"),NEW: (12,"testo triggered !")
|
|
-- Test returning a system attribute
|
|
INSERT INTO rem1(f2) VALUES ('test') RETURNING ctid;
|
|
NOTICE: trig_row_before(23, skidoo) BEFORE ROW INSERT ON rem1
|
|
NOTICE: NEW: (13,test)
|
|
NOTICE: trig_row_after(23, skidoo) AFTER ROW INSERT ON rem1
|
|
NOTICE: NEW: (13,"test triggered !")
|
|
ctid
|
|
--------
|
|
(0,27)
|
|
(1 row)
|
|
|
|
-- cleanup
|
|
DROP TRIGGER trig_row_before ON rem1;
|
|
DROP TRIGGER trig_row_after ON rem1;
|
|
DROP TRIGGER trig_local_before ON loc1;
|
|
-- Test direct foreign table modification functionality
|
|
-- Test with statement-level triggers
|
|
CREATE TRIGGER trig_stmt_before
|
|
BEFORE DELETE OR INSERT OR UPDATE ON rem1
|
|
FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func();
|
|
EXPLAIN (verbose, costs off)
|
|
UPDATE rem1 set f2 = ''; -- can be pushed down
|
|
QUERY PLAN
|
|
----------------------------------------------------------
|
|
Update on public.rem1
|
|
-> Foreign Update on public.rem1
|
|
Remote SQL: UPDATE public.loc1 SET f2 = ''::text
|
|
(3 rows)
|
|
|
|
EXPLAIN (verbose, costs off)
|
|
DELETE FROM rem1; -- can be pushed down
|
|
QUERY PLAN
|
|
---------------------------------------------
|
|
Delete on public.rem1
|
|
-> Foreign Delete on public.rem1
|
|
Remote SQL: DELETE FROM public.loc1
|
|
(3 rows)
|
|
|
|
DROP TRIGGER trig_stmt_before ON rem1;
|
|
CREATE TRIGGER trig_stmt_after
|
|
AFTER DELETE OR INSERT OR UPDATE ON rem1
|
|
FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func();
|
|
EXPLAIN (verbose, costs off)
|
|
UPDATE rem1 set f2 = ''; -- can be pushed down
|
|
QUERY PLAN
|
|
----------------------------------------------------------
|
|
Update on public.rem1
|
|
-> Foreign Update on public.rem1
|
|
Remote SQL: UPDATE public.loc1 SET f2 = ''::text
|
|
(3 rows)
|
|
|
|
EXPLAIN (verbose, costs off)
|
|
DELETE FROM rem1; -- can be pushed down
|
|
QUERY PLAN
|
|
---------------------------------------------
|
|
Delete on public.rem1
|
|
-> Foreign Delete on public.rem1
|
|
Remote SQL: DELETE FROM public.loc1
|
|
(3 rows)
|
|
|
|
DROP TRIGGER trig_stmt_after ON rem1;
|
|
-- Test with row-level ON INSERT triggers
|
|
CREATE TRIGGER trig_row_before_insert
|
|
BEFORE INSERT ON rem1
|
|
FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo');
|
|
EXPLAIN (verbose, costs off)
|
|
UPDATE rem1 set f2 = ''; -- can be pushed down
|
|
QUERY PLAN
|
|
----------------------------------------------------------
|
|
Update on public.rem1
|
|
-> Foreign Update on public.rem1
|
|
Remote SQL: UPDATE public.loc1 SET f2 = ''::text
|
|
(3 rows)
|
|
|
|
EXPLAIN (verbose, costs off)
|
|
DELETE FROM rem1; -- can be pushed down
|
|
QUERY PLAN
|
|
---------------------------------------------
|
|
Delete on public.rem1
|
|
-> Foreign Delete on public.rem1
|
|
Remote SQL: DELETE FROM public.loc1
|
|
(3 rows)
|
|
|
|
DROP TRIGGER trig_row_before_insert ON rem1;
|
|
CREATE TRIGGER trig_row_after_insert
|
|
AFTER INSERT ON rem1
|
|
FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo');
|
|
EXPLAIN (verbose, costs off)
|
|
UPDATE rem1 set f2 = ''; -- can be pushed down
|
|
QUERY PLAN
|
|
----------------------------------------------------------
|
|
Update on public.rem1
|
|
-> Foreign Update on public.rem1
|
|
Remote SQL: UPDATE public.loc1 SET f2 = ''::text
|
|
(3 rows)
|
|
|
|
EXPLAIN (verbose, costs off)
|
|
DELETE FROM rem1; -- can be pushed down
|
|
QUERY PLAN
|
|
---------------------------------------------
|
|
Delete on public.rem1
|
|
-> Foreign Delete on public.rem1
|
|
Remote SQL: DELETE FROM public.loc1
|
|
(3 rows)
|
|
|
|
DROP TRIGGER trig_row_after_insert ON rem1;
|
|
-- Test with row-level ON UPDATE triggers
|
|
CREATE TRIGGER trig_row_before_update
|
|
BEFORE UPDATE ON rem1
|
|
FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo');
|
|
EXPLAIN (verbose, costs off)
|
|
UPDATE rem1 set f2 = ''; -- can't be pushed down
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------
|
|
Update on public.rem1
|
|
Remote SQL: UPDATE public.loc1 SET f2 = $2 WHERE ctid = $1
|
|
-> Foreign Scan on public.rem1
|
|
Output: f1, ''::text, ctid, rem1.*
|
|
Remote SQL: SELECT f1, f2, ctid FROM public.loc1 FOR UPDATE
|
|
(5 rows)
|
|
|
|
EXPLAIN (verbose, costs off)
|
|
DELETE FROM rem1; -- can be pushed down
|
|
QUERY PLAN
|
|
---------------------------------------------
|
|
Delete on public.rem1
|
|
-> Foreign Delete on public.rem1
|
|
Remote SQL: DELETE FROM public.loc1
|
|
(3 rows)
|
|
|
|
DROP TRIGGER trig_row_before_update ON rem1;
|
|
CREATE TRIGGER trig_row_after_update
|
|
AFTER UPDATE ON rem1
|
|
FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo');
|
|
EXPLAIN (verbose, costs off)
|
|
UPDATE rem1 set f2 = ''; -- can't be pushed down
|
|
QUERY PLAN
|
|
-------------------------------------------------------------------------------
|
|
Update on public.rem1
|
|
Remote SQL: UPDATE public.loc1 SET f2 = $2 WHERE ctid = $1 RETURNING f1, f2
|
|
-> Foreign Scan on public.rem1
|
|
Output: f1, ''::text, ctid, rem1.*
|
|
Remote SQL: SELECT f1, f2, ctid FROM public.loc1 FOR UPDATE
|
|
(5 rows)
|
|
|
|
EXPLAIN (verbose, costs off)
|
|
DELETE FROM rem1; -- can be pushed down
|
|
QUERY PLAN
|
|
---------------------------------------------
|
|
Delete on public.rem1
|
|
-> Foreign Delete on public.rem1
|
|
Remote SQL: DELETE FROM public.loc1
|
|
(3 rows)
|
|
|
|
DROP TRIGGER trig_row_after_update ON rem1;
|
|
-- Test with row-level ON DELETE triggers
|
|
CREATE TRIGGER trig_row_before_delete
|
|
BEFORE DELETE ON rem1
|
|
FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo');
|
|
EXPLAIN (verbose, costs off)
|
|
UPDATE rem1 set f2 = ''; -- can be pushed down
|
|
QUERY PLAN
|
|
----------------------------------------------------------
|
|
Update on public.rem1
|
|
-> Foreign Update on public.rem1
|
|
Remote SQL: UPDATE public.loc1 SET f2 = ''::text
|
|
(3 rows)
|
|
|
|
EXPLAIN (verbose, costs off)
|
|
DELETE FROM rem1; -- can't be pushed down
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------
|
|
Delete on public.rem1
|
|
Remote SQL: DELETE FROM public.loc1 WHERE ctid = $1
|
|
-> Foreign Scan on public.rem1
|
|
Output: ctid, rem1.*
|
|
Remote SQL: SELECT f1, f2, ctid FROM public.loc1 FOR UPDATE
|
|
(5 rows)
|
|
|
|
DROP TRIGGER trig_row_before_delete ON rem1;
|
|
CREATE TRIGGER trig_row_after_delete
|
|
AFTER DELETE ON rem1
|
|
FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo');
|
|
EXPLAIN (verbose, costs off)
|
|
UPDATE rem1 set f2 = ''; -- can be pushed down
|
|
QUERY PLAN
|
|
----------------------------------------------------------
|
|
Update on public.rem1
|
|
-> Foreign Update on public.rem1
|
|
Remote SQL: UPDATE public.loc1 SET f2 = ''::text
|
|
(3 rows)
|
|
|
|
EXPLAIN (verbose, costs off)
|
|
DELETE FROM rem1; -- can't be pushed down
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------
|
|
Delete on public.rem1
|
|
Remote SQL: DELETE FROM public.loc1 WHERE ctid = $1 RETURNING f1, f2
|
|
-> Foreign Scan on public.rem1
|
|
Output: ctid, rem1.*
|
|
Remote SQL: SELECT f1, f2, ctid FROM public.loc1 FOR UPDATE
|
|
(5 rows)
|
|
|
|
DROP TRIGGER trig_row_after_delete ON rem1;
|
|
-- ===================================================================
|
|
-- test inheritance features
|
|
-- ===================================================================
|
|
CREATE TABLE a (aa TEXT);
|
|
CREATE TABLE loct (aa TEXT, bb TEXT);
|
|
CREATE FOREIGN TABLE b (bb TEXT) INHERITS (a)
|
|
SERVER loopback OPTIONS (table_name 'loct');
|
|
INSERT INTO a(aa) VALUES('aaa');
|
|
INSERT INTO a(aa) VALUES('aaaa');
|
|
INSERT INTO a(aa) VALUES('aaaaa');
|
|
INSERT INTO b(aa) VALUES('bbb');
|
|
INSERT INTO b(aa) VALUES('bbbb');
|
|
INSERT INTO b(aa) VALUES('bbbbb');
|
|
SELECT tableoid::regclass, * FROM a;
|
|
tableoid | aa
|
|
----------+-------
|
|
a | aaa
|
|
a | aaaa
|
|
a | aaaaa
|
|
b | bbb
|
|
b | bbbb
|
|
b | bbbbb
|
|
(6 rows)
|
|
|
|
SELECT tableoid::regclass, * FROM b;
|
|
tableoid | aa | bb
|
|
----------+-------+----
|
|
b | bbb |
|
|
b | bbbb |
|
|
b | bbbbb |
|
|
(3 rows)
|
|
|
|
SELECT tableoid::regclass, * FROM ONLY a;
|
|
tableoid | aa
|
|
----------+-------
|
|
a | aaa
|
|
a | aaaa
|
|
a | aaaaa
|
|
(3 rows)
|
|
|
|
UPDATE a SET aa = 'zzzzzz' WHERE aa LIKE 'aaaa%';
|
|
SELECT tableoid::regclass, * FROM a;
|
|
tableoid | aa
|
|
----------+--------
|
|
a | aaa
|
|
a | zzzzzz
|
|
a | zzzzzz
|
|
b | bbb
|
|
b | bbbb
|
|
b | bbbbb
|
|
(6 rows)
|
|
|
|
SELECT tableoid::regclass, * FROM b;
|
|
tableoid | aa | bb
|
|
----------+-------+----
|
|
b | bbb |
|
|
b | bbbb |
|
|
b | bbbbb |
|
|
(3 rows)
|
|
|
|
SELECT tableoid::regclass, * FROM ONLY a;
|
|
tableoid | aa
|
|
----------+--------
|
|
a | aaa
|
|
a | zzzzzz
|
|
a | zzzzzz
|
|
(3 rows)
|
|
|
|
UPDATE b SET aa = 'new';
|
|
SELECT tableoid::regclass, * FROM a;
|
|
tableoid | aa
|
|
----------+--------
|
|
a | aaa
|
|
a | zzzzzz
|
|
a | zzzzzz
|
|
b | new
|
|
b | new
|
|
b | new
|
|
(6 rows)
|
|
|
|
SELECT tableoid::regclass, * FROM b;
|
|
tableoid | aa | bb
|
|
----------+-----+----
|
|
b | new |
|
|
b | new |
|
|
b | new |
|
|
(3 rows)
|
|
|
|
SELECT tableoid::regclass, * FROM ONLY a;
|
|
tableoid | aa
|
|
----------+--------
|
|
a | aaa
|
|
a | zzzzzz
|
|
a | zzzzzz
|
|
(3 rows)
|
|
|
|
UPDATE a SET aa = 'newtoo';
|
|
SELECT tableoid::regclass, * FROM a;
|
|
tableoid | aa
|
|
----------+--------
|
|
a | newtoo
|
|
a | newtoo
|
|
a | newtoo
|
|
b | newtoo
|
|
b | newtoo
|
|
b | newtoo
|
|
(6 rows)
|
|
|
|
SELECT tableoid::regclass, * FROM b;
|
|
tableoid | aa | bb
|
|
----------+--------+----
|
|
b | newtoo |
|
|
b | newtoo |
|
|
b | newtoo |
|
|
(3 rows)
|
|
|
|
SELECT tableoid::regclass, * FROM ONLY a;
|
|
tableoid | aa
|
|
----------+--------
|
|
a | newtoo
|
|
a | newtoo
|
|
a | newtoo
|
|
(3 rows)
|
|
|
|
DELETE FROM a;
|
|
SELECT tableoid::regclass, * FROM a;
|
|
tableoid | aa
|
|
----------+----
|
|
(0 rows)
|
|
|
|
SELECT tableoid::regclass, * FROM b;
|
|
tableoid | aa | bb
|
|
----------+----+----
|
|
(0 rows)
|
|
|
|
SELECT tableoid::regclass, * FROM ONLY a;
|
|
tableoid | aa
|
|
----------+----
|
|
(0 rows)
|
|
|
|
DROP TABLE a CASCADE;
|
|
NOTICE: drop cascades to foreign table b
|
|
DROP TABLE loct;
|
|
-- Check SELECT FOR UPDATE/SHARE with an inherited source table
|
|
create table loct1 (f1 int, f2 int, f3 int);
|
|
create table loct2 (f1 int, f2 int, f3 int);
|
|
create table foo (f1 int, f2 int);
|
|
create foreign table foo2 (f3 int) inherits (foo)
|
|
server loopback options (table_name 'loct1');
|
|
create table bar (f1 int, f2 int);
|
|
create foreign table bar2 (f3 int) inherits (bar)
|
|
server loopback options (table_name 'loct2');
|
|
insert into foo values(1,1);
|
|
insert into foo values(3,3);
|
|
insert into foo2 values(2,2,2);
|
|
insert into foo2 values(4,4,4);
|
|
insert into bar values(1,11);
|
|
insert into bar values(2,22);
|
|
insert into bar values(6,66);
|
|
insert into bar2 values(3,33,33);
|
|
insert into bar2 values(4,44,44);
|
|
insert into bar2 values(7,77,77);
|
|
explain (verbose, costs off)
|
|
select * from bar where f1 in (select f1 from foo) for update;
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------------------------------
|
|
LockRows
|
|
Output: bar.f1, bar.f2, bar.ctid, bar.*, bar.tableoid, foo.ctid, foo.*, foo.tableoid
|
|
-> Hash Join
|
|
Output: bar.f1, bar.f2, bar.ctid, bar.*, bar.tableoid, foo.ctid, foo.*, foo.tableoid
|
|
Hash Cond: (bar.f1 = foo.f1)
|
|
-> Append
|
|
-> Seq Scan on public.bar
|
|
Output: bar.f1, bar.f2, bar.ctid, bar.*, bar.tableoid
|
|
-> Foreign Scan on public.bar2
|
|
Output: bar2.f1, bar2.f2, bar2.ctid, bar2.*, bar2.tableoid
|
|
Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 FOR UPDATE
|
|
-> Hash
|
|
Output: foo.ctid, foo.*, foo.tableoid, foo.f1
|
|
-> HashAggregate
|
|
Output: foo.ctid, foo.*, foo.tableoid, foo.f1
|
|
Group Key: foo.f1
|
|
-> Append
|
|
-> Seq Scan on public.foo
|
|
Output: foo.ctid, foo.*, foo.tableoid, foo.f1
|
|
-> Foreign Scan on public.foo2
|
|
Output: foo2.ctid, foo2.*, foo2.tableoid, foo2.f1
|
|
Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct1
|
|
(22 rows)
|
|
|
|
select * from bar where f1 in (select f1 from foo) for update;
|
|
f1 | f2
|
|
----+----
|
|
1 | 11
|
|
2 | 22
|
|
3 | 33
|
|
4 | 44
|
|
(4 rows)
|
|
|
|
explain (verbose, costs off)
|
|
select * from bar where f1 in (select f1 from foo) for share;
|
|
QUERY PLAN
|
|
----------------------------------------------------------------------------------------------
|
|
LockRows
|
|
Output: bar.f1, bar.f2, bar.ctid, bar.*, bar.tableoid, foo.ctid, foo.*, foo.tableoid
|
|
-> Hash Join
|
|
Output: bar.f1, bar.f2, bar.ctid, bar.*, bar.tableoid, foo.ctid, foo.*, foo.tableoid
|
|
Hash Cond: (bar.f1 = foo.f1)
|
|
-> Append
|
|
-> Seq Scan on public.bar
|
|
Output: bar.f1, bar.f2, bar.ctid, bar.*, bar.tableoid
|
|
-> Foreign Scan on public.bar2
|
|
Output: bar2.f1, bar2.f2, bar2.ctid, bar2.*, bar2.tableoid
|
|
Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 FOR SHARE
|
|
-> Hash
|
|
Output: foo.ctid, foo.*, foo.tableoid, foo.f1
|
|
-> HashAggregate
|
|
Output: foo.ctid, foo.*, foo.tableoid, foo.f1
|
|
Group Key: foo.f1
|
|
-> Append
|
|
-> Seq Scan on public.foo
|
|
Output: foo.ctid, foo.*, foo.tableoid, foo.f1
|
|
-> Foreign Scan on public.foo2
|
|
Output: foo2.ctid, foo2.*, foo2.tableoid, foo2.f1
|
|
Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct1
|
|
(22 rows)
|
|
|
|
select * from bar where f1 in (select f1 from foo) for share;
|
|
f1 | f2
|
|
----+----
|
|
1 | 11
|
|
2 | 22
|
|
3 | 33
|
|
4 | 44
|
|
(4 rows)
|
|
|
|
-- Check UPDATE with inherited target and an inherited source table
|
|
explain (verbose, costs off)
|
|
update bar set f2 = f2 + 100 where f1 in (select f1 from foo);
|
|
QUERY PLAN
|
|
---------------------------------------------------------------------------------------------
|
|
Update on public.bar
|
|
Update on public.bar
|
|
Foreign Update on public.bar2
|
|
Remote SQL: UPDATE public.loct2 SET f2 = $2 WHERE ctid = $1
|
|
-> Hash Join
|
|
Output: bar.f1, (bar.f2 + 100), bar.ctid, foo.ctid, foo.*, foo.tableoid
|
|
Hash Cond: (bar.f1 = foo.f1)
|
|
-> Seq Scan on public.bar
|
|
Output: bar.f1, bar.f2, bar.ctid
|
|
-> Hash
|
|
Output: foo.ctid, foo.*, foo.tableoid, foo.f1
|
|
-> HashAggregate
|
|
Output: foo.ctid, foo.*, foo.tableoid, foo.f1
|
|
Group Key: foo.f1
|
|
-> Append
|
|
-> Seq Scan on public.foo
|
|
Output: foo.ctid, foo.*, foo.tableoid, foo.f1
|
|
-> Foreign Scan on public.foo2
|
|
Output: foo2.ctid, foo2.*, foo2.tableoid, foo2.f1
|
|
Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct1
|
|
-> Hash Join
|
|
Output: bar2.f1, (bar2.f2 + 100), bar2.f3, bar2.ctid, foo.ctid, foo.*, foo.tableoid
|
|
Hash Cond: (bar2.f1 = foo.f1)
|
|
-> Foreign Scan on public.bar2
|
|
Output: bar2.f1, bar2.f2, bar2.f3, bar2.ctid
|
|
Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 FOR UPDATE
|
|
-> Hash
|
|
Output: foo.ctid, foo.*, foo.tableoid, foo.f1
|
|
-> HashAggregate
|
|
Output: foo.ctid, foo.*, foo.tableoid, foo.f1
|
|
Group Key: foo.f1
|
|
-> Append
|
|
-> Seq Scan on public.foo
|
|
Output: foo.ctid, foo.*, foo.tableoid, foo.f1
|
|
-> Foreign Scan on public.foo2
|
|
Output: foo2.ctid, foo2.*, foo2.tableoid, foo2.f1
|
|
Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct1
|
|
(37 rows)
|
|
|
|
update bar set f2 = f2 + 100 where f1 in (select f1 from foo);
|
|
select tableoid::regclass, * from bar order by 1,2;
|
|
tableoid | f1 | f2
|
|
----------+----+-----
|
|
bar | 1 | 111
|
|
bar | 2 | 122
|
|
bar | 6 | 66
|
|
bar2 | 3 | 133
|
|
bar2 | 4 | 144
|
|
bar2 | 7 | 77
|
|
(6 rows)
|
|
|
|
-- Check UPDATE with inherited target and an appendrel subquery
|
|
explain (verbose, costs off)
|
|
update bar set f2 = f2 + 100
|
|
from
|
|
( select f1 from foo union all select f1+3 from foo ) ss
|
|
where bar.f1 = ss.f1;
|
|
QUERY PLAN
|
|
--------------------------------------------------------------------------------------
|
|
Update on public.bar
|
|
Update on public.bar
|
|
Foreign Update on public.bar2
|
|
Remote SQL: UPDATE public.loct2 SET f2 = $2 WHERE ctid = $1
|
|
-> Hash Join
|
|
Output: bar.f1, (bar.f2 + 100), bar.ctid, (ROW(foo.f1))
|
|
Hash Cond: (foo.f1 = bar.f1)
|
|
-> Append
|
|
-> Seq Scan on public.foo
|
|
Output: ROW(foo.f1), foo.f1
|
|
-> Foreign Scan on public.foo2
|
|
Output: ROW(foo2.f1), foo2.f1
|
|
Remote SQL: SELECT f1 FROM public.loct1
|
|
-> Seq Scan on public.foo foo_1
|
|
Output: ROW((foo_1.f1 + 3)), (foo_1.f1 + 3)
|
|
-> Foreign Scan on public.foo2 foo2_1
|
|
Output: ROW((foo2_1.f1 + 3)), (foo2_1.f1 + 3)
|
|
Remote SQL: SELECT f1 FROM public.loct1
|
|
-> Hash
|
|
Output: bar.f1, bar.f2, bar.ctid
|
|
-> Seq Scan on public.bar
|
|
Output: bar.f1, bar.f2, bar.ctid
|
|
-> Merge Join
|
|
Output: bar2.f1, (bar2.f2 + 100), bar2.f3, bar2.ctid, (ROW(foo.f1))
|
|
Merge Cond: (bar2.f1 = foo.f1)
|
|
-> Sort
|
|
Output: bar2.f1, bar2.f2, bar2.f3, bar2.ctid
|
|
Sort Key: bar2.f1
|
|
-> Foreign Scan on public.bar2
|
|
Output: bar2.f1, bar2.f2, bar2.f3, bar2.ctid
|
|
Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 FOR UPDATE
|
|
-> Sort
|
|
Output: (ROW(foo.f1)), foo.f1
|
|
Sort Key: foo.f1
|
|
-> Append
|
|
-> Seq Scan on public.foo
|
|
Output: ROW(foo.f1), foo.f1
|
|
-> Foreign Scan on public.foo2
|
|
Output: ROW(foo2.f1), foo2.f1
|
|
Remote SQL: SELECT f1 FROM public.loct1
|
|
-> Seq Scan on public.foo foo_1
|
|
Output: ROW((foo_1.f1 + 3)), (foo_1.f1 + 3)
|
|
-> Foreign Scan on public.foo2 foo2_1
|
|
Output: ROW((foo2_1.f1 + 3)), (foo2_1.f1 + 3)
|
|
Remote SQL: SELECT f1 FROM public.loct1
|
|
(45 rows)
|
|
|
|
update bar set f2 = f2 + 100
|
|
from
|
|
( select f1 from foo union all select f1+3 from foo ) ss
|
|
where bar.f1 = ss.f1;
|
|
select tableoid::regclass, * from bar order by 1,2;
|
|
tableoid | f1 | f2
|
|
----------+----+-----
|
|
bar | 1 | 211
|
|
bar | 2 | 222
|
|
bar | 6 | 166
|
|
bar2 | 3 | 233
|
|
bar2 | 4 | 244
|
|
bar2 | 7 | 177
|
|
(6 rows)
|
|
|
|
-- Test forcing the remote server to produce sorted data for a merge join,
|
|
-- but the foreign table is an inheritance child.
|
|
truncate table loct1;
|
|
truncate table only foo;
|
|
\set num_rows_foo 2000
|
|
insert into loct1 select generate_series(0, :num_rows_foo, 2), generate_series(0, :num_rows_foo, 2), generate_series(0, :num_rows_foo, 2);
|
|
insert into foo select generate_series(1, :num_rows_foo, 2), generate_series(1, :num_rows_foo, 2);
|
|
SET enable_hashjoin to false;
|
|
SET enable_nestloop to false;
|
|
alter foreign table foo2 options (use_remote_estimate 'true');
|
|
create index i_loct1_f1 on loct1(f1);
|
|
create index i_foo_f1 on foo(f1);
|
|
analyze foo;
|
|
analyze loct1;
|
|
-- inner join; expressions in the clauses appear in the equivalence class list
|
|
explain (verbose, costs off)
|
|
select foo.f1, loct1.f1 from foo join loct1 on (foo.f1 = loct1.f1) order by foo.f2 offset 10 limit 10;
|
|
QUERY PLAN
|
|
--------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: foo.f1, loct1.f1, foo.f2
|
|
-> Sort
|
|
Output: foo.f1, loct1.f1, foo.f2
|
|
Sort Key: foo.f2
|
|
-> Merge Join
|
|
Output: foo.f1, loct1.f1, foo.f2
|
|
Merge Cond: (foo.f1 = loct1.f1)
|
|
-> Merge Append
|
|
Sort Key: foo.f1
|
|
-> Index Scan using i_foo_f1 on public.foo
|
|
Output: foo.f1, foo.f2
|
|
-> Foreign Scan on public.foo2
|
|
Output: foo2.f1, foo2.f2
|
|
Remote SQL: SELECT f1, f2 FROM public.loct1 ORDER BY f1 ASC NULLS LAST
|
|
-> Index Only Scan using i_loct1_f1 on public.loct1
|
|
Output: loct1.f1
|
|
(17 rows)
|
|
|
|
select foo.f1, loct1.f1 from foo join loct1 on (foo.f1 = loct1.f1) order by foo.f2 offset 10 limit 10;
|
|
f1 | f1
|
|
----+----
|
|
20 | 20
|
|
22 | 22
|
|
24 | 24
|
|
26 | 26
|
|
28 | 28
|
|
30 | 30
|
|
32 | 32
|
|
34 | 34
|
|
36 | 36
|
|
38 | 38
|
|
(10 rows)
|
|
|
|
-- outer join; expressions in the clauses do not appear in equivalence class
|
|
-- list but no output change as compared to the previous query
|
|
explain (verbose, costs off)
|
|
select foo.f1, loct1.f1 from foo left join loct1 on (foo.f1 = loct1.f1) order by foo.f2 offset 10 limit 10;
|
|
QUERY PLAN
|
|
--------------------------------------------------------------------------------------------------
|
|
Limit
|
|
Output: foo.f1, loct1.f1, foo.f2
|
|
-> Sort
|
|
Output: foo.f1, loct1.f1, foo.f2
|
|
Sort Key: foo.f2
|
|
-> Merge Left Join
|
|
Output: foo.f1, loct1.f1, foo.f2
|
|
Merge Cond: (foo.f1 = loct1.f1)
|
|
-> Merge Append
|
|
Sort Key: foo.f1
|
|
-> Index Scan using i_foo_f1 on public.foo
|
|
Output: foo.f1, foo.f2
|
|
-> Foreign Scan on public.foo2
|
|
Output: foo2.f1, foo2.f2
|
|
Remote SQL: SELECT f1, f2 FROM public.loct1 ORDER BY f1 ASC NULLS LAST
|
|
-> Index Only Scan using i_loct1_f1 on public.loct1
|
|
Output: loct1.f1
|
|
(17 rows)
|
|
|
|
select foo.f1, loct1.f1 from foo left join loct1 on (foo.f1 = loct1.f1) order by foo.f2 offset 10 limit 10;
|
|
f1 | f1
|
|
----+----
|
|
10 | 10
|
|
11 |
|
|
12 | 12
|
|
13 |
|
|
14 | 14
|
|
15 |
|
|
16 | 16
|
|
17 |
|
|
18 | 18
|
|
19 |
|
|
(10 rows)
|
|
|
|
RESET enable_hashjoin;
|
|
RESET enable_nestloop;
|
|
-- Test that WHERE CURRENT OF is not supported
|
|
begin;
|
|
declare c cursor for select * from bar where f1 = 7;
|
|
fetch from c;
|
|
f1 | f2
|
|
----+-----
|
|
7 | 177
|
|
(1 row)
|
|
|
|
update bar set f2 = null where current of c;
|
|
ERROR: WHERE CURRENT OF is not supported for this table type
|
|
rollback;
|
|
explain (verbose, costs off)
|
|
delete from foo where f1 < 5 returning *;
|
|
QUERY PLAN
|
|
--------------------------------------------------------------------------------
|
|
Delete on public.foo
|
|
Output: foo.f1, foo.f2
|
|
Delete on public.foo
|
|
Foreign Delete on public.foo2
|
|
-> Index Scan using i_foo_f1 on public.foo
|
|
Output: foo.ctid
|
|
Index Cond: (foo.f1 < 5)
|
|
-> Foreign Delete on public.foo2
|
|
Remote SQL: DELETE FROM public.loct1 WHERE ((f1 < 5)) RETURNING f1, f2
|
|
(9 rows)
|
|
|
|
delete from foo where f1 < 5 returning *;
|
|
f1 | f2
|
|
----+----
|
|
1 | 1
|
|
3 | 3
|
|
0 | 0
|
|
2 | 2
|
|
4 | 4
|
|
(5 rows)
|
|
|
|
explain (verbose, costs off)
|
|
update bar set f2 = f2 + 100 returning *;
|
|
QUERY PLAN
|
|
------------------------------------------------------------------------------
|
|
Update on public.bar
|
|
Output: bar.f1, bar.f2
|
|
Update on public.bar
|
|
Foreign Update on public.bar2
|
|
-> Seq Scan on public.bar
|
|
Output: bar.f1, (bar.f2 + 100), bar.ctid
|
|
-> Foreign Update on public.bar2
|
|
Remote SQL: UPDATE public.loct2 SET f2 = (f2 + 100) RETURNING f1, f2
|
|
(8 rows)
|
|
|
|
update bar set f2 = f2 + 100 returning *;
|
|
f1 | f2
|
|
----+-----
|
|
1 | 311
|
|
2 | 322
|
|
6 | 266
|
|
3 | 333
|
|
4 | 344
|
|
7 | 277
|
|
(6 rows)
|
|
|
|
drop table foo cascade;
|
|
NOTICE: drop cascades to foreign table foo2
|
|
drop table bar cascade;
|
|
NOTICE: drop cascades to foreign table bar2
|
|
drop table loct1;
|
|
drop table loct2;
|
|
-- ===================================================================
|
|
-- test IMPORT FOREIGN SCHEMA
|
|
-- ===================================================================
|
|
CREATE SCHEMA import_source;
|
|
CREATE TABLE import_source.t1 (c1 int, c2 varchar NOT NULL);
|
|
CREATE TABLE import_source.t2 (c1 int default 42, c2 varchar NULL, c3 text collate "POSIX");
|
|
CREATE TYPE typ1 AS (m1 int, m2 varchar);
|
|
CREATE TABLE import_source.t3 (c1 timestamptz default now(), c2 typ1);
|
|
CREATE TABLE import_source."x 4" (c1 float8, "C 2" text, c3 varchar(42));
|
|
CREATE TABLE import_source."x 5" (c1 float8);
|
|
ALTER TABLE import_source."x 5" DROP COLUMN c1;
|
|
CREATE SCHEMA import_dest1;
|
|
IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest1;
|
|
\det+ import_dest1.*
|
|
List of foreign tables
|
|
Schema | Table | Server | FDW Options | Description
|
|
--------------+-------+----------+-------------------------------------------------+-------------
|
|
import_dest1 | t1 | loopback | (schema_name 'import_source', table_name 't1') |
|
|
import_dest1 | t2 | loopback | (schema_name 'import_source', table_name 't2') |
|
|
import_dest1 | t3 | loopback | (schema_name 'import_source', table_name 't3') |
|
|
import_dest1 | x 4 | loopback | (schema_name 'import_source', table_name 'x 4') |
|
|
import_dest1 | x 5 | loopback | (schema_name 'import_source', table_name 'x 5') |
|
|
(5 rows)
|
|
|
|
\d import_dest1.*
|
|
Foreign table "import_dest1.t1"
|
|
Column | Type | Collation | Nullable | Default | FDW Options
|
|
--------+-------------------+-----------+----------+---------+--------------------
|
|
c1 | integer | | | | (column_name 'c1')
|
|
c2 | character varying | | not null | | (column_name 'c2')
|
|
Server: loopback
|
|
FDW Options: (schema_name 'import_source', table_name 't1')
|
|
|
|
Foreign table "import_dest1.t2"
|
|
Column | Type | Collation | Nullable | Default | FDW Options
|
|
--------+-------------------+-----------+----------+---------+--------------------
|
|
c1 | integer | | | | (column_name 'c1')
|
|
c2 | character varying | | | | (column_name 'c2')
|
|
c3 | text | POSIX | | | (column_name 'c3')
|
|
Server: loopback
|
|
FDW Options: (schema_name 'import_source', table_name 't2')
|
|
|
|
Foreign table "import_dest1.t3"
|
|
Column | Type | Collation | Nullable | Default | FDW Options
|
|
--------+--------------------------+-----------+----------+---------+--------------------
|
|
c1 | timestamp with time zone | | | | (column_name 'c1')
|
|
c2 | typ1 | | | | (column_name 'c2')
|
|
Server: loopback
|
|
FDW Options: (schema_name 'import_source', table_name 't3')
|
|
|
|
Foreign table "import_dest1.x 4"
|
|
Column | Type | Collation | Nullable | Default | FDW Options
|
|
--------+-----------------------+-----------+----------+---------+---------------------
|
|
c1 | double precision | | | | (column_name 'c1')
|
|
C 2 | text | | | | (column_name 'C 2')
|
|
c3 | character varying(42) | | | | (column_name 'c3')
|
|
Server: loopback
|
|
FDW Options: (schema_name 'import_source', table_name 'x 4')
|
|
|
|
Foreign table "import_dest1.x 5"
|
|
Column | Type | Collation | Nullable | Default | FDW Options
|
|
--------+------+-----------+----------+---------+-------------
|
|
Server: loopback
|
|
FDW Options: (schema_name 'import_source', table_name 'x 5')
|
|
|
|
-- Options
|
|
CREATE SCHEMA import_dest2;
|
|
IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest2
|
|
OPTIONS (import_default 'true');
|
|
\det+ import_dest2.*
|
|
List of foreign tables
|
|
Schema | Table | Server | FDW Options | Description
|
|
--------------+-------+----------+-------------------------------------------------+-------------
|
|
import_dest2 | t1 | loopback | (schema_name 'import_source', table_name 't1') |
|
|
import_dest2 | t2 | loopback | (schema_name 'import_source', table_name 't2') |
|
|
import_dest2 | t3 | loopback | (schema_name 'import_source', table_name 't3') |
|
|
import_dest2 | x 4 | loopback | (schema_name 'import_source', table_name 'x 4') |
|
|
import_dest2 | x 5 | loopback | (schema_name 'import_source', table_name 'x 5') |
|
|
(5 rows)
|
|
|
|
\d import_dest2.*
|
|
Foreign table "import_dest2.t1"
|
|
Column | Type | Collation | Nullable | Default | FDW Options
|
|
--------+-------------------+-----------+----------+---------+--------------------
|
|
c1 | integer | | | | (column_name 'c1')
|
|
c2 | character varying | | not null | | (column_name 'c2')
|
|
Server: loopback
|
|
FDW Options: (schema_name 'import_source', table_name 't1')
|
|
|
|
Foreign table "import_dest2.t2"
|
|
Column | Type | Collation | Nullable | Default | FDW Options
|
|
--------+-------------------+-----------+----------+---------+--------------------
|
|
c1 | integer | | | 42 | (column_name 'c1')
|
|
c2 | character varying | | | | (column_name 'c2')
|
|
c3 | text | POSIX | | | (column_name 'c3')
|
|
Server: loopback
|
|
FDW Options: (schema_name 'import_source', table_name 't2')
|
|
|
|
Foreign table "import_dest2.t3"
|
|
Column | Type | Collation | Nullable | Default | FDW Options
|
|
--------+--------------------------+-----------+----------+---------+--------------------
|
|
c1 | timestamp with time zone | | | now() | (column_name 'c1')
|
|
c2 | typ1 | | | | (column_name 'c2')
|
|
Server: loopback
|
|
FDW Options: (schema_name 'import_source', table_name 't3')
|
|
|
|
Foreign table "import_dest2.x 4"
|
|
Column | Type | Collation | Nullable | Default | FDW Options
|
|
--------+-----------------------+-----------+----------+---------+---------------------
|
|
c1 | double precision | | | | (column_name 'c1')
|
|
C 2 | text | | | | (column_name 'C 2')
|
|
c3 | character varying(42) | | | | (column_name 'c3')
|
|
Server: loopback
|
|
FDW Options: (schema_name 'import_source', table_name 'x 4')
|
|
|
|
Foreign table "import_dest2.x 5"
|
|
Column | Type | Collation | Nullable | Default | FDW Options
|
|
--------+------+-----------+----------+---------+-------------
|
|
Server: loopback
|
|
FDW Options: (schema_name 'import_source', table_name 'x 5')
|
|
|
|
CREATE SCHEMA import_dest3;
|
|
IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest3
|
|
OPTIONS (import_collate 'false', import_not_null 'false');
|
|
\det+ import_dest3.*
|
|
List of foreign tables
|
|
Schema | Table | Server | FDW Options | Description
|
|
--------------+-------+----------+-------------------------------------------------+-------------
|
|
import_dest3 | t1 | loopback | (schema_name 'import_source', table_name 't1') |
|
|
import_dest3 | t2 | loopback | (schema_name 'import_source', table_name 't2') |
|
|
import_dest3 | t3 | loopback | (schema_name 'import_source', table_name 't3') |
|
|
import_dest3 | x 4 | loopback | (schema_name 'import_source', table_name 'x 4') |
|
|
import_dest3 | x 5 | loopback | (schema_name 'import_source', table_name 'x 5') |
|
|
(5 rows)
|
|
|
|
\d import_dest3.*
|
|
Foreign table "import_dest3.t1"
|
|
Column | Type | Collation | Nullable | Default | FDW Options
|
|
--------+-------------------+-----------+----------+---------+--------------------
|
|
c1 | integer | | | | (column_name 'c1')
|
|
c2 | character varying | | | | (column_name 'c2')
|
|
Server: loopback
|
|
FDW Options: (schema_name 'import_source', table_name 't1')
|
|
|
|
Foreign table "import_dest3.t2"
|
|
Column | Type | Collation | Nullable | Default | FDW Options
|
|
--------+-------------------+-----------+----------+---------+--------------------
|
|
c1 | integer | | | | (column_name 'c1')
|
|
c2 | character varying | | | | (column_name 'c2')
|
|
c3 | text | | | | (column_name 'c3')
|
|
Server: loopback
|
|
FDW Options: (schema_name 'import_source', table_name 't2')
|
|
|
|
Foreign table "import_dest3.t3"
|
|
Column | Type | Collation | Nullable | Default | FDW Options
|
|
--------+--------------------------+-----------+----------+---------+--------------------
|
|
c1 | timestamp with time zone | | | | (column_name 'c1')
|
|
c2 | typ1 | | | | (column_name 'c2')
|
|
Server: loopback
|
|
FDW Options: (schema_name 'import_source', table_name 't3')
|
|
|
|
Foreign table "import_dest3.x 4"
|
|
Column | Type | Collation | Nullable | Default | FDW Options
|
|
--------+-----------------------+-----------+----------+---------+---------------------
|
|
c1 | double precision | | | | (column_name 'c1')
|
|
C 2 | text | | | | (column_name 'C 2')
|
|
c3 | character varying(42) | | | | (column_name 'c3')
|
|
Server: loopback
|
|
FDW Options: (schema_name 'import_source', table_name 'x 4')
|
|
|
|
Foreign table "import_dest3.x 5"
|
|
Column | Type | Collation | Nullable | Default | FDW Options
|
|
--------+------+-----------+----------+---------+-------------
|
|
Server: loopback
|
|
FDW Options: (schema_name 'import_source', table_name 'x 5')
|
|
|
|
-- Check LIMIT TO and EXCEPT
|
|
CREATE SCHEMA import_dest4;
|
|
IMPORT FOREIGN SCHEMA import_source LIMIT TO (t1, nonesuch)
|
|
FROM SERVER loopback INTO import_dest4;
|
|
\det+ import_dest4.*
|
|
List of foreign tables
|
|
Schema | Table | Server | FDW Options | Description
|
|
--------------+-------+----------+------------------------------------------------+-------------
|
|
import_dest4 | t1 | loopback | (schema_name 'import_source', table_name 't1') |
|
|
(1 row)
|
|
|
|
IMPORT FOREIGN SCHEMA import_source EXCEPT (t1, "x 4", nonesuch)
|
|
FROM SERVER loopback INTO import_dest4;
|
|
\det+ import_dest4.*
|
|
List of foreign tables
|
|
Schema | Table | Server | FDW Options | Description
|
|
--------------+-------+----------+-------------------------------------------------+-------------
|
|
import_dest4 | t1 | loopback | (schema_name 'import_source', table_name 't1') |
|
|
import_dest4 | t2 | loopback | (schema_name 'import_source', table_name 't2') |
|
|
import_dest4 | t3 | loopback | (schema_name 'import_source', table_name 't3') |
|
|
import_dest4 | x 5 | loopback | (schema_name 'import_source', table_name 'x 5') |
|
|
(4 rows)
|
|
|
|
-- Assorted error cases
|
|
IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest4;
|
|
ERROR: relation "t1" already exists
|
|
CONTEXT: importing foreign table "t1"
|
|
IMPORT FOREIGN SCHEMA nonesuch FROM SERVER loopback INTO import_dest4;
|
|
ERROR: schema "nonesuch" is not present on foreign server "loopback"
|
|
IMPORT FOREIGN SCHEMA nonesuch FROM SERVER loopback INTO notthere;
|
|
ERROR: schema "notthere" does not exist
|
|
IMPORT FOREIGN SCHEMA nonesuch FROM SERVER nowhere INTO notthere;
|
|
ERROR: server "nowhere" does not exist
|
|
-- Check case of a type present only on the remote server.
|
|
-- We can fake this by dropping the type locally in our transaction.
|
|
CREATE TYPE "Colors" AS ENUM ('red', 'green', 'blue');
|
|
CREATE TABLE import_source.t5 (c1 int, c2 text collate "C", "Col" "Colors");
|
|
CREATE SCHEMA import_dest5;
|
|
BEGIN;
|
|
DROP TYPE "Colors" CASCADE;
|
|
NOTICE: drop cascades to table import_source.t5 column Col
|
|
IMPORT FOREIGN SCHEMA import_source LIMIT TO (t5)
|
|
FROM SERVER loopback INTO import_dest5; -- ERROR
|
|
ERROR: type "public.Colors" does not exist
|
|
LINE 4: "Col" public."Colors" OPTIONS (column_name 'Col')
|
|
^
|
|
QUERY: CREATE FOREIGN TABLE t5 (
|
|
c1 integer OPTIONS (column_name 'c1'),
|
|
c2 text OPTIONS (column_name 'c2') COLLATE pg_catalog."C",
|
|
"Col" public."Colors" OPTIONS (column_name 'Col')
|
|
) SERVER loopback
|
|
OPTIONS (schema_name 'import_source', table_name 't5');
|
|
CONTEXT: importing foreign table "t5"
|
|
ROLLBACK;
|
|
BEGIN;
|
|
CREATE SERVER fetch101 FOREIGN DATA WRAPPER postgres_fdw OPTIONS( fetch_size '101' );
|
|
SELECT count(*)
|
|
FROM pg_foreign_server
|
|
WHERE srvname = 'fetch101'
|
|
AND srvoptions @> array['fetch_size=101'];
|
|
count
|
|
-------
|
|
1
|
|
(1 row)
|
|
|
|
ALTER SERVER fetch101 OPTIONS( SET fetch_size '202' );
|
|
SELECT count(*)
|
|
FROM pg_foreign_server
|
|
WHERE srvname = 'fetch101'
|
|
AND srvoptions @> array['fetch_size=101'];
|
|
count
|
|
-------
|
|
0
|
|
(1 row)
|
|
|
|
SELECT count(*)
|
|
FROM pg_foreign_server
|
|
WHERE srvname = 'fetch101'
|
|
AND srvoptions @> array['fetch_size=202'];
|
|
count
|
|
-------
|
|
1
|
|
(1 row)
|
|
|
|
CREATE FOREIGN TABLE table30000 ( x int ) SERVER fetch101 OPTIONS ( fetch_size '30000' );
|
|
SELECT COUNT(*)
|
|
FROM pg_foreign_table
|
|
WHERE ftrelid = 'table30000'::regclass
|
|
AND ftoptions @> array['fetch_size=30000'];
|
|
count
|
|
-------
|
|
1
|
|
(1 row)
|
|
|
|
ALTER FOREIGN TABLE table30000 OPTIONS ( SET fetch_size '60000');
|
|
SELECT COUNT(*)
|
|
FROM pg_foreign_table
|
|
WHERE ftrelid = 'table30000'::regclass
|
|
AND ftoptions @> array['fetch_size=30000'];
|
|
count
|
|
-------
|
|
0
|
|
(1 row)
|
|
|
|
SELECT COUNT(*)
|
|
FROM pg_foreign_table
|
|
WHERE ftrelid = 'table30000'::regclass
|
|
AND ftoptions @> array['fetch_size=60000'];
|
|
count
|
|
-------
|
|
1
|
|
(1 row)
|
|
|
|
ROLLBACK;
|