mirror of https://github.com/citusdata/citus.git
Merge pull request #1124 from citusdata/mx_worker_tests
MX regression tests for queries from workerspull/1165/head
commit
8a83665ea0
|
@ -37,7 +37,7 @@ output_files := $(patsubst $(citus_abs_srcdir)/output/%.source,expected/%.out, $
|
|||
# intermediate, for muscle memory backward compatibility.
|
||||
check: check-full
|
||||
# check-full triggers all tests that ought to be run routinely
|
||||
check-full: check-multi check-multi-task-tracker-extra check-multi-binary check-worker
|
||||
check-full: check-multi check-multi-mx check-multi-task-tracker-extra check-multi-binary check-worker
|
||||
|
||||
# using pg_regress_multi_check unnecessarily starts up multiple nodes, which isn't needed
|
||||
# for check-worker. But that's harmless besides a few cycles.
|
||||
|
@ -59,6 +59,10 @@ check-isolation: all tempinstall-main
|
|||
|
||||
check-vanilla: all tempinstall-main
|
||||
$(pg_regress_multi_check) --load-extension=citus --vanillatest
|
||||
|
||||
check-multi-mx: all tempinstall-main
|
||||
$(pg_regress_multi_check) --load-extension=citus \
|
||||
-- $(MULTI_REGRESS_OPTS) --schedule=$(citus_abs_srcdir)/multi_mx_schedule $(EXTRA_TESTS)
|
||||
|
||||
check-multi-task-tracker-extra: all tempinstall-main
|
||||
$(pg_regress_multi_check) --load-extension=citus \
|
||||
|
|
|
@ -16,3 +16,4 @@
|
|||
/multi_subquery_0.out
|
||||
/worker_copy.out
|
||||
/multi_complex_count_distinct.out
|
||||
/multi_mx_copy_data.out
|
||||
|
|
|
@ -0,0 +1,496 @@
|
|||
--
|
||||
-- MULTI_MX_CREATE_TABLE
|
||||
--
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1220000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1220000;
|
||||
SELECT start_metadata_sync_to_node('localhost', :worker_1_port);
|
||||
start_metadata_sync_to_node
|
||||
-----------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT start_metadata_sync_to_node('localhost', :worker_2_port);
|
||||
start_metadata_sync_to_node
|
||||
-----------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- create schema to test schema support
|
||||
CREATE SCHEMA citus_mx_test_schema;
|
||||
CREATE SCHEMA citus_mx_test_schema_join_1;
|
||||
CREATE SCHEMA citus_mx_test_schema_join_2;
|
||||
-- create UDFs that we're going to use in our tests
|
||||
SET search_path TO public;
|
||||
CREATE OR REPLACE FUNCTION simpleTestFunction(theValue integer)
|
||||
RETURNS text AS
|
||||
$$
|
||||
DECLARE
|
||||
strresult text;
|
||||
BEGIN
|
||||
RETURN theValue * 3 / 2 + 1;
|
||||
END;
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
SET search_path TO citus_mx_test_schema;
|
||||
CREATE OR REPLACE FUNCTION simpleTestFunction2(theValue integer)
|
||||
RETURNS text AS
|
||||
$$
|
||||
DECLARE
|
||||
strresult text;
|
||||
BEGIN
|
||||
RETURN theValue * 3 / 2 + 1;
|
||||
END;
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
CREATE FUNCTION public.immutable_append_mx(old_values int[], new_value int)
|
||||
RETURNS int[] AS $$ SELECT old_values || new_value $$ LANGUAGE SQL IMMUTABLE;
|
||||
CREATE OPERATOR citus_mx_test_schema.=== (
|
||||
LEFTARG = int,
|
||||
RIGHTARG = int,
|
||||
PROCEDURE = int4eq,
|
||||
COMMUTATOR = ===,
|
||||
NEGATOR = !==,
|
||||
HASHES, MERGES
|
||||
);
|
||||
SET search_path TO public;
|
||||
CREATE COLLATION citus_mx_test_schema.english FROM "en_US";
|
||||
CREATE TYPE citus_mx_test_schema.new_composite_type as (key1 text, key2 text);
|
||||
CREATE TYPE order_side_mx AS ENUM ('buy', 'sell');
|
||||
-- now create required stuff in the worker 1
|
||||
\c - - - :worker_1_port
|
||||
-- create schema to test schema support
|
||||
CREATE SCHEMA citus_mx_test_schema;
|
||||
CREATE SCHEMA citus_mx_test_schema_join_1;
|
||||
CREATE SCHEMA citus_mx_test_schema_join_2;
|
||||
-- create UDFs in worker node
|
||||
CREATE OR REPLACE FUNCTION simpleTestFunction(theValue integer)
|
||||
RETURNS text AS
|
||||
$$
|
||||
DECLARE
|
||||
strresult text;
|
||||
BEGIN
|
||||
RETURN theValue * 3 / 2 + 1;
|
||||
END;
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
SET search_path TO citus_mx_test_schema;
|
||||
CREATE OR REPLACE FUNCTION simpleTestFunction2(theValue integer)
|
||||
RETURNS text AS
|
||||
$$
|
||||
DECLARE
|
||||
strresult text;
|
||||
BEGIN
|
||||
RETURN theValue * 3 / 2 + 1;
|
||||
END;
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
CREATE FUNCTION public.immutable_append_mx(old_values int[], new_value int)
|
||||
RETURNS int[] AS $$ SELECT old_values || new_value $$ LANGUAGE SQL IMMUTABLE;
|
||||
-- create operator
|
||||
CREATE OPERATOR citus_mx_test_schema.=== (
|
||||
LEFTARG = int,
|
||||
RIGHTARG = int,
|
||||
PROCEDURE = int4eq,
|
||||
COMMUTATOR = ===,
|
||||
NEGATOR = !==,
|
||||
HASHES, MERGES
|
||||
);
|
||||
SET search_path TO public;
|
||||
CREATE COLLATION citus_mx_test_schema.english FROM "en_US";
|
||||
SET search_path TO public;
|
||||
CREATE TYPE citus_mx_test_schema.new_composite_type as (key1 text, key2 text);
|
||||
CREATE TYPE order_side_mx AS ENUM ('buy', 'sell');
|
||||
-- now create required stuff in the worker 2
|
||||
\c - - - :worker_2_port
|
||||
-- create schema to test schema support
|
||||
CREATE SCHEMA citus_mx_test_schema;
|
||||
CREATE SCHEMA citus_mx_test_schema_join_1;
|
||||
CREATE SCHEMA citus_mx_test_schema_join_2;
|
||||
-- create UDF
|
||||
CREATE OR REPLACE FUNCTION simpleTestFunction(theValue integer)
|
||||
RETURNS text AS
|
||||
$$
|
||||
DECLARE
|
||||
strresult text;
|
||||
BEGIN
|
||||
RETURN theValue * 3 / 2 + 1;
|
||||
END;
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
SET search_path TO citus_mx_test_schema;
|
||||
CREATE OR REPLACE FUNCTION simpleTestFunction2(theValue integer)
|
||||
RETURNS text AS
|
||||
$$
|
||||
DECLARE
|
||||
strresult text;
|
||||
BEGIN
|
||||
RETURN theValue * 3 / 2 + 1;
|
||||
END;
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
CREATE FUNCTION public.immutable_append_mx(old_values int[], new_value int)
|
||||
RETURNS int[] AS $$ SELECT old_values || new_value $$ LANGUAGE SQL IMMUTABLE;
|
||||
-- create operator
|
||||
CREATE OPERATOR citus_mx_test_schema.=== (
|
||||
LEFTARG = int,
|
||||
RIGHTARG = int,
|
||||
PROCEDURE = int4eq,
|
||||
COMMUTATOR = ===,
|
||||
NEGATOR = !==,
|
||||
HASHES, MERGES
|
||||
);
|
||||
SET search_path TO public;
|
||||
CREATE COLLATION citus_mx_test_schema.english FROM "en_US";
|
||||
SET search_path TO public;
|
||||
CREATE TYPE citus_mx_test_schema.new_composite_type as (key1 text, key2 text);
|
||||
CREATE TYPE order_side_mx AS ENUM ('buy', 'sell');
|
||||
-- connect back to the master, and do some more tests
|
||||
\c - - - :master_port
|
||||
SET citus.shard_replication_factor TO 1;
|
||||
SET citus.replication_model TO streaming;
|
||||
SET search_path TO public;
|
||||
CREATE TABLE nation_hash(
|
||||
n_nationkey integer not null,
|
||||
n_name char(25) not null,
|
||||
n_regionkey integer not null,
|
||||
n_comment varchar(152)
|
||||
);
|
||||
SET citus.shard_count TO 16;
|
||||
SELECT create_distributed_table('nation_hash', 'n_nationkey');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SET search_path TO citus_mx_test_schema;
|
||||
-- create mx tables that we're going to use for our tests
|
||||
CREATE TABLE citus_mx_test_schema.nation_hash(
|
||||
n_nationkey integer not null,
|
||||
n_name char(25) not null,
|
||||
n_regionkey integer not null,
|
||||
n_comment varchar(152)
|
||||
);
|
||||
SELECT create_distributed_table('nation_hash', 'n_nationkey');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
CREATE TABLE citus_mx_test_schema_join_1.nation_hash (
|
||||
n_nationkey integer not null,
|
||||
n_name char(25) not null,
|
||||
n_regionkey integer not null,
|
||||
n_comment varchar(152));
|
||||
SET citus.shard_count TO 4;
|
||||
SELECT create_distributed_table('citus_mx_test_schema_join_1.nation_hash', 'n_nationkey');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
CREATE TABLE citus_mx_test_schema_join_1.nation_hash_2 (
|
||||
n_nationkey integer not null,
|
||||
n_name char(25) not null,
|
||||
n_regionkey integer not null,
|
||||
n_comment varchar(152));
|
||||
SELECT create_distributed_table('citus_mx_test_schema_join_1.nation_hash_2', 'n_nationkey');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SET search_path TO citus_mx_test_schema_join_2;
|
||||
CREATE TABLE nation_hash (
|
||||
n_nationkey integer not null,
|
||||
n_name char(25) not null,
|
||||
n_regionkey integer not null,
|
||||
n_comment varchar(152));
|
||||
SELECT create_distributed_table('nation_hash', 'n_nationkey');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SET search_path TO citus_mx_test_schema;
|
||||
CREATE TABLE nation_hash_collation_search_path(
|
||||
n_nationkey integer not null,
|
||||
n_name char(25) not null COLLATE english,
|
||||
n_regionkey integer not null,
|
||||
n_comment varchar(152)
|
||||
);
|
||||
SELECT create_distributed_table('nation_hash_collation_search_path', 'n_nationkey');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
\COPY nation_hash_collation_search_path FROM STDIN with delimiter '|';
|
||||
CREATE TABLE citus_mx_test_schema.nation_hash_composite_types(
|
||||
n_nationkey integer not null,
|
||||
n_name char(25) not null,
|
||||
n_regionkey integer not null,
|
||||
n_comment varchar(152),
|
||||
test_col citus_mx_test_schema.new_composite_type
|
||||
);
|
||||
SELECT create_distributed_table('citus_mx_test_schema.nation_hash_composite_types', 'n_nationkey');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- insert some data to verify composite type queries
|
||||
\COPY citus_mx_test_schema.nation_hash_composite_types FROM STDIN with delimiter '|';
|
||||
-- now create tpch tables
|
||||
-- Create new table definitions for use in testing in distributed planning and
|
||||
-- execution functionality. Also create indexes to boost performance.
|
||||
SET search_path TO public;
|
||||
CREATE TABLE lineitem_mx (
|
||||
l_orderkey bigint not null,
|
||||
l_partkey integer not null,
|
||||
l_suppkey integer not null,
|
||||
l_linenumber integer not null,
|
||||
l_quantity decimal(15, 2) not null,
|
||||
l_extendedprice decimal(15, 2) not null,
|
||||
l_discount decimal(15, 2) not null,
|
||||
l_tax decimal(15, 2) not null,
|
||||
l_returnflag char(1) not null,
|
||||
l_linestatus char(1) not null,
|
||||
l_shipdate date not null,
|
||||
l_commitdate date not null,
|
||||
l_receiptdate date not null,
|
||||
l_shipinstruct char(25) not null,
|
||||
l_shipmode char(10) not null,
|
||||
l_comment varchar(44) not null,
|
||||
PRIMARY KEY(l_orderkey, l_linenumber) );
|
||||
SET citus.shard_count TO 16;
|
||||
SELECT create_distributed_table('lineitem_mx', 'l_orderkey');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
CREATE INDEX lineitem_mx_time_index ON lineitem_mx (l_shipdate);
|
||||
NOTICE: using one-phase commit for distributed DDL commands
|
||||
HINT: You can enable two-phase commit for extra safety with: SET citus.multi_shard_commit_protocol TO '2pc'
|
||||
CREATE TABLE orders_mx (
|
||||
o_orderkey bigint not null,
|
||||
o_custkey integer not null,
|
||||
o_orderstatus char(1) not null,
|
||||
o_totalprice decimal(15,2) not null,
|
||||
o_orderdate date not null,
|
||||
o_orderpriority char(15) not null,
|
||||
o_clerk char(15) not null,
|
||||
o_shippriority integer not null,
|
||||
o_comment varchar(79) not null,
|
||||
PRIMARY KEY(o_orderkey) );
|
||||
SELECT create_distributed_table('orders_mx', 'o_orderkey');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
CREATE TABLE customer_mx (
|
||||
c_custkey integer not null,
|
||||
c_name varchar(25) not null,
|
||||
c_address varchar(40) not null,
|
||||
c_nationkey integer not null,
|
||||
c_phone char(15) not null,
|
||||
c_acctbal decimal(15,2) not null,
|
||||
c_mktsegment char(10) not null,
|
||||
c_comment varchar(117) not null);
|
||||
SET citus.shard_count TO 1;
|
||||
SELECT create_distributed_table('customer_mx', 'c_custkey');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
CREATE TABLE nation_mx (
|
||||
n_nationkey integer not null,
|
||||
n_name char(25) not null,
|
||||
n_regionkey integer not null,
|
||||
n_comment varchar(152));
|
||||
SELECT create_distributed_table('nation_mx', 'n_nationkey');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
CREATE TABLE part_mx (
|
||||
p_partkey integer not null,
|
||||
p_name varchar(55) not null,
|
||||
p_mfgr char(25) not null,
|
||||
p_brand char(10) not null,
|
||||
p_type varchar(25) not null,
|
||||
p_size integer not null,
|
||||
p_container char(10) not null,
|
||||
p_retailprice decimal(15,2) not null,
|
||||
p_comment varchar(23) not null);
|
||||
SELECT create_distributed_table('part_mx', 'p_partkey');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
CREATE TABLE supplier_mx
|
||||
(
|
||||
s_suppkey integer not null,
|
||||
s_name char(25) not null,
|
||||
s_address varchar(40) not null,
|
||||
s_nationkey integer,
|
||||
s_phone char(15) not null,
|
||||
s_acctbal decimal(15,2) not null,
|
||||
s_comment varchar(101) not null
|
||||
);
|
||||
SELECT create_distributed_table('supplier_mx', 's_suppkey');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- Create test table for ddl
|
||||
CREATE TABLE mx_ddl_table (
|
||||
key int primary key,
|
||||
value int
|
||||
);
|
||||
SET citus.shard_count TO 4;
|
||||
SELECT create_distributed_table('mx_ddl_table', 'key', 'hash');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- Load some test data
|
||||
COPY mx_ddl_table (key, value) FROM STDIN WITH (FORMAT 'csv');
|
||||
-- test table for modifications
|
||||
CREATE TABLE limit_orders_mx (
|
||||
id bigint PRIMARY KEY,
|
||||
symbol text NOT NULL,
|
||||
bidder_id bigint NOT NULL,
|
||||
placed_at timestamp NOT NULL,
|
||||
kind order_side_mx NOT NULL,
|
||||
limit_price decimal NOT NULL DEFAULT 0.00 CHECK (limit_price >= 0.00)
|
||||
);
|
||||
SET citus.shard_count TO 2;
|
||||
SELECT create_distributed_table('limit_orders_mx', 'id');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- test table for modifications
|
||||
CREATE TABLE multiple_hash_mx (
|
||||
category text NOT NULL,
|
||||
data text NOT NULL
|
||||
);
|
||||
SELECT create_distributed_table('multiple_hash_mx', 'category');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SET citus.shard_count TO 4;
|
||||
CREATE TABLE app_analytics_events_mx (id bigserial, app_id integer, name text);
|
||||
SELECT create_distributed_table('app_analytics_events_mx', 'app_id');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
CREATE TABLE researchers_mx (
|
||||
id bigint NOT NULL,
|
||||
lab_id int NOT NULL,
|
||||
name text NOT NULL
|
||||
);
|
||||
SET citus.shard_count TO 2;
|
||||
SELECT create_distributed_table('researchers_mx', 'lab_id');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
CREATE TABLE labs_mx (
|
||||
id bigint NOT NULL,
|
||||
name text NOT NULL
|
||||
);
|
||||
SET citus.shard_count TO 1;
|
||||
SELECT create_distributed_table('labs_mx', 'id');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- now, for some special failures...
|
||||
CREATE TABLE objects_mx (
|
||||
id bigint PRIMARY KEY,
|
||||
name text NOT NULL
|
||||
);
|
||||
SELECT create_distributed_table('objects_mx', 'id', 'hash');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
CREATE TABLE articles_hash_mx (
|
||||
id bigint NOT NULL,
|
||||
author_id bigint NOT NULL,
|
||||
title varchar(20) NOT NULL,
|
||||
word_count integer
|
||||
);
|
||||
-- this table is used in router executor tests
|
||||
CREATE TABLE articles_single_shard_hash_mx (LIKE articles_hash_mx);
|
||||
SET citus.shard_count TO 2;
|
||||
SELECT create_distributed_table('articles_hash_mx', 'author_id');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SET citus.shard_count TO 1;
|
||||
SELECT create_distributed_table('articles_single_shard_hash_mx', 'author_id');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SET citus.shard_count TO 4;
|
||||
CREATE TABLE company_employees_mx (company_id int, employee_id int, manager_id int);
|
||||
SELECT create_distributed_table('company_employees_mx', 'company_id');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
WITH shard_counts AS (
|
||||
SELECT logicalrelid, count(*) AS shard_count FROM pg_dist_shard GROUP BY logicalrelid
|
||||
)
|
||||
SELECT logicalrelid, colocationid, shard_count, partmethod, repmodel
|
||||
FROM pg_dist_partition NATURAL JOIN shard_counts
|
||||
ORDER BY colocationid, logicalrelid;
|
||||
logicalrelid | colocationid | shard_count | partmethod | repmodel
|
||||
--------------------------------------------------------+--------------+-------------+------------+----------
|
||||
nation_hash | 2 | 16 | h | s
|
||||
citus_mx_test_schema.nation_hash | 2 | 16 | h | s
|
||||
citus_mx_test_schema_join_1.nation_hash | 3 | 4 | h | s
|
||||
citus_mx_test_schema_join_1.nation_hash_2 | 3 | 4 | h | s
|
||||
citus_mx_test_schema_join_2.nation_hash | 3 | 4 | h | s
|
||||
citus_mx_test_schema.nation_hash_collation_search_path | 3 | 4 | h | s
|
||||
citus_mx_test_schema.nation_hash_composite_types | 3 | 4 | h | s
|
||||
mx_ddl_table | 3 | 4 | h | s
|
||||
app_analytics_events_mx | 3 | 4 | h | s
|
||||
company_employees_mx | 3 | 4 | h | s
|
||||
lineitem_mx | 4 | 16 | h | s
|
||||
orders_mx | 4 | 16 | h | s
|
||||
customer_mx | 5 | 1 | h | s
|
||||
nation_mx | 5 | 1 | h | s
|
||||
part_mx | 5 | 1 | h | s
|
||||
supplier_mx | 5 | 1 | h | s
|
||||
limit_orders_mx | 6 | 2 | h | s
|
||||
articles_hash_mx | 6 | 2 | h | s
|
||||
multiple_hash_mx | 7 | 2 | h | s
|
||||
researchers_mx | 8 | 2 | h | s
|
||||
labs_mx | 9 | 1 | h | s
|
||||
objects_mx | 9 | 1 | h | s
|
||||
articles_single_shard_hash_mx | 9 | 1 | h | s
|
||||
(23 rows)
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
-- Tests related to distributed DDL commands on mx cluster
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1600000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1600000;
|
||||
SELECT * FROM mx_ddl_table ORDER BY key;
|
||||
key | value
|
||||
-----+-------
|
||||
1 | 10
|
||||
2 | 11
|
||||
3 | 21
|
||||
4 | 37
|
||||
5 | 60
|
||||
6 | 100
|
||||
10 | 200
|
||||
11 | 230
|
||||
(8 rows)
|
||||
|
||||
-- CREATE INDEX
|
||||
CREATE INDEX ddl_test_index ON mx_ddl_table(value);
|
||||
NOTICE: using one-phase commit for distributed DDL commands
|
||||
HINT: You can enable two-phase commit for extra safety with: SET citus.multi_shard_commit_protocol TO '2pc'
|
||||
-- ADD COLUMN
|
||||
ALTER TABLE mx_ddl_table ADD COLUMN version INTEGER;
|
||||
-- SET DEFAULT
|
||||
ALTER TABLE mx_ddl_table ALTER COLUMN version SET DEFAULT 1;
|
||||
SELECT master_modify_multiple_shards('UPDATE mx_ddl_table SET version=0.1 WHERE version IS NULL');
|
||||
master_modify_multiple_shards
|
||||
-------------------------------
|
||||
8
|
||||
(1 row)
|
||||
|
||||
-- SET NOT NULL
|
||||
ALTER TABLE mx_ddl_table ALTER COLUMN version SET NOT NULL;
|
||||
-- See that the changes are applied on schema node, worker tables and shards
|
||||
\d mx_ddl_table
|
||||
Table "public.mx_ddl_table"
|
||||
Column | Type | Modifiers
|
||||
---------+---------+--------------------
|
||||
key | integer | not null
|
||||
value | integer |
|
||||
version | integer | not null default 1
|
||||
Indexes:
|
||||
"mx_ddl_table_pkey" PRIMARY KEY, btree (key)
|
||||
"ddl_test_index" btree (value)
|
||||
|
||||
\c - - - :worker_1_port
|
||||
\d mx_ddl_table
|
||||
Table "public.mx_ddl_table"
|
||||
Column | Type | Modifiers
|
||||
---------+---------+--------------------
|
||||
key | integer | not null
|
||||
value | integer |
|
||||
version | integer | not null default 1
|
||||
Indexes:
|
||||
"mx_ddl_table_pkey" PRIMARY KEY, btree (key)
|
||||
"ddl_test_index" btree (value)
|
||||
|
||||
\d mx_ddl_table_1600000
|
||||
\c - - - :worker_2_port
|
||||
\d mx_ddl_table
|
||||
Table "public.mx_ddl_table"
|
||||
Column | Type | Modifiers
|
||||
---------+---------+--------------------
|
||||
key | integer | not null
|
||||
value | integer |
|
||||
version | integer | not null default 1
|
||||
Indexes:
|
||||
"mx_ddl_table_pkey" PRIMARY KEY, btree (key)
|
||||
"ddl_test_index" btree (value)
|
||||
|
||||
\d mx_ddl_table_1600001
|
||||
INSERT INTO mx_ddl_table VALUES (37, 78, 2);
|
||||
INSERT INTO mx_ddl_table VALUES (38, 78);
|
||||
-- Switch to the schema node
|
||||
\c - - - :master_port
|
||||
-- SET DATA TYPE
|
||||
ALTER TABLE mx_ddl_table ALTER COLUMN version SET DATA TYPE double precision;
|
||||
NOTICE: using one-phase commit for distributed DDL commands
|
||||
HINT: You can enable two-phase commit for extra safety with: SET citus.multi_shard_commit_protocol TO '2pc'
|
||||
INSERT INTO mx_ddl_table VALUES (78, 83, 2.1);
|
||||
\c - - - :worker_1_port
|
||||
SELECT * FROM mx_ddl_table ORDER BY key;
|
||||
key | value | version
|
||||
-----+-------+---------
|
||||
1 | 10 | 0
|
||||
2 | 11 | 0
|
||||
3 | 21 | 0
|
||||
4 | 37 | 0
|
||||
5 | 60 | 0
|
||||
6 | 100 | 0
|
||||
10 | 200 | 0
|
||||
11 | 230 | 0
|
||||
37 | 78 | 2
|
||||
38 | 78 | 1
|
||||
78 | 83 | 2.1
|
||||
(11 rows)
|
||||
|
||||
-- Switch to the schema node
|
||||
\c - - - :master_port
|
||||
-- DROP INDEX
|
||||
DROP INDEX ddl_test_index;
|
||||
NOTICE: using one-phase commit for distributed DDL commands
|
||||
HINT: You can enable two-phase commit for extra safety with: SET citus.multi_shard_commit_protocol TO '2pc'
|
||||
-- DROP DEFAULT
|
||||
ALTER TABLE mx_ddl_table ALTER COLUMN version DROP DEFAULT;
|
||||
-- DROP NOT NULL
|
||||
ALTER TABLE mx_ddl_table ALTER COLUMN version DROP NOT NULL;
|
||||
-- DROP COLUMN
|
||||
ALTER TABLE mx_ddl_table DROP COLUMN version;
|
||||
-- See that the changes are applied on schema node, worker tables and shards
|
||||
\d mx_ddl_table
|
||||
Table "public.mx_ddl_table"
|
||||
Column | Type | Modifiers
|
||||
--------+---------+-----------
|
||||
key | integer | not null
|
||||
value | integer |
|
||||
Indexes:
|
||||
"mx_ddl_table_pkey" PRIMARY KEY, btree (key)
|
||||
|
||||
\c - - - :worker_1_port
|
||||
\d mx_ddl_table
|
||||
Table "public.mx_ddl_table"
|
||||
Column | Type | Modifiers
|
||||
--------+---------+-----------
|
||||
key | integer | not null
|
||||
value | integer |
|
||||
Indexes:
|
||||
"mx_ddl_table_pkey" PRIMARY KEY, btree (key)
|
||||
|
||||
\d mx_ddl_table_1600000
|
||||
\c - - - :worker_2_port
|
||||
\d mx_ddl_table
|
||||
Table "public.mx_ddl_table"
|
||||
Column | Type | Modifiers
|
||||
--------+---------+-----------
|
||||
key | integer | not null
|
||||
value | integer |
|
||||
Indexes:
|
||||
"mx_ddl_table_pkey" PRIMARY KEY, btree (key)
|
||||
|
||||
\d mx_ddl_table_1600001
|
||||
-- Show that DDL commands are done within a two-phase commit transaction
|
||||
\c - - - :master_port
|
||||
SET client_min_messages TO debug2;
|
||||
CREATE INDEX ddl_test_index ON mx_ddl_table(value);
|
||||
NOTICE: using one-phase commit for distributed DDL commands
|
||||
HINT: You can enable two-phase commit for extra safety with: SET citus.multi_shard_commit_protocol TO '2pc'
|
||||
DEBUG: building index "ddl_test_index" on table "mx_ddl_table"
|
||||
RESET client_min_messages;
|
||||
DROP INDEX ddl_test_index;
|
||||
-- show that sequences owned by mx tables result in unique values
|
||||
SET citus.shard_replication_factor TO 1;
|
||||
SET citus.shard_count TO 4;
|
||||
SET citus.replication_model TO streaming;
|
||||
CREATE TABLE mx_sequence(key INT, value BIGSERIAL);
|
||||
SELECT create_distributed_table('mx_sequence', 'key');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
\c - - - :worker_1_port
|
||||
SELECT groupid FROM pg_dist_local_group;
|
||||
groupid
|
||||
---------
|
||||
14
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM mx_sequence_value_seq;
|
||||
sequence_name | last_value | start_value | increment_by | max_value | min_value | cache_value | log_cnt | is_cycled | is_called
|
||||
-----------------------+------------------+------------------+--------------+------------------+------------------+-------------+---------+-----------+-----------
|
||||
mx_sequence_value_seq | 3940649673949185 | 3940649673949185 | 1 | 4222124650659841 | 3940649673949185 | 1 | 0 | f | f
|
||||
(1 row)
|
||||
|
||||
\c - - - :worker_2_port
|
||||
SELECT groupid FROM pg_dist_local_group;
|
||||
groupid
|
||||
---------
|
||||
16
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM mx_sequence_value_seq;
|
||||
sequence_name | last_value | start_value | increment_by | max_value | min_value | cache_value | log_cnt | is_cycled | is_called
|
||||
-----------------------+------------------+------------------+--------------+------------------+------------------+-------------+---------+-----------+-----------
|
||||
mx_sequence_value_seq | 4503599627370497 | 4503599627370497 | 1 | 4785074604081153 | 4503599627370497 | 1 | 0 | f | f
|
||||
(1 row)
|
||||
|
||||
\c - - - :master_port
|
||||
-- the type of sequences can't be changed
|
||||
ALTER TABLE mx_sequence ALTER value TYPE BIGINT;
|
||||
NOTICE: using one-phase commit for distributed DDL commands
|
||||
HINT: You can enable two-phase commit for extra safety with: SET citus.multi_shard_commit_protocol TO '2pc'
|
||||
ALTER TABLE mx_sequence ALTER value TYPE INT;
|
|
@ -0,0 +1,709 @@
|
|||
--
|
||||
-- MULTI_MX_EXPLAIN
|
||||
--
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1320000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1320000;
|
||||
\c - - - :worker_1_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1320000;
|
||||
\c - - - :worker_2_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1320000;
|
||||
\c - - - :master_port
|
||||
\a\t
|
||||
SET citus.task_executor_type TO 'real-time';
|
||||
SET citus.explain_distributed_queries TO on;
|
||||
\c - - - :worker_1_port
|
||||
-- Function that parses explain output as JSON
|
||||
CREATE FUNCTION explain_json(query text)
|
||||
RETURNS jsonb
|
||||
AS $BODY$
|
||||
DECLARE
|
||||
result jsonb;
|
||||
BEGIN
|
||||
EXECUTE format('EXPLAIN (FORMAT JSON) %s', query) INTO result;
|
||||
RETURN result;
|
||||
END;
|
||||
$BODY$ LANGUAGE plpgsql;
|
||||
-- Function that parses explain output as XML
|
||||
CREATE FUNCTION explain_xml(query text)
|
||||
RETURNS xml
|
||||
AS $BODY$
|
||||
DECLARE
|
||||
result xml;
|
||||
BEGIN
|
||||
EXECUTE format('EXPLAIN (FORMAT XML) %s', query) INTO result;
|
||||
RETURN result;
|
||||
END;
|
||||
$BODY$ LANGUAGE plpgsql;
|
||||
\c - - - :worker_2_port
|
||||
-- Function that parses explain output as JSON
|
||||
CREATE FUNCTION explain_json(query text)
|
||||
RETURNS jsonb
|
||||
AS $BODY$
|
||||
DECLARE
|
||||
result jsonb;
|
||||
BEGIN
|
||||
EXECUTE format('EXPLAIN (FORMAT JSON) %s', query) INTO result;
|
||||
RETURN result;
|
||||
END;
|
||||
$BODY$ LANGUAGE plpgsql;
|
||||
-- Function that parses explain output as XML
|
||||
CREATE FUNCTION explain_xml(query text)
|
||||
RETURNS xml
|
||||
AS $BODY$
|
||||
DECLARE
|
||||
result xml;
|
||||
BEGIN
|
||||
EXECUTE format('EXPLAIN (FORMAT XML) %s', query) INTO result;
|
||||
RETURN result;
|
||||
END;
|
||||
$BODY$ LANGUAGE plpgsql;
|
||||
-- Test Text format
|
||||
EXPLAIN (COSTS FALSE, FORMAT TEXT)
|
||||
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
||||
Distributed Query into pg_merge_job_68720796736
|
||||
Executor: Real-Time
|
||||
Task Count: 16
|
||||
Tasks Shown: One of 16
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> HashAggregate
|
||||
Group Key: l_quantity
|
||||
-> Seq Scan on lineitem_mx_1220052 lineitem_mx
|
||||
Master Query
|
||||
-> Sort
|
||||
Sort Key: COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(intermediate_column_68720796736_1))::bigint, '0'::bigint))))::bigint, '0'::bigint), intermediate_column_68720796736_0
|
||||
-> HashAggregate
|
||||
Group Key: intermediate_column_68720796736_0
|
||||
-> Seq Scan on pg_merge_job_68720796736
|
||||
-- Test JSON format
|
||||
EXPLAIN (COSTS FALSE, FORMAT JSON)
|
||||
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
||||
[
|
||||
{
|
||||
"Executor": "Real-Time",
|
||||
"Job": {
|
||||
"Task Count": 16,
|
||||
"Tasks Shown": "One of 16",
|
||||
"Tasks": [
|
||||
{
|
||||
"Node": "host=localhost port=57637 dbname=regression",
|
||||
"Remote Plan": [
|
||||
[
|
||||
{
|
||||
"Plan": {
|
||||
"Node Type": "Aggregate",
|
||||
"Strategy": "Hashed",
|
||||
"Partial Mode": "Simple",
|
||||
"Parallel Aware": false,
|
||||
"Group Key": ["l_quantity"],
|
||||
"Plans": [
|
||||
{
|
||||
"Node Type": "Seq Scan",
|
||||
"Parent Relationship": "Outer",
|
||||
"Parallel Aware": false,
|
||||
"Relation Name": "lineitem_mx_1220052",
|
||||
"Alias": "lineitem_mx"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"Master Query": [
|
||||
{
|
||||
"Plan": {
|
||||
"Node Type": "Sort",
|
||||
"Parallel Aware": false,
|
||||
"Sort Key": ["COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(intermediate_column_68720796737_1))::bigint, '0'::bigint))))::bigint, '0'::bigint)", "intermediate_column_68720796737_0"],
|
||||
"Plans": [
|
||||
{
|
||||
"Node Type": "Aggregate",
|
||||
"Strategy": "Hashed",
|
||||
"Partial Mode": "Simple",
|
||||
"Parent Relationship": "Outer",
|
||||
"Parallel Aware": false,
|
||||
"Group Key": ["intermediate_column_68720796737_0"],
|
||||
"Plans": [
|
||||
{
|
||||
"Node Type": "Seq Scan",
|
||||
"Parent Relationship": "Outer",
|
||||
"Parallel Aware": false,
|
||||
"Relation Name": "pg_merge_job_68720796737",
|
||||
"Alias": "pg_merge_job_68720796737"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
-- Validate JSON format
|
||||
SELECT true AS valid FROM explain_json($$
|
||||
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity$$);
|
||||
t
|
||||
\c - - - :worker_1_port
|
||||
-- Test XML format
|
||||
EXPLAIN (COSTS FALSE, FORMAT XML)
|
||||
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
||||
<explain xmlns="http://www.postgresql.org/2009/explain">
|
||||
<Distributed-Query>
|
||||
<Executor>Real-Time</Executor>
|
||||
<Job>
|
||||
<Task-Count>16</Task-Count>
|
||||
<Tasks-Shown>One of 16</Tasks-Shown>
|
||||
<Tasks>
|
||||
<Task>
|
||||
<Node>host=localhost port=57637 dbname=regression</Node>
|
||||
<Remote-Plan>
|
||||
<explain xmlns="http://www.postgresql.org/2009/explain">
|
||||
<Query>
|
||||
<Plan>
|
||||
<Node-Type>Aggregate</Node-Type>
|
||||
<Strategy>Hashed</Strategy>
|
||||
<Partial-Mode>Simple</Partial-Mode>
|
||||
<Parallel-Aware>false</Parallel-Aware>
|
||||
<Group-Key>
|
||||
<Item>l_quantity</Item>
|
||||
</Group-Key>
|
||||
<Plans>
|
||||
<Plan>
|
||||
<Node-Type>Seq Scan</Node-Type>
|
||||
<Parent-Relationship>Outer</Parent-Relationship>
|
||||
<Parallel-Aware>false</Parallel-Aware>
|
||||
<Relation-Name>lineitem_mx_1220052</Relation-Name>
|
||||
<Alias>lineitem_mx</Alias>
|
||||
</Plan>
|
||||
</Plans>
|
||||
</Plan>
|
||||
</Query>
|
||||
</explain>
|
||||
</Remote-Plan>
|
||||
</Task>
|
||||
</Tasks>
|
||||
</Job>
|
||||
<Master-Query>
|
||||
<Query>
|
||||
<Plan>
|
||||
<Node-Type>Sort</Node-Type>
|
||||
<Parallel-Aware>false</Parallel-Aware>
|
||||
<Sort-Key>
|
||||
<Item>COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(intermediate_column_60130862144_1))::bigint, '0'::bigint))))::bigint, '0'::bigint)</Item>
|
||||
<Item>intermediate_column_60130862144_0</Item>
|
||||
</Sort-Key>
|
||||
<Plans>
|
||||
<Plan>
|
||||
<Node-Type>Aggregate</Node-Type>
|
||||
<Strategy>Hashed</Strategy>
|
||||
<Partial-Mode>Simple</Partial-Mode>
|
||||
<Parent-Relationship>Outer</Parent-Relationship>
|
||||
<Parallel-Aware>false</Parallel-Aware>
|
||||
<Group-Key>
|
||||
<Item>intermediate_column_60130862144_0</Item>
|
||||
</Group-Key>
|
||||
<Plans>
|
||||
<Plan>
|
||||
<Node-Type>Seq Scan</Node-Type>
|
||||
<Parent-Relationship>Outer</Parent-Relationship>
|
||||
<Parallel-Aware>false</Parallel-Aware>
|
||||
<Relation-Name>pg_merge_job_60130862144</Relation-Name>
|
||||
<Alias>pg_merge_job_60130862144</Alias>
|
||||
</Plan>
|
||||
</Plans>
|
||||
</Plan>
|
||||
</Plans>
|
||||
</Plan>
|
||||
</Query>
|
||||
</Master-Query>
|
||||
</Distributed-Query>
|
||||
</explain>
|
||||
-- Validate XML format
|
||||
SELECT true AS valid FROM explain_xml($$
|
||||
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity$$);
|
||||
t
|
||||
-- Test YAML format
|
||||
EXPLAIN (COSTS FALSE, FORMAT YAML)
|
||||
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
||||
- Executor: "Real-Time"
|
||||
Job:
|
||||
Task Count: 16
|
||||
Tasks Shown: "One of 16"
|
||||
Tasks:
|
||||
- Node: "host=localhost port=57637 dbname=regression"
|
||||
Remote Plan:
|
||||
- Plan:
|
||||
Node Type: "Aggregate"
|
||||
Strategy: "Hashed"
|
||||
Partial Mode: "Simple"
|
||||
Parallel Aware: false
|
||||
Group Key:
|
||||
- "l_quantity"
|
||||
Plans:
|
||||
- Node Type: "Seq Scan"
|
||||
Parent Relationship: "Outer"
|
||||
Parallel Aware: false
|
||||
Relation Name: "lineitem_mx_1220052"
|
||||
Alias: "lineitem_mx"
|
||||
|
||||
Master Query:
|
||||
- Plan:
|
||||
Node Type: "Sort"
|
||||
Parallel Aware: false
|
||||
Sort Key:
|
||||
- "COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(intermediate_column_60130862146_1))::bigint, '0'::bigint))))::bigint, '0'::bigint)"
|
||||
- "intermediate_column_60130862146_0"
|
||||
Plans:
|
||||
- Node Type: "Aggregate"
|
||||
Strategy: "Hashed"
|
||||
Partial Mode: "Simple"
|
||||
Parent Relationship: "Outer"
|
||||
Parallel Aware: false
|
||||
Group Key:
|
||||
- "intermediate_column_60130862146_0"
|
||||
Plans:
|
||||
- Node Type: "Seq Scan"
|
||||
Parent Relationship: "Outer"
|
||||
Parallel Aware: false
|
||||
Relation Name: "pg_merge_job_60130862146"
|
||||
Alias: "pg_merge_job_60130862146"
|
||||
-- Test Text format
|
||||
EXPLAIN (COSTS FALSE, FORMAT TEXT)
|
||||
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
||||
Distributed Query into pg_merge_job_60130862147
|
||||
Executor: Real-Time
|
||||
Task Count: 16
|
||||
Tasks Shown: One of 16
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> HashAggregate
|
||||
Group Key: l_quantity
|
||||
-> Seq Scan on lineitem_mx_1220052 lineitem_mx
|
||||
Master Query
|
||||
-> Sort
|
||||
Sort Key: COALESCE((pg_catalog.sum((COALESCE((pg_catalog.sum(intermediate_column_60130862147_1))::bigint, '0'::bigint))))::bigint, '0'::bigint), intermediate_column_60130862147_0
|
||||
-> HashAggregate
|
||||
Group Key: intermediate_column_60130862147_0
|
||||
-> Seq Scan on pg_merge_job_60130862147
|
||||
\c - - - :worker_2_port
|
||||
-- Test verbose
|
||||
EXPLAIN (COSTS FALSE, VERBOSE TRUE)
|
||||
SELECT sum(l_quantity) / avg(l_quantity) FROM lineitem_mx;
|
||||
Distributed Query into pg_merge_job_68720796739
|
||||
Executor: Real-Time
|
||||
Task Count: 16
|
||||
Tasks Shown: One of 16
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Aggregate
|
||||
Output: sum(l_quantity), sum(l_quantity), count(l_quantity)
|
||||
-> Seq Scan on public.lineitem_mx_1220052 lineitem_mx
|
||||
Output: l_orderkey, l_partkey, l_suppkey, l_linenumber, l_quantity, l_extendedprice, l_discount, l_tax, l_returnflag, l_linestatus, l_shipdate, l_commitdate, l_receiptdate, l_shipinstruct, l_shipmode, l_comment
|
||||
Master Query
|
||||
-> Aggregate
|
||||
Output: (sum(intermediate_column_68720796739_0) / (sum(intermediate_column_68720796739_1) / pg_catalog.sum(intermediate_column_68720796739_2)))
|
||||
-> Seq Scan on pg_temp_2.pg_merge_job_68720796739
|
||||
Output: intermediate_column_68720796739_0, intermediate_column_68720796739_1, intermediate_column_68720796739_2
|
||||
-- Test join
|
||||
EXPLAIN (COSTS FALSE)
|
||||
SELECT * FROM lineitem_mx
|
||||
JOIN orders_mx ON l_orderkey = o_orderkey AND l_quantity < 5.0
|
||||
ORDER BY l_quantity LIMIT 10;
|
||||
Distributed Query into pg_merge_job_68720796740
|
||||
Executor: Real-Time
|
||||
Task Count: 16
|
||||
Tasks Shown: One of 16
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Limit
|
||||
-> Sort
|
||||
Sort Key: lineitem_mx.l_quantity
|
||||
-> Hash Join
|
||||
Hash Cond: (lineitem_mx.l_orderkey = orders_mx.o_orderkey)
|
||||
-> Seq Scan on lineitem_mx_1220052 lineitem_mx
|
||||
Filter: (l_quantity < 5.0)
|
||||
-> Hash
|
||||
-> Seq Scan on orders_mx_1220068 orders_mx
|
||||
Master Query
|
||||
-> Limit
|
||||
-> Sort
|
||||
Sort Key: intermediate_column_68720796740_4
|
||||
-> Seq Scan on pg_merge_job_68720796740
|
||||
-- Test insert
|
||||
EXPLAIN (COSTS FALSE)
|
||||
INSERT INTO lineitem_mx VALUES(1,0);
|
||||
Distributed Query
|
||||
Executor: Router
|
||||
Task Count: 1
|
||||
Tasks Shown: All
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Insert on lineitem_mx_1220052
|
||||
-> Result
|
||||
-- Test update
|
||||
EXPLAIN (COSTS FALSE)
|
||||
UPDATE lineitem_mx
|
||||
SET l_suppkey = 12
|
||||
WHERE l_orderkey = 1 AND l_partkey = 0;
|
||||
Distributed Query
|
||||
Executor: Router
|
||||
Task Count: 1
|
||||
Tasks Shown: All
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Update on lineitem_mx_1220052
|
||||
-> Index Scan using lineitem_mx_pkey_1220052 on lineitem_mx_1220052
|
||||
Index Cond: (l_orderkey = 1)
|
||||
Filter: (l_partkey = 0)
|
||||
-- Test delete
|
||||
EXPLAIN (COSTS FALSE)
|
||||
DELETE FROM lineitem_mx
|
||||
WHERE l_orderkey = 1 AND l_partkey = 0;
|
||||
Distributed Query
|
||||
Executor: Router
|
||||
Task Count: 1
|
||||
Tasks Shown: All
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Delete on lineitem_mx_1220052
|
||||
-> Index Scan using lineitem_mx_pkey_1220052 on lineitem_mx_1220052
|
||||
Index Cond: (l_orderkey = 1)
|
||||
Filter: (l_partkey = 0)
|
||||
-- Test single-shard SELECT
|
||||
EXPLAIN (COSTS FALSE)
|
||||
SELECT l_quantity FROM lineitem_mx WHERE l_orderkey = 5;
|
||||
Distributed Query
|
||||
Executor: Router
|
||||
Task Count: 1
|
||||
Tasks Shown: All
|
||||
-> Task
|
||||
Node: host=localhost port=57638 dbname=regression
|
||||
-> Bitmap Heap Scan on lineitem_mx_1220055 lineitem_mx
|
||||
Recheck Cond: (l_orderkey = 5)
|
||||
-> Bitmap Index Scan on lineitem_mx_pkey_1220055
|
||||
Index Cond: (l_orderkey = 5)
|
||||
SELECT true AS valid FROM explain_xml($$
|
||||
SELECT l_quantity FROM lineitem_mx WHERE l_orderkey = 5$$);
|
||||
t
|
||||
SELECT true AS valid FROM explain_json($$
|
||||
SELECT l_quantity FROM lineitem_mx WHERE l_orderkey = 5$$);
|
||||
t
|
||||
-- Test CREATE TABLE ... AS
|
||||
EXPLAIN (COSTS FALSE)
|
||||
CREATE TABLE explain_result AS
|
||||
SELECT * FROM lineitem_mx;
|
||||
Distributed Query into pg_merge_job_68720796741
|
||||
Executor: Real-Time
|
||||
Task Count: 16
|
||||
Tasks Shown: One of 16
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Seq Scan on lineitem_mx_1220052 lineitem_mx
|
||||
Master Query
|
||||
-> Seq Scan on pg_merge_job_68720796741
|
||||
-- Test all tasks output
|
||||
SET citus.explain_all_tasks TO on;
|
||||
EXPLAIN (COSTS FALSE)
|
||||
SELECT avg(l_linenumber) FROM lineitem_mx WHERE l_orderkey > 9030;
|
||||
Distributed Query into pg_merge_job_68720796742
|
||||
Executor: Real-Time
|
||||
Task Count: 16
|
||||
Tasks Shown: All
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220052 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57638 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220053 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220054 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57638 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220055 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220056 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57638 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220057 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220058 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57638 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220059 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220060 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57638 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220061 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220062 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57638 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220063 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220064 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57638 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220065 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220066 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57638 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220067 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
Master Query
|
||||
-> Aggregate
|
||||
-> Seq Scan on pg_merge_job_68720796742
|
||||
SELECT true AS valid FROM explain_xml($$
|
||||
SELECT avg(l_linenumber) FROM lineitem_mx WHERE l_orderkey > 9030$$);
|
||||
t
|
||||
SELECT true AS valid FROM explain_json($$
|
||||
SELECT avg(l_linenumber) FROM lineitem_mx WHERE l_orderkey > 9030$$);
|
||||
t
|
||||
-- Test track tracker
|
||||
SET citus.task_executor_type TO 'task-tracker';
|
||||
SET citus.explain_all_tasks TO off;
|
||||
EXPLAIN (COSTS FALSE)
|
||||
SELECT avg(l_linenumber) FROM lineitem_mx WHERE l_orderkey > 9030;
|
||||
Distributed Query into pg_merge_job_68720796745
|
||||
Executor: Task-Tracker
|
||||
Task Count: 16
|
||||
Tasks Shown: One of 16
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220052 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
Master Query
|
||||
-> Aggregate
|
||||
-> Seq Scan on pg_merge_job_68720796745
|
||||
-- Test re-partition join
|
||||
SET citus.large_table_shard_count TO 1;
|
||||
EXPLAIN (COSTS FALSE)
|
||||
SELECT count(*)
|
||||
FROM lineitem_mx, orders_mx, customer_mx, supplier_mx
|
||||
WHERE l_orderkey = o_orderkey
|
||||
AND o_custkey = c_custkey
|
||||
AND l_suppkey = s_suppkey;
|
||||
Distributed Query into pg_merge_job_68720796750
|
||||
Executor: Task-Tracker
|
||||
Task Count: 4
|
||||
Tasks Shown: None, not supported for re-partition queries
|
||||
-> MapMergeJob
|
||||
Map Task Count: 4
|
||||
Merge Task Count: 4
|
||||
-> MapMergeJob
|
||||
Map Task Count: 16
|
||||
Merge Task Count: 4
|
||||
-> MapMergeJob
|
||||
Map Task Count: 1
|
||||
Merge Task Count: 4
|
||||
-> MapMergeJob
|
||||
Map Task Count: 1
|
||||
Merge Task Count: 4
|
||||
Master Query
|
||||
-> Aggregate
|
||||
-> Seq Scan on pg_merge_job_68720796750
|
||||
EXPLAIN (COSTS FALSE, FORMAT JSON)
|
||||
SELECT count(*)
|
||||
FROM lineitem_mx, orders_mx, customer_mx, supplier_mx
|
||||
WHERE l_orderkey = o_orderkey
|
||||
AND o_custkey = c_custkey
|
||||
AND l_suppkey = s_suppkey;
|
||||
[
|
||||
{
|
||||
"Executor": "Task-Tracker",
|
||||
"Job": {
|
||||
"Task Count": 4,
|
||||
"Tasks Shown": "None, not supported for re-partition queries",
|
||||
"Depended Jobs": [
|
||||
{
|
||||
"Map Task Count": 4,
|
||||
"Merge Task Count": 4,
|
||||
"Depended Jobs": [
|
||||
{
|
||||
"Map Task Count": 16,
|
||||
"Merge Task Count": 4
|
||||
},
|
||||
{
|
||||
"Map Task Count": 1,
|
||||
"Merge Task Count": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Map Task Count": 1,
|
||||
"Merge Task Count": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
"Master Query": [
|
||||
{
|
||||
"Plan": {
|
||||
"Node Type": "Aggregate",
|
||||
"Strategy": "Plain",
|
||||
"Partial Mode": "Simple",
|
||||
"Parallel Aware": false,
|
||||
"Plans": [
|
||||
{
|
||||
"Node Type": "Seq Scan",
|
||||
"Parent Relationship": "Outer",
|
||||
"Parallel Aware": false,
|
||||
"Relation Name": "pg_merge_job_68720796755",
|
||||
"Alias": "pg_merge_job_68720796755"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
SELECT true AS valid FROM explain_json($$
|
||||
SELECT count(*)
|
||||
FROM lineitem_mx, orders_mx, customer_mx, supplier_mx
|
||||
WHERE l_orderkey = o_orderkey
|
||||
AND o_custkey = c_custkey
|
||||
AND l_suppkey = s_suppkey$$);
|
||||
t
|
||||
EXPLAIN (COSTS FALSE, FORMAT XML)
|
||||
SELECT count(*)
|
||||
FROM lineitem_mx, orders_mx, customer_mx, supplier_mx
|
||||
WHERE l_orderkey = o_orderkey
|
||||
AND o_custkey = c_custkey
|
||||
AND l_suppkey = s_suppkey;
|
||||
<explain xmlns="http://www.postgresql.org/2009/explain">
|
||||
<Distributed-Query>
|
||||
<Executor>Task-Tracker</Executor>
|
||||
<Job>
|
||||
<Task-Count>4</Task-Count>
|
||||
<Tasks-Shown>None, not supported for re-partition queries</Tasks-Shown>
|
||||
<Depended-Jobs>
|
||||
<MapMergeJob>
|
||||
<Map-Task-Count>4</Map-Task-Count>
|
||||
<Merge-Task-Count>4</Merge-Task-Count>
|
||||
<Depended-Jobs>
|
||||
<MapMergeJob>
|
||||
<Map-Task-Count>16</Map-Task-Count>
|
||||
<Merge-Task-Count>4</Merge-Task-Count>
|
||||
</MapMergeJob>
|
||||
<MapMergeJob>
|
||||
<Map-Task-Count>1</Map-Task-Count>
|
||||
<Merge-Task-Count>4</Merge-Task-Count>
|
||||
</MapMergeJob>
|
||||
</Depended-Jobs>
|
||||
</MapMergeJob>
|
||||
<MapMergeJob>
|
||||
<Map-Task-Count>1</Map-Task-Count>
|
||||
<Merge-Task-Count>4</Merge-Task-Count>
|
||||
</MapMergeJob>
|
||||
</Depended-Jobs>
|
||||
</Job>
|
||||
<Master-Query>
|
||||
<Query>
|
||||
<Plan>
|
||||
<Node-Type>Aggregate</Node-Type>
|
||||
<Strategy>Plain</Strategy>
|
||||
<Partial-Mode>Simple</Partial-Mode>
|
||||
<Parallel-Aware>false</Parallel-Aware>
|
||||
<Plans>
|
||||
<Plan>
|
||||
<Node-Type>Seq Scan</Node-Type>
|
||||
<Parent-Relationship>Outer</Parent-Relationship>
|
||||
<Parallel-Aware>false</Parallel-Aware>
|
||||
<Relation-Name>pg_merge_job_68720796765</Relation-Name>
|
||||
<Alias>pg_merge_job_68720796765</Alias>
|
||||
</Plan>
|
||||
</Plans>
|
||||
</Plan>
|
||||
</Query>
|
||||
</Master-Query>
|
||||
</Distributed-Query>
|
||||
</explain>
|
||||
SELECT true AS valid FROM explain_xml($$
|
||||
SELECT count(*)
|
||||
FROM lineitem_mx, orders_mx, customer_mx, supplier_mx
|
||||
WHERE l_orderkey = o_orderkey
|
||||
AND o_custkey = c_custkey
|
||||
AND l_suppkey = s_suppkey$$);
|
||||
t
|
||||
EXPLAIN (COSTS FALSE, FORMAT YAML)
|
||||
SELECT count(*)
|
||||
FROM lineitem_mx, orders_mx, customer_mx, supplier_mx
|
||||
WHERE l_orderkey = o_orderkey
|
||||
AND o_custkey = c_custkey
|
||||
AND l_suppkey = s_suppkey;
|
||||
- Executor: "Task-Tracker"
|
||||
Job:
|
||||
Task Count: 4
|
||||
Tasks Shown: "None, not supported for re-partition queries"
|
||||
Depended Jobs:
|
||||
- Map Task Count: 4
|
||||
Merge Task Count: 4
|
||||
Depended Jobs:
|
||||
- Map Task Count: 16
|
||||
Merge Task Count: 4
|
||||
- Map Task Count: 1
|
||||
Merge Task Count: 4
|
||||
- Map Task Count: 1
|
||||
Merge Task Count: 4
|
||||
Master Query:
|
||||
- Plan:
|
||||
Node Type: "Aggregate"
|
||||
Strategy: "Plain"
|
||||
Partial Mode: "Simple"
|
||||
Parallel Aware: false
|
||||
Plans:
|
||||
- Node Type: "Seq Scan"
|
||||
Parent Relationship: "Outer"
|
||||
Parallel Aware: false
|
||||
Relation Name: "pg_merge_job_68720796775"
|
||||
Alias: "pg_merge_job_68720796775"
|
|
@ -0,0 +1,679 @@
|
|||
--
|
||||
-- MULTI_MX_EXPLAIN
|
||||
--
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1320000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1320000;
|
||||
\c - - - :worker_1_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1320000;
|
||||
\c - - - :worker_2_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1320000;
|
||||
\c - - - :master_port
|
||||
\a\t
|
||||
SET citus.task_executor_type TO 'real-time';
|
||||
SET citus.explain_distributed_queries TO on;
|
||||
\c - - - :worker_1_port
|
||||
-- Function that parses explain output as JSON
|
||||
CREATE FUNCTION explain_json(query text)
|
||||
RETURNS jsonb
|
||||
AS $BODY$
|
||||
DECLARE
|
||||
result jsonb;
|
||||
BEGIN
|
||||
EXECUTE format('EXPLAIN (FORMAT JSON) %s', query) INTO result;
|
||||
RETURN result;
|
||||
END;
|
||||
$BODY$ LANGUAGE plpgsql;
|
||||
-- Function that parses explain output as XML
|
||||
CREATE FUNCTION explain_xml(query text)
|
||||
RETURNS xml
|
||||
AS $BODY$
|
||||
DECLARE
|
||||
result xml;
|
||||
BEGIN
|
||||
EXECUTE format('EXPLAIN (FORMAT XML) %s', query) INTO result;
|
||||
RETURN result;
|
||||
END;
|
||||
$BODY$ LANGUAGE plpgsql;
|
||||
\c - - - :worker_2_port
|
||||
-- Function that parses explain output as JSON
|
||||
CREATE FUNCTION explain_json(query text)
|
||||
RETURNS jsonb
|
||||
AS $BODY$
|
||||
DECLARE
|
||||
result jsonb;
|
||||
BEGIN
|
||||
EXECUTE format('EXPLAIN (FORMAT JSON) %s', query) INTO result;
|
||||
RETURN result;
|
||||
END;
|
||||
$BODY$ LANGUAGE plpgsql;
|
||||
-- Function that parses explain output as XML
|
||||
CREATE FUNCTION explain_xml(query text)
|
||||
RETURNS xml
|
||||
AS $BODY$
|
||||
DECLARE
|
||||
result xml;
|
||||
BEGIN
|
||||
EXECUTE format('EXPLAIN (FORMAT XML) %s', query) INTO result;
|
||||
RETURN result;
|
||||
END;
|
||||
$BODY$ LANGUAGE plpgsql;
|
||||
-- Test Text format
|
||||
EXPLAIN (COSTS FALSE, FORMAT TEXT)
|
||||
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
||||
Distributed Query into pg_merge_job_68720796736
|
||||
Executor: Real-Time
|
||||
Task Count: 16
|
||||
Tasks Shown: One of 16
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> HashAggregate
|
||||
Group Key: l_quantity
|
||||
-> Seq Scan on lineitem_mx_1220052 lineitem_mx
|
||||
Master Query
|
||||
-> Sort
|
||||
Sort Key: COALESCE((sum((COALESCE((sum(intermediate_column_68720796736_1))::bigint, '0'::bigint))))::bigint, '0'::bigint), intermediate_column_68720796736_0
|
||||
-> HashAggregate
|
||||
Group Key: intermediate_column_68720796736_0
|
||||
-> Seq Scan on pg_merge_job_68720796736
|
||||
-- Test JSON format
|
||||
EXPLAIN (COSTS FALSE, FORMAT JSON)
|
||||
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
||||
[
|
||||
{
|
||||
"Executor": "Real-Time",
|
||||
"Job": {
|
||||
"Task Count": 16,
|
||||
"Tasks Shown": "One of 16",
|
||||
"Tasks": [
|
||||
{
|
||||
"Node": "host=localhost port=57637 dbname=regression",
|
||||
"Remote Plan": [
|
||||
[
|
||||
{
|
||||
"Plan": {
|
||||
"Node Type": "Aggregate",
|
||||
"Strategy": "Hashed",
|
||||
"Group Key": ["l_quantity"],
|
||||
"Plans": [
|
||||
{
|
||||
"Node Type": "Seq Scan",
|
||||
"Parent Relationship": "Outer",
|
||||
"Relation Name": "lineitem_mx_1220052",
|
||||
"Alias": "lineitem_mx"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"Master Query": [
|
||||
{
|
||||
"Plan": {
|
||||
"Node Type": "Sort",
|
||||
"Sort Key": ["COALESCE((sum((COALESCE((sum(intermediate_column_68720796737_1))::bigint, '0'::bigint))))::bigint, '0'::bigint)", "intermediate_column_68720796737_0"],
|
||||
"Plans": [
|
||||
{
|
||||
"Node Type": "Aggregate",
|
||||
"Strategy": "Hashed",
|
||||
"Parent Relationship": "Outer",
|
||||
"Group Key": ["intermediate_column_68720796737_0"],
|
||||
"Plans": [
|
||||
{
|
||||
"Node Type": "Seq Scan",
|
||||
"Parent Relationship": "Outer",
|
||||
"Relation Name": "pg_merge_job_68720796737",
|
||||
"Alias": "pg_merge_job_68720796737"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
-- Validate JSON format
|
||||
SELECT true AS valid FROM explain_json($$
|
||||
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity$$);
|
||||
t
|
||||
\c - - - :worker_1_port
|
||||
-- Test XML format
|
||||
EXPLAIN (COSTS FALSE, FORMAT XML)
|
||||
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
||||
<explain xmlns="http://www.postgresql.org/2009/explain">
|
||||
<Distributed-Query>
|
||||
<Executor>Real-Time</Executor>
|
||||
<Job>
|
||||
<Task-Count>16</Task-Count>
|
||||
<Tasks-Shown>One of 16</Tasks-Shown>
|
||||
<Tasks>
|
||||
<Task>
|
||||
<Node>host=localhost port=57637 dbname=regression</Node>
|
||||
<Remote-Plan>
|
||||
<explain xmlns="http://www.postgresql.org/2009/explain">
|
||||
<Query>
|
||||
<Plan>
|
||||
<Node-Type>Aggregate</Node-Type>
|
||||
<Strategy>Hashed</Strategy>
|
||||
<Group-Key>
|
||||
<Item>l_quantity</Item>
|
||||
</Group-Key>
|
||||
<Plans>
|
||||
<Plan>
|
||||
<Node-Type>Seq Scan</Node-Type>
|
||||
<Parent-Relationship>Outer</Parent-Relationship>
|
||||
<Relation-Name>lineitem_mx_1220052</Relation-Name>
|
||||
<Alias>lineitem_mx</Alias>
|
||||
</Plan>
|
||||
</Plans>
|
||||
</Plan>
|
||||
</Query>
|
||||
</explain>
|
||||
</Remote-Plan>
|
||||
</Task>
|
||||
</Tasks>
|
||||
</Job>
|
||||
<Master-Query>
|
||||
<Query>
|
||||
<Plan>
|
||||
<Node-Type>Sort</Node-Type>
|
||||
<Sort-Key>
|
||||
<Item>COALESCE((sum((COALESCE((sum(intermediate_column_60130862144_1))::bigint, '0'::bigint))))::bigint, '0'::bigint)</Item>
|
||||
<Item>intermediate_column_60130862144_0</Item>
|
||||
</Sort-Key>
|
||||
<Plans>
|
||||
<Plan>
|
||||
<Node-Type>Aggregate</Node-Type>
|
||||
<Strategy>Hashed</Strategy>
|
||||
<Parent-Relationship>Outer</Parent-Relationship>
|
||||
<Group-Key>
|
||||
<Item>intermediate_column_60130862144_0</Item>
|
||||
</Group-Key>
|
||||
<Plans>
|
||||
<Plan>
|
||||
<Node-Type>Seq Scan</Node-Type>
|
||||
<Parent-Relationship>Outer</Parent-Relationship>
|
||||
<Relation-Name>pg_merge_job_60130862144</Relation-Name>
|
||||
<Alias>pg_merge_job_60130862144</Alias>
|
||||
</Plan>
|
||||
</Plans>
|
||||
</Plan>
|
||||
</Plans>
|
||||
</Plan>
|
||||
</Query>
|
||||
</Master-Query>
|
||||
</Distributed-Query>
|
||||
</explain>
|
||||
-- Validate XML format
|
||||
SELECT true AS valid FROM explain_xml($$
|
||||
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity$$);
|
||||
t
|
||||
-- Test YAML format
|
||||
EXPLAIN (COSTS FALSE, FORMAT YAML)
|
||||
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
||||
- Executor: "Real-Time"
|
||||
Job:
|
||||
Task Count: 16
|
||||
Tasks Shown: "One of 16"
|
||||
Tasks:
|
||||
- Node: "host=localhost port=57637 dbname=regression"
|
||||
Remote Plan:
|
||||
- Plan:
|
||||
Node Type: "Aggregate"
|
||||
Strategy: "Hashed"
|
||||
Group Key:
|
||||
- "l_quantity"
|
||||
Plans:
|
||||
- Node Type: "Seq Scan"
|
||||
Parent Relationship: "Outer"
|
||||
Relation Name: "lineitem_mx_1220052"
|
||||
Alias: "lineitem_mx"
|
||||
|
||||
Master Query:
|
||||
- Plan:
|
||||
Node Type: "Sort"
|
||||
Sort Key:
|
||||
- "COALESCE((sum((COALESCE((sum(intermediate_column_60130862146_1))::bigint, '0'::bigint))))::bigint, '0'::bigint)"
|
||||
- "intermediate_column_60130862146_0"
|
||||
Plans:
|
||||
- Node Type: "Aggregate"
|
||||
Strategy: "Hashed"
|
||||
Parent Relationship: "Outer"
|
||||
Group Key:
|
||||
- "intermediate_column_60130862146_0"
|
||||
Plans:
|
||||
- Node Type: "Seq Scan"
|
||||
Parent Relationship: "Outer"
|
||||
Relation Name: "pg_merge_job_60130862146"
|
||||
Alias: "pg_merge_job_60130862146"
|
||||
-- Test Text format
|
||||
EXPLAIN (COSTS FALSE, FORMAT TEXT)
|
||||
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
||||
Distributed Query into pg_merge_job_60130862147
|
||||
Executor: Real-Time
|
||||
Task Count: 16
|
||||
Tasks Shown: One of 16
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> HashAggregate
|
||||
Group Key: l_quantity
|
||||
-> Seq Scan on lineitem_mx_1220052 lineitem_mx
|
||||
Master Query
|
||||
-> Sort
|
||||
Sort Key: COALESCE((sum((COALESCE((sum(intermediate_column_60130862147_1))::bigint, '0'::bigint))))::bigint, '0'::bigint), intermediate_column_60130862147_0
|
||||
-> HashAggregate
|
||||
Group Key: intermediate_column_60130862147_0
|
||||
-> Seq Scan on pg_merge_job_60130862147
|
||||
\c - - - :worker_2_port
|
||||
-- Test verbose
|
||||
EXPLAIN (COSTS FALSE, VERBOSE TRUE)
|
||||
SELECT sum(l_quantity) / avg(l_quantity) FROM lineitem_mx;
|
||||
Distributed Query into pg_merge_job_68720796739
|
||||
Executor: Real-Time
|
||||
Task Count: 16
|
||||
Tasks Shown: One of 16
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Aggregate
|
||||
Output: sum(l_quantity), sum(l_quantity), count(l_quantity)
|
||||
-> Seq Scan on public.lineitem_mx_1220052 lineitem_mx
|
||||
Output: l_orderkey, l_partkey, l_suppkey, l_linenumber, l_quantity, l_extendedprice, l_discount, l_tax, l_returnflag, l_linestatus, l_shipdate, l_commitdate, l_receiptdate, l_shipinstruct, l_shipmode, l_comment
|
||||
Master Query
|
||||
-> Aggregate
|
||||
Output: (sum(intermediate_column_68720796739_0) / (sum(intermediate_column_68720796739_1) / sum(intermediate_column_68720796739_2)))
|
||||
-> Seq Scan on pg_temp_2.pg_merge_job_68720796739
|
||||
Output: intermediate_column_68720796739_0, intermediate_column_68720796739_1, intermediate_column_68720796739_2
|
||||
-- Test join
|
||||
EXPLAIN (COSTS FALSE)
|
||||
SELECT * FROM lineitem_mx
|
||||
JOIN orders_mx ON l_orderkey = o_orderkey AND l_quantity < 5.0
|
||||
ORDER BY l_quantity LIMIT 10;
|
||||
Distributed Query into pg_merge_job_68720796740
|
||||
Executor: Real-Time
|
||||
Task Count: 16
|
||||
Tasks Shown: One of 16
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Limit
|
||||
-> Sort
|
||||
Sort Key: lineitem_mx.l_quantity
|
||||
-> Hash Join
|
||||
Hash Cond: (lineitem_mx.l_orderkey = orders_mx.o_orderkey)
|
||||
-> Seq Scan on lineitem_mx_1220052 lineitem_mx
|
||||
Filter: (l_quantity < 5.0)
|
||||
-> Hash
|
||||
-> Seq Scan on orders_mx_1220068 orders_mx
|
||||
Master Query
|
||||
-> Limit
|
||||
-> Sort
|
||||
Sort Key: intermediate_column_68720796740_4
|
||||
-> Seq Scan on pg_merge_job_68720796740
|
||||
-- Test insert
|
||||
EXPLAIN (COSTS FALSE)
|
||||
INSERT INTO lineitem_mx VALUES(1,0);
|
||||
Distributed Query
|
||||
Executor: Router
|
||||
Task Count: 1
|
||||
Tasks Shown: All
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Insert on lineitem_mx_1220052
|
||||
-> Result
|
||||
-- Test update
|
||||
EXPLAIN (COSTS FALSE)
|
||||
UPDATE lineitem_mx
|
||||
SET l_suppkey = 12
|
||||
WHERE l_orderkey = 1 AND l_partkey = 0;
|
||||
Distributed Query
|
||||
Executor: Router
|
||||
Task Count: 1
|
||||
Tasks Shown: All
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Update on lineitem_mx_1220052
|
||||
-> Index Scan using lineitem_mx_pkey_1220052 on lineitem_mx_1220052
|
||||
Index Cond: (l_orderkey = 1)
|
||||
Filter: (l_partkey = 0)
|
||||
-- Test delete
|
||||
EXPLAIN (COSTS FALSE)
|
||||
DELETE FROM lineitem_mx
|
||||
WHERE l_orderkey = 1 AND l_partkey = 0;
|
||||
Distributed Query
|
||||
Executor: Router
|
||||
Task Count: 1
|
||||
Tasks Shown: All
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Delete on lineitem_mx_1220052
|
||||
-> Index Scan using lineitem_mx_pkey_1220052 on lineitem_mx_1220052
|
||||
Index Cond: (l_orderkey = 1)
|
||||
Filter: (l_partkey = 0)
|
||||
-- Test single-shard SELECT
|
||||
EXPLAIN (COSTS FALSE)
|
||||
SELECT l_quantity FROM lineitem_mx WHERE l_orderkey = 5;
|
||||
Distributed Query
|
||||
Executor: Router
|
||||
Task Count: 1
|
||||
Tasks Shown: All
|
||||
-> Task
|
||||
Node: host=localhost port=57638 dbname=regression
|
||||
-> Bitmap Heap Scan on lineitem_mx_1220055 lineitem_mx
|
||||
Recheck Cond: (l_orderkey = 5)
|
||||
-> Bitmap Index Scan on lineitem_mx_pkey_1220055
|
||||
Index Cond: (l_orderkey = 5)
|
||||
SELECT true AS valid FROM explain_xml($$
|
||||
SELECT l_quantity FROM lineitem_mx WHERE l_orderkey = 5$$);
|
||||
t
|
||||
SELECT true AS valid FROM explain_json($$
|
||||
SELECT l_quantity FROM lineitem_mx WHERE l_orderkey = 5$$);
|
||||
t
|
||||
-- Test CREATE TABLE ... AS
|
||||
EXPLAIN (COSTS FALSE)
|
||||
CREATE TABLE explain_result AS
|
||||
SELECT * FROM lineitem_mx;
|
||||
Distributed Query into pg_merge_job_68720796741
|
||||
Executor: Real-Time
|
||||
Task Count: 16
|
||||
Tasks Shown: One of 16
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Seq Scan on lineitem_mx_1220052 lineitem_mx
|
||||
Master Query
|
||||
-> Seq Scan on pg_merge_job_68720796741
|
||||
-- Test all tasks output
|
||||
SET citus.explain_all_tasks TO on;
|
||||
EXPLAIN (COSTS FALSE)
|
||||
SELECT avg(l_linenumber) FROM lineitem_mx WHERE l_orderkey > 9030;
|
||||
Distributed Query into pg_merge_job_68720796742
|
||||
Executor: Real-Time
|
||||
Task Count: 16
|
||||
Tasks Shown: All
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220052 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57638 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220053 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220054 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57638 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220055 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220056 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57638 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220057 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220058 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57638 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220059 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220060 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57638 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220061 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220062 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57638 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220063 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220064 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57638 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220065 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220066 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
-> Task
|
||||
Node: host=localhost port=57638 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220067 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
Master Query
|
||||
-> Aggregate
|
||||
-> Seq Scan on pg_merge_job_68720796742
|
||||
SELECT true AS valid FROM explain_xml($$
|
||||
SELECT avg(l_linenumber) FROM lineitem_mx WHERE l_orderkey > 9030$$);
|
||||
t
|
||||
SELECT true AS valid FROM explain_json($$
|
||||
SELECT avg(l_linenumber) FROM lineitem_mx WHERE l_orderkey > 9030$$);
|
||||
t
|
||||
-- Test track tracker
|
||||
SET citus.task_executor_type TO 'task-tracker';
|
||||
SET citus.explain_all_tasks TO off;
|
||||
EXPLAIN (COSTS FALSE)
|
||||
SELECT avg(l_linenumber) FROM lineitem_mx WHERE l_orderkey > 9030;
|
||||
Distributed Query into pg_merge_job_68720796745
|
||||
Executor: Task-Tracker
|
||||
Task Count: 16
|
||||
Tasks Shown: One of 16
|
||||
-> Task
|
||||
Node: host=localhost port=57637 dbname=regression
|
||||
-> Aggregate
|
||||
-> Seq Scan on lineitem_mx_1220052 lineitem_mx
|
||||
Filter: (l_orderkey > 9030)
|
||||
Master Query
|
||||
-> Aggregate
|
||||
-> Seq Scan on pg_merge_job_68720796745
|
||||
-- Test re-partition join
|
||||
SET citus.large_table_shard_count TO 1;
|
||||
EXPLAIN (COSTS FALSE)
|
||||
SELECT count(*)
|
||||
FROM lineitem_mx, orders_mx, customer_mx, supplier_mx
|
||||
WHERE l_orderkey = o_orderkey
|
||||
AND o_custkey = c_custkey
|
||||
AND l_suppkey = s_suppkey;
|
||||
Distributed Query into pg_merge_job_68720796750
|
||||
Executor: Task-Tracker
|
||||
Task Count: 4
|
||||
Tasks Shown: None, not supported for re-partition queries
|
||||
-> MapMergeJob
|
||||
Map Task Count: 4
|
||||
Merge Task Count: 4
|
||||
-> MapMergeJob
|
||||
Map Task Count: 16
|
||||
Merge Task Count: 4
|
||||
-> MapMergeJob
|
||||
Map Task Count: 1
|
||||
Merge Task Count: 4
|
||||
-> MapMergeJob
|
||||
Map Task Count: 1
|
||||
Merge Task Count: 4
|
||||
Master Query
|
||||
-> Aggregate
|
||||
-> Seq Scan on pg_merge_job_68720796750
|
||||
EXPLAIN (COSTS FALSE, FORMAT JSON)
|
||||
SELECT count(*)
|
||||
FROM lineitem_mx, orders_mx, customer_mx, supplier_mx
|
||||
WHERE l_orderkey = o_orderkey
|
||||
AND o_custkey = c_custkey
|
||||
AND l_suppkey = s_suppkey;
|
||||
[
|
||||
{
|
||||
"Executor": "Task-Tracker",
|
||||
"Job": {
|
||||
"Task Count": 4,
|
||||
"Tasks Shown": "None, not supported for re-partition queries",
|
||||
"Depended Jobs": [
|
||||
{
|
||||
"Map Task Count": 4,
|
||||
"Merge Task Count": 4,
|
||||
"Depended Jobs": [
|
||||
{
|
||||
"Map Task Count": 16,
|
||||
"Merge Task Count": 4
|
||||
},
|
||||
{
|
||||
"Map Task Count": 1,
|
||||
"Merge Task Count": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Map Task Count": 1,
|
||||
"Merge Task Count": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
"Master Query": [
|
||||
{
|
||||
"Plan": {
|
||||
"Node Type": "Aggregate",
|
||||
"Strategy": "Plain",
|
||||
"Plans": [
|
||||
{
|
||||
"Node Type": "Seq Scan",
|
||||
"Parent Relationship": "Outer",
|
||||
"Relation Name": "pg_merge_job_68720796755",
|
||||
"Alias": "pg_merge_job_68720796755"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
SELECT true AS valid FROM explain_json($$
|
||||
SELECT count(*)
|
||||
FROM lineitem_mx, orders_mx, customer_mx, supplier_mx
|
||||
WHERE l_orderkey = o_orderkey
|
||||
AND o_custkey = c_custkey
|
||||
AND l_suppkey = s_suppkey$$);
|
||||
t
|
||||
EXPLAIN (COSTS FALSE, FORMAT XML)
|
||||
SELECT count(*)
|
||||
FROM lineitem_mx, orders_mx, customer_mx, supplier_mx
|
||||
WHERE l_orderkey = o_orderkey
|
||||
AND o_custkey = c_custkey
|
||||
AND l_suppkey = s_suppkey;
|
||||
<explain xmlns="http://www.postgresql.org/2009/explain">
|
||||
<Distributed-Query>
|
||||
<Executor>Task-Tracker</Executor>
|
||||
<Job>
|
||||
<Task-Count>4</Task-Count>
|
||||
<Tasks-Shown>None, not supported for re-partition queries</Tasks-Shown>
|
||||
<Depended-Jobs>
|
||||
<MapMergeJob>
|
||||
<Map-Task-Count>4</Map-Task-Count>
|
||||
<Merge-Task-Count>4</Merge-Task-Count>
|
||||
<Depended-Jobs>
|
||||
<MapMergeJob>
|
||||
<Map-Task-Count>16</Map-Task-Count>
|
||||
<Merge-Task-Count>4</Merge-Task-Count>
|
||||
</MapMergeJob>
|
||||
<MapMergeJob>
|
||||
<Map-Task-Count>1</Map-Task-Count>
|
||||
<Merge-Task-Count>4</Merge-Task-Count>
|
||||
</MapMergeJob>
|
||||
</Depended-Jobs>
|
||||
</MapMergeJob>
|
||||
<MapMergeJob>
|
||||
<Map-Task-Count>1</Map-Task-Count>
|
||||
<Merge-Task-Count>4</Merge-Task-Count>
|
||||
</MapMergeJob>
|
||||
</Depended-Jobs>
|
||||
</Job>
|
||||
<Master-Query>
|
||||
<Query>
|
||||
<Plan>
|
||||
<Node-Type>Aggregate</Node-Type>
|
||||
<Strategy>Plain</Strategy>
|
||||
<Plans>
|
||||
<Plan>
|
||||
<Node-Type>Seq Scan</Node-Type>
|
||||
<Parent-Relationship>Outer</Parent-Relationship>
|
||||
<Relation-Name>pg_merge_job_68720796765</Relation-Name>
|
||||
<Alias>pg_merge_job_68720796765</Alias>
|
||||
</Plan>
|
||||
</Plans>
|
||||
</Plan>
|
||||
</Query>
|
||||
</Master-Query>
|
||||
</Distributed-Query>
|
||||
</explain>
|
||||
SELECT true AS valid FROM explain_xml($$
|
||||
SELECT count(*)
|
||||
FROM lineitem_mx, orders_mx, customer_mx, supplier_mx
|
||||
WHERE l_orderkey = o_orderkey
|
||||
AND o_custkey = c_custkey
|
||||
AND l_suppkey = s_suppkey$$);
|
||||
t
|
||||
EXPLAIN (COSTS FALSE, FORMAT YAML)
|
||||
SELECT count(*)
|
||||
FROM lineitem_mx, orders_mx, customer_mx, supplier_mx
|
||||
WHERE l_orderkey = o_orderkey
|
||||
AND o_custkey = c_custkey
|
||||
AND l_suppkey = s_suppkey;
|
||||
- Executor: "Task-Tracker"
|
||||
Job:
|
||||
Task Count: 4
|
||||
Tasks Shown: "None, not supported for re-partition queries"
|
||||
Depended Jobs:
|
||||
- Map Task Count: 4
|
||||
Merge Task Count: 4
|
||||
Depended Jobs:
|
||||
- Map Task Count: 16
|
||||
Merge Task Count: 4
|
||||
- Map Task Count: 1
|
||||
Merge Task Count: 4
|
||||
- Map Task Count: 1
|
||||
Merge Task Count: 4
|
||||
Master Query:
|
||||
- Plan:
|
||||
Node Type: "Aggregate"
|
||||
Strategy: "Plain"
|
||||
Plans:
|
||||
- Node Type: "Seq Scan"
|
||||
Parent Relationship: "Outer"
|
||||
Relation Name: "pg_merge_job_68720796775"
|
||||
Alias: "pg_merge_job_68720796775"
|
|
@ -0,0 +1,269 @@
|
|||
-- Test creation of mx tables and metadata syncing
|
||||
-- get rid of the previously created entries in pg_dist_transaction
|
||||
-- for the sake of getting consistent results in this test file
|
||||
SELECT recover_prepared_transactions();
|
||||
recover_prepared_transactions
|
||||
-------------------------------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
CREATE TABLE distributed_mx_table (
|
||||
key text primary key,
|
||||
value jsonb
|
||||
);
|
||||
CREATE INDEX ON distributed_mx_table USING GIN (value);
|
||||
SET citus.shard_replication_factor TO 1;
|
||||
SET citus.replication_model TO streaming;
|
||||
SET citus.shard_count TO 4;
|
||||
SELECT create_distributed_table('distributed_mx_table', 'key');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- Verify that we've logged commit records
|
||||
SELECT count(*) FROM pg_dist_transaction;
|
||||
count
|
||||
-------
|
||||
5
|
||||
(1 row)
|
||||
|
||||
-- Confirm that the metadata transactions have been committed
|
||||
SELECT recover_prepared_transactions();
|
||||
recover_prepared_transactions
|
||||
-------------------------------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
-- Verify that the commit records have been removed
|
||||
SELECT count(*) FROM pg_dist_transaction;
|
||||
count
|
||||
-------
|
||||
3
|
||||
(1 row)
|
||||
|
||||
\c - - - :worker_1_port
|
||||
\d distributed_mx_table
|
||||
Table "public.distributed_mx_table"
|
||||
Column | Type | Modifiers
|
||||
--------+-------+-----------
|
||||
key | text | not null
|
||||
value | jsonb |
|
||||
Indexes:
|
||||
"distributed_mx_table_pkey" PRIMARY KEY, btree (key)
|
||||
"distributed_mx_table_value_idx" gin (value)
|
||||
|
||||
SELECT repmodel FROM pg_dist_partition
|
||||
WHERE logicalrelid = 'distributed_mx_table'::regclass;
|
||||
repmodel
|
||||
----------
|
||||
s
|
||||
(1 row)
|
||||
|
||||
SELECT count(*) FROM pg_dist_shard JOIN pg_dist_shard_placement USING (shardid)
|
||||
WHERE logicalrelid = 'distributed_mx_table'::regclass;
|
||||
count
|
||||
-------
|
||||
4
|
||||
(1 row)
|
||||
|
||||
\c - - - :worker_2_port
|
||||
\d distributed_mx_table
|
||||
Table "public.distributed_mx_table"
|
||||
Column | Type | Modifiers
|
||||
--------+-------+-----------
|
||||
key | text | not null
|
||||
value | jsonb |
|
||||
Indexes:
|
||||
"distributed_mx_table_pkey" PRIMARY KEY, btree (key)
|
||||
"distributed_mx_table_value_idx" gin (value)
|
||||
|
||||
SELECT repmodel FROM pg_dist_partition
|
||||
WHERE logicalrelid = 'distributed_mx_table'::regclass;
|
||||
repmodel
|
||||
----------
|
||||
s
|
||||
(1 row)
|
||||
|
||||
SELECT count(*) FROM pg_dist_shard JOIN pg_dist_shard_placement USING (shardid)
|
||||
WHERE logicalrelid = 'distributed_mx_table'::regclass;
|
||||
count
|
||||
-------
|
||||
4
|
||||
(1 row)
|
||||
|
||||
-- Create a table and then roll back the transaction
|
||||
\c - - - :master_port
|
||||
SET citus.shard_replication_factor TO 1;
|
||||
SET citus.replication_model TO streaming;
|
||||
BEGIN;
|
||||
CREATE TABLE should_not_exist (
|
||||
key text primary key,
|
||||
value jsonb
|
||||
);
|
||||
SELECT create_distributed_table('should_not_exist', 'key');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
ABORT;
|
||||
-- Verify that the table does not exist on the worker
|
||||
\c - - - :worker_1_port
|
||||
SELECT count(*) FROM pg_tables WHERE tablename = 'should_not_exist';
|
||||
count
|
||||
-------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
-- Ensure that we don't allow prepare on a metadata transaction
|
||||
\c - - - :master_port
|
||||
SET citus.shard_replication_factor TO 1;
|
||||
SET citus.replication_model TO streaming;
|
||||
BEGIN;
|
||||
CREATE TABLE should_not_exist (
|
||||
key text primary key,
|
||||
value jsonb
|
||||
);
|
||||
SELECT create_distributed_table('should_not_exist', 'key');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
PREPARE TRANSACTION 'this_should_fail';
|
||||
ERROR: cannot use 2PC in transactions involving multiple servers
|
||||
-- now show that we can create tables and schemas withing a single transaction
|
||||
BEGIN;
|
||||
CREATE SCHEMA IF NOT EXISTS citus_mx_schema_for_xacts;
|
||||
SET search_path TO citus_mx_schema_for_xacts;
|
||||
SET citus.shard_replication_factor TO 1;
|
||||
SET citus.shard_count TO 1;
|
||||
CREATE TABLE objects_for_xacts (
|
||||
id bigint PRIMARY KEY,
|
||||
name text NOT NULL
|
||||
);
|
||||
SELECT create_distributed_table('objects_for_xacts', 'id');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
COMMIT;
|
||||
-- see that the table actually created and distributed
|
||||
\c - - - :worker_1_port
|
||||
SELECT repmodel FROM pg_dist_partition
|
||||
WHERE logicalrelid = 'citus_mx_schema_for_xacts.objects_for_xacts'::regclass;
|
||||
repmodel
|
||||
----------
|
||||
s
|
||||
(1 row)
|
||||
|
||||
SELECT count(*) FROM pg_dist_shard JOIN pg_dist_shard_placement USING (shardid)
|
||||
WHERE logicalrelid = 'citus_mx_schema_for_xacts.objects_for_xacts'::regclass;
|
||||
count
|
||||
-------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
\c - - - :master_port
|
||||
SET citus.shard_replication_factor TO 1;
|
||||
SET citus.replication_model TO streaming;
|
||||
-- now show that we can rollback on creating mx table, but shards remain....
|
||||
BEGIN;
|
||||
CREATE SCHEMA IF NOT EXISTS citus_mx_schema_for_xacts;
|
||||
NOTICE: schema "citus_mx_schema_for_xacts" already exists, skipping
|
||||
SET search_path TO citus_mx_schema_for_xacts;
|
||||
SET citus.shard_replication_factor TO 1;
|
||||
SET citus.shard_count TO 2;
|
||||
CREATE TABLE objects_for_xacts2 (
|
||||
id bigint PRIMARY KEY,
|
||||
name text NOT NULL
|
||||
);
|
||||
SELECT create_distributed_table('objects_for_xacts2', 'id');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
ROLLBACK;
|
||||
-- show that the table not exists on the schema node
|
||||
SELECT count(*) FROM pg_tables WHERE tablename = 'objects_for_xacts2' and schemaname = 'citus_mx_schema_for_xacts';
|
||||
count
|
||||
-------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
\c - - - :worker_1_port
|
||||
-- the distributed table not exists on the worker node
|
||||
SELECT count(*) FROM pg_tables WHERE tablename = 'objects_for_xacts2' and schemaname = 'citus_mx_schema_for_xacts';
|
||||
count
|
||||
-------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
-- but the shard exists since we do not create shards in a transaction
|
||||
SELECT count(*) FROM pg_tables WHERE tablename LIKE 'objects_for_xacts2_%' and schemaname = 'citus_mx_schema_for_xacts';
|
||||
count
|
||||
-------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
-- make sure that master_drop_all_shards does not work from the worker nodes
|
||||
SELECT master_drop_all_shards('citus_mx_schema_for_xacts.objects_for_xacts'::regclass, 'citus_mx_schema_for_xacts', 'objects_for_xacts');
|
||||
ERROR: operation is not allowed on this node
|
||||
HINT: Connect to the schema node and run it again.
|
||||
-- Ensure pg_dist_transaction is empty for test
|
||||
SELECT recover_prepared_transactions();
|
||||
recover_prepared_transactions
|
||||
-------------------------------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
-- Create some "fake" prepared transactions to recover
|
||||
\c - - - :worker_1_port
|
||||
BEGIN;
|
||||
CREATE TABLE should_abort (value int);
|
||||
PREPARE TRANSACTION 'citus_0_should_abort';
|
||||
BEGIN;
|
||||
CREATE TABLE should_commit (value int);
|
||||
PREPARE TRANSACTION 'citus_0_should_commit';
|
||||
BEGIN;
|
||||
CREATE TABLE should_be_sorted_into_middle (value int);
|
||||
PREPARE TRANSACTION 'citus_0_should_be_sorted_into_middle';
|
||||
\c - - - :master_port
|
||||
-- Add "fake" pg_dist_transaction records and run recovery
|
||||
INSERT INTO pg_dist_transaction VALUES (14, 'citus_0_should_commit');
|
||||
INSERT INTO pg_dist_transaction VALUES (14, 'citus_0_should_be_forgotten');
|
||||
SELECT recover_prepared_transactions();
|
||||
NOTICE: recovered a prepared transaction on localhost:57637
|
||||
CONTEXT: ROLLBACK PREPARED 'citus_0_should_abort'
|
||||
NOTICE: recovered a prepared transaction on localhost:57637
|
||||
CONTEXT: ROLLBACK PREPARED 'citus_0_should_be_sorted_into_middle'
|
||||
NOTICE: recovered a prepared transaction on localhost:57637
|
||||
CONTEXT: COMMIT PREPARED 'citus_0_should_commit'
|
||||
recover_prepared_transactions
|
||||
-------------------------------
|
||||
3
|
||||
(1 row)
|
||||
|
||||
SELECT count(*) FROM pg_dist_transaction;
|
||||
count
|
||||
-------
|
||||
3
|
||||
(1 row)
|
||||
|
||||
-- Confirm that transactions were correctly rolled forward
|
||||
\c - - - :worker_1_port
|
||||
SELECT count(*) FROM pg_tables WHERE tablename = 'should_abort';
|
||||
count
|
||||
-------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
SELECT count(*) FROM pg_tables WHERE tablename = 'should_commit';
|
||||
count
|
||||
-------
|
||||
1
|
||||
(1 row)
|
||||
|
|
@ -0,0 +1,461 @@
|
|||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1330000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1330000;
|
||||
-- ===================================================================
|
||||
-- test end-to-end modification functionality for mx tables
|
||||
-- ===================================================================
|
||||
-- basic single-row INSERT
|
||||
INSERT INTO limit_orders_mx VALUES (32743, 'AAPL', 9580, '2004-10-19 10:23:54', 'buy',
|
||||
20.69);
|
||||
SELECT COUNT(*) FROM limit_orders_mx WHERE id = 32743;
|
||||
count
|
||||
-------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
-- now singe-row INSERT from a worker
|
||||
\c - - - :worker_1_port
|
||||
INSERT INTO limit_orders_mx VALUES (32744, 'AAPL', 9580, '2004-10-19 10:23:54', 'buy',
|
||||
20.69);
|
||||
SELECT COUNT(*) FROM limit_orders_mx WHERE id = 32744;
|
||||
count
|
||||
-------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
-- now singe-row INSERT to the other worker
|
||||
\c - - - :worker_2_port
|
||||
INSERT INTO limit_orders_mx VALUES (32745, 'AAPL', 9580, '2004-10-19 10:23:54', 'buy',
|
||||
20.69);
|
||||
SELECT COUNT(*) FROM limit_orders_mx WHERE id = 32745;
|
||||
count
|
||||
-------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
-- and see all the inserted rows
|
||||
SELECT * FROM limit_orders_mx;
|
||||
id | symbol | bidder_id | placed_at | kind | limit_price
|
||||
-------+--------+-----------+--------------------------+------+-------------
|
||||
32744 | AAPL | 9580 | Tue Oct 19 10:23:54 2004 | buy | 20.69
|
||||
32743 | AAPL | 9580 | Tue Oct 19 10:23:54 2004 | buy | 20.69
|
||||
32745 | AAPL | 9580 | Tue Oct 19 10:23:54 2004 | buy | 20.69
|
||||
(3 rows)
|
||||
|
||||
-- basic single-row INSERT with RETURNING
|
||||
INSERT INTO limit_orders_mx VALUES (32746, 'AAPL', 9580, '2004-10-19 10:23:54', 'buy', 20.69) RETURNING *;
|
||||
id | symbol | bidder_id | placed_at | kind | limit_price
|
||||
-------+--------+-----------+--------------------------+------+-------------
|
||||
32746 | AAPL | 9580 | Tue Oct 19 10:23:54 2004 | buy | 20.69
|
||||
(1 row)
|
||||
|
||||
-- INSERT with DEFAULT in the target list
|
||||
INSERT INTO limit_orders_mx VALUES (12756, 'MSFT', 10959, '2013-05-08 07:29:23', 'sell',
|
||||
DEFAULT);
|
||||
SELECT * FROM limit_orders_mx WHERE id = 12756;
|
||||
id | symbol | bidder_id | placed_at | kind | limit_price
|
||||
-------+--------+-----------+--------------------------+------+-------------
|
||||
12756 | MSFT | 10959 | Wed May 08 07:29:23 2013 | sell | 0.00
|
||||
(1 row)
|
||||
|
||||
-- INSERT with expressions in target list
|
||||
INSERT INTO limit_orders_mx VALUES (430, upper('ibm'), 214, timestamp '2003-01-28 10:31:17' +
|
||||
interval '5 hours', 'buy', sqrt(2));
|
||||
SELECT * FROM limit_orders_mx WHERE id = 430;
|
||||
id | symbol | bidder_id | placed_at | kind | limit_price
|
||||
-----+--------+-----------+--------------------------+------+-----------------
|
||||
430 | IBM | 214 | Tue Jan 28 15:31:17 2003 | buy | 1.4142135623731
|
||||
(1 row)
|
||||
|
||||
-- INSERT without partition key
|
||||
INSERT INTO limit_orders_mx DEFAULT VALUES;
|
||||
ERROR: cannot plan INSERT using row with NULL value in partition column
|
||||
-- squelch WARNINGs that contain worker_port
|
||||
SET client_min_messages TO ERROR;
|
||||
-- INSERT violating NOT NULL constraint
|
||||
INSERT INTO limit_orders_mx VALUES (NULL, 'T', 975234, DEFAULT);
|
||||
ERROR: cannot plan INSERT using row with NULL value in partition column
|
||||
-- INSERT violating column constraint
|
||||
INSERT INTO limit_orders_mx VALUES (18811, 'BUD', 14962, '2014-04-05 08:32:16', 'sell',
|
||||
-5.00);
|
||||
ERROR: new row for relation "limit_orders_mx_1220092" violates check constraint "limit_orders_mx_limit_price_check"
|
||||
DETAIL: Failing row contains (18811, BUD, 14962, 2014-04-05 08:32:16, sell, -5.00).
|
||||
CONTEXT: while executing command on localhost:57637
|
||||
-- INSERT violating primary key constraint
|
||||
INSERT INTO limit_orders_mx VALUES (32743, 'LUV', 5994, '2001-04-16 03:37:28', 'buy', 0.58);
|
||||
ERROR: duplicate key value violates unique constraint "limit_orders_mx_pkey_1220093"
|
||||
DETAIL: Key (id)=(32743) already exists.
|
||||
CONTEXT: while executing command on localhost:57638
|
||||
-- INSERT violating primary key constraint, with RETURNING specified.
|
||||
INSERT INTO limit_orders_mx VALUES (32743, 'LUV', 5994, '2001-04-16 03:37:28', 'buy', 0.58) RETURNING *;
|
||||
ERROR: duplicate key value violates unique constraint "limit_orders_mx_pkey_1220093"
|
||||
DETAIL: Key (id)=(32743) already exists.
|
||||
CONTEXT: while executing command on localhost:57638
|
||||
-- INSERT, with RETURNING specified, failing with a non-constraint error
|
||||
INSERT INTO limit_orders_mx VALUES (34153, 'LEE', 5994, '2001-04-16 03:37:28', 'buy', 0.58) RETURNING id / 0;
|
||||
ERROR: could not modify any active placements
|
||||
SET client_min_messages TO DEFAULT;
|
||||
-- commands with non-constant partition values are unsupported
|
||||
INSERT INTO limit_orders_mx VALUES (random() * 100, 'ORCL', 152, '2011-08-25 11:50:45',
|
||||
'sell', 0.58);
|
||||
ERROR: values given for the partition column must be constants or constant expressions
|
||||
-- values for other columns are totally fine
|
||||
INSERT INTO limit_orders_mx VALUES (2036, 'GOOG', 5634, now(), 'buy', random());
|
||||
-- commands with mutable functions in their quals
|
||||
DELETE FROM limit_orders_mx WHERE id = 246 AND bidder_id = (random() * 1000);
|
||||
ERROR: functions used in the WHERE clause of modification queries on distributed tables must not be VOLATILE
|
||||
-- commands with mutable but non-volatile functions(ie: stable func.) in their quals
|
||||
-- (the cast to timestamp is because the timestamp_eq_timestamptz operator is stable)
|
||||
DELETE FROM limit_orders_mx WHERE id = 246 AND placed_at = current_timestamp::timestamp;
|
||||
-- commands with multiple rows are unsupported
|
||||
INSERT INTO limit_orders_mx VALUES (DEFAULT), (DEFAULT);
|
||||
ERROR: cannot perform distributed planning for the given modification
|
||||
DETAIL: Multi-row INSERTs to distributed tables are not supported.
|
||||
-- INSERT ... SELECT ... FROM commands are unsupported from workers
|
||||
INSERT INTO limit_orders_mx SELECT * FROM limit_orders_mx;
|
||||
ERROR: operation is not allowed on this node
|
||||
HINT: Connect to the schema node and run it again.
|
||||
-- connect back to the other node
|
||||
\c - - - :worker_1_port
|
||||
-- commands containing a CTE are unsupported
|
||||
WITH deleted_orders AS (DELETE FROM limit_orders_mx RETURNING *)
|
||||
INSERT INTO limit_orders_mx DEFAULT VALUES;
|
||||
ERROR: common table expressions are not supported in distributed modifications
|
||||
-- test simple DELETE
|
||||
INSERT INTO limit_orders_mx VALUES (246, 'TSLA', 162, '2007-07-02 16:32:15', 'sell', 20.69);
|
||||
SELECT COUNT(*) FROM limit_orders_mx WHERE id = 246;
|
||||
count
|
||||
-------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
DELETE FROM limit_orders_mx WHERE id = 246;
|
||||
SELECT COUNT(*) FROM limit_orders_mx WHERE id = 246;
|
||||
count
|
||||
-------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
-- test simple DELETE with RETURNING
|
||||
DELETE FROM limit_orders_mx WHERE id = 430 RETURNING *;
|
||||
id | symbol | bidder_id | placed_at | kind | limit_price
|
||||
-----+--------+-----------+--------------------------+------+-----------------
|
||||
430 | IBM | 214 | Tue Jan 28 15:31:17 2003 | buy | 1.4142135623731
|
||||
(1 row)
|
||||
|
||||
SELECT COUNT(*) FROM limit_orders_mx WHERE id = 430;
|
||||
count
|
||||
-------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
-- DELETE with expression in WHERE clause
|
||||
INSERT INTO limit_orders_mx VALUES (246, 'TSLA', 162, '2007-07-02 16:32:15', 'sell', 20.69);
|
||||
SELECT COUNT(*) FROM limit_orders_mx WHERE id = 246;
|
||||
count
|
||||
-------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
DELETE FROM limit_orders_mx WHERE id = (2 * 123);
|
||||
SELECT COUNT(*) FROM limit_orders_mx WHERE id = 246;
|
||||
count
|
||||
-------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
-- commands with no constraints on the partition key are not supported
|
||||
DELETE FROM limit_orders_mx WHERE bidder_id = 162;
|
||||
ERROR: distributed modifications must target exactly one shard
|
||||
DETAIL: This command modifies all shards.
|
||||
HINT: Consider using an equality filter on partition column "id". You can use master_modify_multiple_shards() to perform multi-shard delete or update operations.
|
||||
-- commands with a USING clause are unsupported
|
||||
CREATE TABLE bidders ( name text, id bigint );
|
||||
DELETE FROM limit_orders_mx USING bidders WHERE limit_orders_mx.id = 246 AND
|
||||
limit_orders_mx.bidder_id = bidders.id AND
|
||||
bidders.name = 'Bernie Madoff';
|
||||
ERROR: cannot plan queries that include both regular and partitioned relations
|
||||
-- commands containing a CTE are unsupported
|
||||
WITH deleted_orders AS (INSERT INTO limit_orders_mx DEFAULT VALUES RETURNING *)
|
||||
DELETE FROM limit_orders_mx;
|
||||
ERROR: common table expressions are not supported in distributed modifications
|
||||
-- cursors are not supported
|
||||
DELETE FROM limit_orders_mx WHERE CURRENT OF cursor_name;
|
||||
ERROR: distributed modifications must target exactly one shard
|
||||
DETAIL: This command modifies all shards.
|
||||
HINT: Consider using an equality filter on partition column "id". You can use master_modify_multiple_shards() to perform multi-shard delete or update operations.
|
||||
INSERT INTO limit_orders_mx VALUES (246, 'TSLA', 162, '2007-07-02 16:32:15', 'sell', 20.69);
|
||||
-- simple UPDATE
|
||||
UPDATE limit_orders_mx SET symbol = 'GM' WHERE id = 246;
|
||||
SELECT symbol FROM limit_orders_mx WHERE id = 246;
|
||||
symbol
|
||||
--------
|
||||
GM
|
||||
(1 row)
|
||||
|
||||
-- simple UPDATE with RETURNING
|
||||
UPDATE limit_orders_mx SET symbol = 'GM' WHERE id = 246 RETURNING *;
|
||||
id | symbol | bidder_id | placed_at | kind | limit_price
|
||||
-----+--------+-----------+--------------------------+------+-------------
|
||||
246 | GM | 162 | Mon Jul 02 16:32:15 2007 | sell | 20.69
|
||||
(1 row)
|
||||
|
||||
-- expression UPDATE
|
||||
UPDATE limit_orders_mx SET bidder_id = 6 * 3 WHERE id = 246;
|
||||
SELECT bidder_id FROM limit_orders_mx WHERE id = 246;
|
||||
bidder_id
|
||||
-----------
|
||||
18
|
||||
(1 row)
|
||||
|
||||
-- expression UPDATE with RETURNING
|
||||
UPDATE limit_orders_mx SET bidder_id = 6 * 5 WHERE id = 246 RETURNING *;
|
||||
id | symbol | bidder_id | placed_at | kind | limit_price
|
||||
-----+--------+-----------+--------------------------+------+-------------
|
||||
246 | GM | 30 | Mon Jul 02 16:32:15 2007 | sell | 20.69
|
||||
(1 row)
|
||||
|
||||
-- multi-column UPDATE
|
||||
UPDATE limit_orders_mx SET (kind, limit_price) = ('buy', DEFAULT) WHERE id = 246;
|
||||
SELECT kind, limit_price FROM limit_orders_mx WHERE id = 246;
|
||||
kind | limit_price
|
||||
------+-------------
|
||||
buy | 0.00
|
||||
(1 row)
|
||||
|
||||
-- multi-column UPDATE with RETURNING
|
||||
UPDATE limit_orders_mx SET (kind, limit_price) = ('buy', 999) WHERE id = 246 RETURNING *;
|
||||
id | symbol | bidder_id | placed_at | kind | limit_price
|
||||
-----+--------+-----------+--------------------------+------+-------------
|
||||
246 | GM | 30 | Mon Jul 02 16:32:15 2007 | buy | 999
|
||||
(1 row)
|
||||
|
||||
-- Test that on unique contraint violations, we fail fast
|
||||
INSERT INTO limit_orders_mx VALUES (275, 'ADR', 140, '2007-07-02 16:32:15', 'sell', 43.67);
|
||||
INSERT INTO limit_orders_mx VALUES (275, 'ADR', 140, '2007-07-02 16:32:15', 'sell', 43.67);
|
||||
ERROR: duplicate key value violates unique constraint "limit_orders_mx_pkey_1220093"
|
||||
DETAIL: Key (id)=(275) already exists.
|
||||
CONTEXT: while executing command on localhost:57638
|
||||
-- commands with no constraints on the partition key are not supported
|
||||
UPDATE limit_orders_mx SET limit_price = 0.00;
|
||||
ERROR: distributed modifications must target exactly one shard
|
||||
DETAIL: This command modifies all shards.
|
||||
HINT: Consider using an equality filter on partition column "id". You can use master_modify_multiple_shards() to perform multi-shard delete or update operations.
|
||||
-- attempting to change the partition key is unsupported
|
||||
UPDATE limit_orders_mx SET id = 0 WHERE id = 246;
|
||||
ERROR: modifying the partition value of rows is not allowed
|
||||
-- UPDATEs with a FROM clause are unsupported
|
||||
UPDATE limit_orders_mx SET limit_price = 0.00 FROM bidders
|
||||
WHERE limit_orders_mx.id = 246 AND
|
||||
limit_orders_mx.bidder_id = bidders.id AND
|
||||
bidders.name = 'Bernie Madoff';
|
||||
ERROR: cannot plan queries that include both regular and partitioned relations
|
||||
-- commands containing a CTE are unsupported
|
||||
WITH deleted_orders AS (INSERT INTO limit_orders_mx DEFAULT VALUES RETURNING *)
|
||||
UPDATE limit_orders_mx SET symbol = 'GM';
|
||||
ERROR: common table expressions are not supported in distributed modifications
|
||||
SELECT symbol, bidder_id FROM limit_orders_mx WHERE id = 246;
|
||||
symbol | bidder_id
|
||||
--------+-----------
|
||||
GM | 30
|
||||
(1 row)
|
||||
|
||||
-- updates referencing just a var are supported
|
||||
UPDATE limit_orders_mx SET bidder_id = id WHERE id = 246;
|
||||
-- updates referencing a column are supported
|
||||
UPDATE limit_orders_mx SET bidder_id = bidder_id + 1 WHERE id = 246;
|
||||
-- IMMUTABLE functions are allowed
|
||||
UPDATE limit_orders_mx SET symbol = LOWER(symbol) WHERE id = 246;
|
||||
SELECT symbol, bidder_id FROM limit_orders_mx WHERE id = 246;
|
||||
symbol | bidder_id
|
||||
--------+-----------
|
||||
gm | 247
|
||||
(1 row)
|
||||
|
||||
-- IMMUTABLE functions are allowed -- even in returning
|
||||
UPDATE limit_orders_mx SET symbol = UPPER(symbol) WHERE id = 246 RETURNING id, LOWER(symbol), symbol;
|
||||
id | lower | symbol
|
||||
-----+-------+--------
|
||||
246 | gm | GM
|
||||
(1 row)
|
||||
|
||||
-- connect schema node to run the DDL
|
||||
\c - - - :master_port
|
||||
ALTER TABLE limit_orders_mx ADD COLUMN array_of_values integer[];
|
||||
NOTICE: using one-phase commit for distributed DDL commands
|
||||
HINT: You can enable two-phase commit for extra safety with: SET citus.multi_shard_commit_protocol TO '2pc'
|
||||
-- connect back to the other node
|
||||
\c - - - :worker_2_port
|
||||
-- updates referencing STABLE functions are allowed
|
||||
UPDATE limit_orders_mx SET placed_at = LEAST(placed_at, now()::timestamp) WHERE id = 246;
|
||||
-- so are binary operators
|
||||
UPDATE limit_orders_mx SET array_of_values = 1 || array_of_values WHERE id = 246;
|
||||
-- connect back to the other node
|
||||
\c - - - :worker_2_port
|
||||
-- immutable function calls with vars are also allowed
|
||||
UPDATE limit_orders_mx
|
||||
SET array_of_values = immutable_append_mx(array_of_values, 2) WHERE id = 246;
|
||||
CREATE FUNCTION stable_append_mx(old_values int[], new_value int)
|
||||
RETURNS int[] AS $$ BEGIN RETURN old_values || new_value; END; $$
|
||||
LANGUAGE plpgsql STABLE;
|
||||
-- but STABLE function calls with vars are not allowed
|
||||
UPDATE limit_orders_mx
|
||||
SET array_of_values = stable_append_mx(array_of_values, 3) WHERE id = 246;
|
||||
ERROR: STABLE functions used in UPDATE queries cannot be called with column references
|
||||
SELECT array_of_values FROM limit_orders_mx WHERE id = 246;
|
||||
array_of_values
|
||||
-----------------
|
||||
{1,2}
|
||||
(1 row)
|
||||
|
||||
-- STRICT functions work as expected
|
||||
CREATE FUNCTION temp_strict_func(integer,integer) RETURNS integer AS
|
||||
'SELECT COALESCE($1, 2) + COALESCE($1, 3);' LANGUAGE SQL STABLE STRICT;
|
||||
UPDATE limit_orders_mx SET bidder_id = temp_strict_func(1, null) WHERE id = 246;
|
||||
ERROR: null value in column "bidder_id" violates not-null constraint
|
||||
DETAIL: Failing row contains (246, GM, null, 2007-07-02 16:32:15, buy, 999, {1,2}).
|
||||
CONTEXT: while executing command on localhost:57637
|
||||
SELECT array_of_values FROM limit_orders_mx WHERE id = 246;
|
||||
array_of_values
|
||||
-----------------
|
||||
{1,2}
|
||||
(1 row)
|
||||
|
||||
-- connect schema node to run the DDL
|
||||
\c - - - :master_port
|
||||
ALTER TABLE limit_orders_mx DROP array_of_values;
|
||||
NOTICE: using one-phase commit for distributed DDL commands
|
||||
HINT: You can enable two-phase commit for extra safety with: SET citus.multi_shard_commit_protocol TO '2pc'
|
||||
-- connect back to the other node
|
||||
\c - - - :worker_2_port
|
||||
-- even in RETURNING
|
||||
UPDATE limit_orders_mx SET placed_at = placed_at WHERE id = 246 RETURNING NOW();
|
||||
ERROR: non-IMMUTABLE functions are not allowed in the RETURNING clause
|
||||
-- cursors are not supported
|
||||
UPDATE limit_orders_mx SET symbol = 'GM' WHERE CURRENT OF cursor_name;
|
||||
ERROR: distributed modifications must target exactly one shard
|
||||
DETAIL: This command modifies all shards.
|
||||
HINT: Consider using an equality filter on partition column "id". You can use master_modify_multiple_shards() to perform multi-shard delete or update operations.
|
||||
-- check that multi-row UPDATE/DELETEs with RETURNING work
|
||||
INSERT INTO multiple_hash_mx VALUES ('0', '1');
|
||||
INSERT INTO multiple_hash_mx VALUES ('0', '2');
|
||||
INSERT INTO multiple_hash_mx VALUES ('0', '3');
|
||||
INSERT INTO multiple_hash_mx VALUES ('0', '4');
|
||||
INSERT INTO multiple_hash_mx VALUES ('0', '5');
|
||||
INSERT INTO multiple_hash_mx VALUES ('0', '6');
|
||||
UPDATE multiple_hash_mx SET data = data ||'-1' WHERE category = '0' RETURNING *;
|
||||
category | data
|
||||
----------+------
|
||||
0 | 1-1
|
||||
0 | 2-1
|
||||
0 | 3-1
|
||||
0 | 4-1
|
||||
0 | 5-1
|
||||
0 | 6-1
|
||||
(6 rows)
|
||||
|
||||
DELETE FROM multiple_hash_mx WHERE category = '0' RETURNING *;
|
||||
category | data
|
||||
----------+------
|
||||
0 | 1-1
|
||||
0 | 2-1
|
||||
0 | 3-1
|
||||
0 | 4-1
|
||||
0 | 5-1
|
||||
0 | 6-1
|
||||
(6 rows)
|
||||
|
||||
-- ensure returned row counters are correct
|
||||
\set QUIET off
|
||||
INSERT INTO multiple_hash_mx VALUES ('1', '1');
|
||||
INSERT 0 1
|
||||
INSERT INTO multiple_hash_mx VALUES ('1', '2');
|
||||
INSERT 0 1
|
||||
INSERT INTO multiple_hash_mx VALUES ('1', '3');
|
||||
INSERT 0 1
|
||||
INSERT INTO multiple_hash_mx VALUES ('2', '1');
|
||||
INSERT 0 1
|
||||
INSERT INTO multiple_hash_mx VALUES ('2', '2');
|
||||
INSERT 0 1
|
||||
INSERT INTO multiple_hash_mx VALUES ('2', '3');
|
||||
INSERT 0 1
|
||||
INSERT INTO multiple_hash_mx VALUES ('2', '3') RETURNING *;
|
||||
category | data
|
||||
----------+------
|
||||
2 | 3
|
||||
(1 row)
|
||||
|
||||
INSERT 0 1
|
||||
-- check that update return the right number of rows
|
||||
-- one row
|
||||
UPDATE multiple_hash_mx SET data = data ||'-1' WHERE category = '1' AND data = '1';
|
||||
UPDATE 1
|
||||
-- three rows
|
||||
UPDATE multiple_hash_mx SET data = data ||'-2' WHERE category = '1';
|
||||
UPDATE 3
|
||||
-- three rows, with RETURNING
|
||||
UPDATE multiple_hash_mx SET data = data ||'-2' WHERE category = '1' RETURNING category;
|
||||
category
|
||||
----------
|
||||
1
|
||||
1
|
||||
1
|
||||
(3 rows)
|
||||
|
||||
UPDATE 3
|
||||
-- check
|
||||
SELECT * FROM multiple_hash_mx WHERE category = '1' ORDER BY category, data;
|
||||
category | data
|
||||
----------+---------
|
||||
1 | 1-1-2-2
|
||||
1 | 2-2-2
|
||||
1 | 3-2-2
|
||||
(3 rows)
|
||||
|
||||
-- check that deletes return the right number of rows
|
||||
-- one row
|
||||
DELETE FROM multiple_hash_mx WHERE category = '2' AND data = '1';
|
||||
DELETE 1
|
||||
-- two rows
|
||||
DELETE FROM multiple_hash_mx WHERE category = '2';
|
||||
DELETE 3
|
||||
-- three rows, with RETURNING
|
||||
DELETE FROM multiple_hash_mx WHERE category = '1' RETURNING category;
|
||||
category
|
||||
----------
|
||||
1
|
||||
1
|
||||
1
|
||||
(3 rows)
|
||||
|
||||
DELETE 3
|
||||
-- check
|
||||
SELECT * FROM multiple_hash_mx WHERE category = '1' ORDER BY category, data;
|
||||
category | data
|
||||
----------+------
|
||||
(0 rows)
|
||||
|
||||
SELECT * FROM multiple_hash_mx WHERE category = '2' ORDER BY category, data;
|
||||
category | data
|
||||
----------+------
|
||||
(0 rows)
|
||||
|
||||
-- verify interaction of default values, SERIAL, and RETURNING
|
||||
\set QUIET on
|
||||
INSERT INTO app_analytics_events_mx VALUES (DEFAULT, 101, 'Fauxkemon Geaux') RETURNING id;
|
||||
id
|
||||
------------------
|
||||
4503599627370497
|
||||
(1 row)
|
||||
|
||||
INSERT INTO app_analytics_events_mx (app_id, name) VALUES (102, 'Wayz') RETURNING id;
|
||||
id
|
||||
------------------
|
||||
4503599627370498
|
||||
(1 row)
|
||||
|
||||
INSERT INTO app_analytics_events_mx (app_id, name) VALUES (103, 'Mynt') RETURNING *;
|
||||
id | app_id | name
|
||||
------------------+--------+------
|
||||
4503599627370499 | 103 | Mynt
|
||||
(1 row)
|
||||
|
|
@ -0,0 +1,421 @@
|
|||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1340000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1340000;
|
||||
-- ===================================================================
|
||||
-- test end-to-end modification functionality for mx tables in transactions
|
||||
-- ===================================================================
|
||||
-- add some data
|
||||
INSERT INTO researchers_mx VALUES (1, 1, 'Donald Knuth');
|
||||
INSERT INTO researchers_mx VALUES (2, 1, 'Niklaus Wirth');
|
||||
INSERT INTO researchers_mx VALUES (3, 2, 'Tony Hoare');
|
||||
INSERT INTO researchers_mx VALUES (4, 2, 'Kenneth Iverson');
|
||||
-- replace a researcher, reusing their id on the schema node
|
||||
BEGIN;
|
||||
DELETE FROM researchers_mx WHERE lab_id = 1 AND id = 2;
|
||||
INSERT INTO researchers_mx VALUES (2, 1, 'John Backus');
|
||||
COMMIT;
|
||||
SELECT name FROM researchers_mx WHERE lab_id = 1 AND id = 2;
|
||||
name
|
||||
-------------
|
||||
John Backus
|
||||
(1 row)
|
||||
|
||||
-- do it on the worker node as well
|
||||
\c - - - :worker_1_port
|
||||
BEGIN;
|
||||
DELETE FROM researchers_mx WHERE lab_id = 1 AND id = 2;
|
||||
INSERT INTO researchers_mx VALUES (2, 1, 'John Backus Worker 1');
|
||||
COMMIT;
|
||||
SELECT name FROM researchers_mx WHERE lab_id = 1 AND id = 2;
|
||||
name
|
||||
----------------------
|
||||
John Backus Worker 1
|
||||
(1 row)
|
||||
|
||||
-- do it on the worker other node as well
|
||||
\c - - - :worker_2_port
|
||||
BEGIN;
|
||||
DELETE FROM researchers_mx WHERE lab_id = 1 AND id = 2;
|
||||
INSERT INTO researchers_mx VALUES (2, 1, 'John Backus Worker 2');
|
||||
COMMIT;
|
||||
SELECT name FROM researchers_mx WHERE lab_id = 1 AND id = 2;
|
||||
name
|
||||
----------------------
|
||||
John Backus Worker 2
|
||||
(1 row)
|
||||
|
||||
\c - - - :master_port
|
||||
-- abort a modification
|
||||
BEGIN;
|
||||
DELETE FROM researchers_mx WHERE lab_id = 1 AND id = 1;
|
||||
ABORT;
|
||||
SELECT name FROM researchers_mx WHERE lab_id = 1 AND id = 1;
|
||||
name
|
||||
--------------
|
||||
Donald Knuth
|
||||
(1 row)
|
||||
|
||||
\c - - - :worker_1_port
|
||||
-- abort a modification on the worker node
|
||||
BEGIN;
|
||||
DELETE FROM researchers_mx WHERE lab_id = 1 AND id = 1;
|
||||
ABORT;
|
||||
SELECT name FROM researchers_mx WHERE lab_id = 1 AND id = 1;
|
||||
name
|
||||
--------------
|
||||
Donald Knuth
|
||||
(1 row)
|
||||
|
||||
\c - - - :worker_2_port
|
||||
-- abort a modification on the other worker node
|
||||
BEGIN;
|
||||
DELETE FROM researchers_mx WHERE lab_id = 1 AND id = 1;
|
||||
ABORT;
|
||||
SELECT name FROM researchers_mx WHERE lab_id = 1 AND id = 1;
|
||||
name
|
||||
--------------
|
||||
Donald Knuth
|
||||
(1 row)
|
||||
|
||||
-- switch back to the first worker node
|
||||
\c - - - :worker_1_port
|
||||
-- creating savepoints should work...
|
||||
BEGIN;
|
||||
INSERT INTO researchers_mx VALUES (5, 3, 'Dennis Ritchie');
|
||||
SAVEPOINT hire_thompson;
|
||||
INSERT INTO researchers_mx VALUES (6, 3, 'Ken Thompson');
|
||||
COMMIT;
|
||||
SELECT name FROM researchers_mx WHERE lab_id = 3 AND id = 6;
|
||||
name
|
||||
--------------
|
||||
Ken Thompson
|
||||
(1 row)
|
||||
|
||||
-- even if created by PL/pgSQL...
|
||||
\set VERBOSITY terse
|
||||
BEGIN;
|
||||
DO $$
|
||||
BEGIN
|
||||
INSERT INTO researchers_mx VALUES (10, 10, 'Edsger Dijkstra');
|
||||
EXCEPTION
|
||||
WHEN not_null_violation THEN
|
||||
RAISE NOTICE 'caught not_null_violation';
|
||||
END $$;
|
||||
COMMIT;
|
||||
-- but rollback should not
|
||||
BEGIN;
|
||||
INSERT INTO researchers_mx VALUES (7, 4, 'Jim Gray');
|
||||
SAVEPOINT hire_engelbart;
|
||||
INSERT INTO researchers_mx VALUES (8, 4, 'Douglas Engelbart');
|
||||
ROLLBACK TO hire_engelbart;
|
||||
COMMIT;
|
||||
ERROR: cannot ROLLBACK TO SAVEPOINT in transactions which modify distributed tables
|
||||
SELECT name FROM researchers_mx WHERE lab_id = 4;
|
||||
name
|
||||
------
|
||||
(0 rows)
|
||||
|
||||
BEGIN;
|
||||
DO $$
|
||||
BEGIN
|
||||
INSERT INTO researchers_mx VALUES (NULL, 10, 'Edsger Dijkstra');
|
||||
EXCEPTION
|
||||
WHEN not_null_violation THEN
|
||||
RAISE NOTICE 'caught not_null_violation';
|
||||
END $$;
|
||||
NOTICE: caught not_null_violation
|
||||
COMMIT;
|
||||
ERROR: could not commit transaction for shard 1220100 on any active node
|
||||
\set VERBOSITY default
|
||||
-- should be valid to edit labs_mx after researchers_mx...
|
||||
BEGIN;
|
||||
INSERT INTO researchers_mx VALUES (8, 5, 'Douglas Engelbart');
|
||||
INSERT INTO labs_mx VALUES (5, 'Los Alamos');
|
||||
COMMIT;
|
||||
SELECT * FROM researchers_mx, labs_mx WHERE labs_mx.id = researchers_mx.lab_id;
|
||||
id | lab_id | name | id | name
|
||||
----+--------+-------------------+----+------------
|
||||
8 | 5 | Douglas Engelbart | 5 | Los Alamos
|
||||
(1 row)
|
||||
|
||||
-- but not the other way around (would require expanding xact participants)...
|
||||
BEGIN;
|
||||
INSERT INTO labs_mx VALUES (6, 'Bell labs_mx');
|
||||
INSERT INTO researchers_mx VALUES (9, 6, 'Leslie Lamport');
|
||||
ERROR: no transaction participant matches localhost:57638
|
||||
DETAIL: Transactions which modify distributed tables may only target nodes affected by the modification command which began the transaction.
|
||||
COMMIT;
|
||||
-- have the same test on the other worker node
|
||||
\c - - - :worker_2_port
|
||||
-- should be valid to edit labs_mx after researchers_mx...
|
||||
BEGIN;
|
||||
INSERT INTO researchers_mx VALUES (8, 5, 'Douglas Engelbart');
|
||||
INSERT INTO labs_mx VALUES (5, 'Los Alamos');
|
||||
COMMIT;
|
||||
SELECT * FROM researchers_mx, labs_mx WHERE labs_mx.id = researchers_mx.lab_id;
|
||||
id | lab_id | name | id | name
|
||||
----+--------+-------------------+----+------------
|
||||
8 | 5 | Douglas Engelbart | 5 | Los Alamos
|
||||
8 | 5 | Douglas Engelbart | 5 | Los Alamos
|
||||
8 | 5 | Douglas Engelbart | 5 | Los Alamos
|
||||
8 | 5 | Douglas Engelbart | 5 | Los Alamos
|
||||
(4 rows)
|
||||
|
||||
-- but not the other way around (would require expanding xact participants)...
|
||||
BEGIN;
|
||||
INSERT INTO labs_mx VALUES (6, 'Bell labs_mx');
|
||||
INSERT INTO researchers_mx VALUES (9, 6, 'Leslie Lamport');
|
||||
ERROR: no transaction participant matches localhost:57638
|
||||
DETAIL: Transactions which modify distributed tables may only target nodes affected by the modification command which began the transaction.
|
||||
COMMIT;
|
||||
-- switch back to the worker node
|
||||
\c - - - :worker_1_port
|
||||
-- this logic doesn't apply to router SELECTs occurring after a modification:
|
||||
-- selecting from the modified node is fine...
|
||||
BEGIN;
|
||||
INSERT INTO labs_mx VALUES (6, 'Bell labs_mx');
|
||||
SELECT count(*) FROM researchers_mx WHERE lab_id = 6;
|
||||
count
|
||||
-------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
ABORT;
|
||||
-- applies to DDL
|
||||
BEGIN;
|
||||
INSERT INTO labs_mx VALUES (6, 'Bell labs_mx');
|
||||
ALTER TABLE labs_mx ADD COLUMN text motto;
|
||||
ERROR: distributed DDL commands must not appear within transaction blocks containing single-shard data modifications
|
||||
COMMIT;
|
||||
-- doesn't apply to COPY after modifications
|
||||
BEGIN;
|
||||
INSERT INTO labs_mx VALUES (6, 'Bell labs_mx');
|
||||
\copy labs_mx from stdin delimiter ','
|
||||
COMMIT;
|
||||
-- copy will also work if before any modifications
|
||||
BEGIN;
|
||||
\copy labs_mx from stdin delimiter ','
|
||||
SELECT name FROM labs_mx WHERE id = 10;
|
||||
name
|
||||
------------------
|
||||
Weyland-Yutani-1
|
||||
Weyland-Yutani-2
|
||||
(2 rows)
|
||||
|
||||
INSERT INTO labs_mx VALUES (6, 'Bell labs_mx');
|
||||
COMMIT;
|
||||
\c - - - :worker_1_port
|
||||
-- test primary key violations
|
||||
BEGIN;
|
||||
INSERT INTO objects_mx VALUES (1, 'apple');
|
||||
INSERT INTO objects_mx VALUES (1, 'orange');
|
||||
ERROR: duplicate key value violates unique constraint "objects_mx_pkey_1220103"
|
||||
DETAIL: Key (id)=(1) already exists.
|
||||
CONTEXT: while executing command on localhost:57637
|
||||
COMMIT;
|
||||
-- data shouldn't have persisted...
|
||||
SELECT * FROM objects_mx WHERE id = 1;
|
||||
id | name
|
||||
----+------
|
||||
(0 rows)
|
||||
|
||||
-- same test on the second worker node
|
||||
\c - - - :worker_2_port
|
||||
-- test primary key violations
|
||||
BEGIN;
|
||||
INSERT INTO objects_mx VALUES (1, 'apple');
|
||||
INSERT INTO objects_mx VALUES (1, 'orange');
|
||||
ERROR: duplicate key value violates unique constraint "objects_mx_pkey_1220103"
|
||||
DETAIL: Key (id)=(1) already exists.
|
||||
CONTEXT: while executing command on localhost:57637
|
||||
COMMIT;
|
||||
-- data shouldn't have persisted...
|
||||
SELECT * FROM objects_mx WHERE id = 1;
|
||||
id | name
|
||||
----+------
|
||||
(0 rows)
|
||||
|
||||
-- create trigger on one worker to reject certain values
|
||||
\c - - - :worker_1_port
|
||||
CREATE FUNCTION reject_bad_mx() RETURNS trigger AS $rb$
|
||||
BEGIN
|
||||
IF (NEW.name = 'BAD') THEN
|
||||
RAISE 'illegal value';
|
||||
END IF;
|
||||
|
||||
RETURN NEW;
|
||||
END;
|
||||
$rb$ LANGUAGE plpgsql;
|
||||
CREATE CONSTRAINT TRIGGER reject_bad_mx
|
||||
AFTER INSERT ON objects_mx_1220103
|
||||
DEFERRABLE INITIALLY IMMEDIATE
|
||||
FOR EACH ROW EXECUTE PROCEDURE reject_bad_mx();
|
||||
-- test partial failure; statement 1 successed, statement 2 fails
|
||||
\set VERBOSITY terse
|
||||
BEGIN;
|
||||
INSERT INTO labs_mx VALUES (7, 'E Corp');
|
||||
INSERT INTO objects_mx VALUES (2, 'BAD');
|
||||
WARNING: illegal value
|
||||
ERROR: could not modify any active placements
|
||||
COMMIT;
|
||||
-- data should NOT be persisted
|
||||
SELECT * FROM objects_mx WHERE id = 2;
|
||||
id | name
|
||||
----+------
|
||||
(0 rows)
|
||||
|
||||
SELECT * FROM labs_mx WHERE id = 7;
|
||||
id | name
|
||||
----+------
|
||||
(0 rows)
|
||||
|
||||
-- same failure test from worker 2
|
||||
\c - - - :worker_2_port
|
||||
-- test partial failure; statement 1 successed, statement 2 fails
|
||||
BEGIN;
|
||||
INSERT INTO labs_mx VALUES (7, 'E Corp');
|
||||
INSERT INTO objects_mx VALUES (2, 'BAD');
|
||||
WARNING: illegal value
|
||||
ERROR: could not modify any active placements
|
||||
COMMIT;
|
||||
-- data should NOT be persisted
|
||||
SELECT * FROM objects_mx WHERE id = 2;
|
||||
id | name
|
||||
----+------
|
||||
(0 rows)
|
||||
|
||||
SELECT * FROM labs_mx WHERE id = 7;
|
||||
id | name
|
||||
----+------
|
||||
(0 rows)
|
||||
|
||||
\c - - - :worker_1_port
|
||||
-- what if there are errors on different shards at different times?
|
||||
\c - - - :worker_1_port
|
||||
CREATE CONSTRAINT TRIGGER reject_bad_mx
|
||||
AFTER INSERT ON labs_mx_1220102
|
||||
DEFERRABLE INITIALLY IMMEDIATE
|
||||
FOR EACH ROW EXECUTE PROCEDURE reject_bad_mx();
|
||||
BEGIN;
|
||||
INSERT INTO objects_mx VALUES (1, 'apple');
|
||||
INSERT INTO objects_mx VALUES (2, 'BAD');
|
||||
WARNING: illegal value
|
||||
ERROR: could not modify any active placements
|
||||
INSERT INTO labs_mx VALUES (8, 'Aperture Science');
|
||||
ERROR: current transaction is aborted, commands ignored until end of transaction block
|
||||
INSERT INTO labs_mx VALUES (9, 'BAD');
|
||||
ERROR: current transaction is aborted, commands ignored until end of transaction block
|
||||
COMMIT;
|
||||
-- data should NOT be persisted
|
||||
SELECT * FROM objects_mx WHERE id = 1;
|
||||
id | name
|
||||
----+------
|
||||
(0 rows)
|
||||
|
||||
SELECT * FROM labs_mx WHERE id = 8;
|
||||
id | name
|
||||
----+------
|
||||
(0 rows)
|
||||
|
||||
-- same test from the other worker
|
||||
\c - - - :worker_2_port
|
||||
BEGIN;
|
||||
INSERT INTO objects_mx VALUES (1, 'apple');
|
||||
INSERT INTO objects_mx VALUES (2, 'BAD');
|
||||
WARNING: illegal value
|
||||
ERROR: could not modify any active placements
|
||||
INSERT INTO labs_mx VALUES (8, 'Aperture Science');
|
||||
ERROR: current transaction is aborted, commands ignored until end of transaction block
|
||||
INSERT INTO labs_mx VALUES (9, 'BAD');
|
||||
ERROR: current transaction is aborted, commands ignored until end of transaction block
|
||||
COMMIT;
|
||||
-- data should NOT be persisted
|
||||
SELECT * FROM objects_mx WHERE id = 1;
|
||||
id | name
|
||||
----+------
|
||||
(0 rows)
|
||||
|
||||
SELECT * FROM labs_mx WHERE id = 8;
|
||||
id | name
|
||||
----+------
|
||||
(0 rows)
|
||||
|
||||
-- what if the failures happen at COMMIT time?
|
||||
\c - - - :worker_1_port
|
||||
DROP TRIGGER reject_bad_mx ON objects_mx_1220103;
|
||||
CREATE CONSTRAINT TRIGGER reject_bad_mx
|
||||
AFTER INSERT ON objects_mx_1220103
|
||||
DEFERRABLE INITIALLY DEFERRED
|
||||
FOR EACH ROW EXECUTE PROCEDURE reject_bad_mx();
|
||||
-- should be the same story as before, just at COMMIT time
|
||||
BEGIN;
|
||||
INSERT INTO objects_mx VALUES (1, 'apple');
|
||||
INSERT INTO objects_mx VALUES (2, 'BAD');
|
||||
INSERT INTO labs_mx VALUES (9, 'Umbrella Corporation');
|
||||
COMMIT;
|
||||
WARNING: illegal value
|
||||
WARNING: failed to commit transaction on localhost:57637
|
||||
WARNING: could not commit transaction for shard 1220103 on any active node
|
||||
WARNING: could not commit transaction for shard 1220102 on any active node
|
||||
ERROR: could not commit transaction on any active node
|
||||
-- data should NOT be persisted
|
||||
SELECT * FROM objects_mx WHERE id = 2;
|
||||
id | name
|
||||
----+------
|
||||
(0 rows)
|
||||
|
||||
SELECT * FROM labs_mx WHERE id = 7;
|
||||
id | name
|
||||
----+------
|
||||
(0 rows)
|
||||
|
||||
DROP TRIGGER reject_bad_mx ON labs_mx_1220102;
|
||||
CREATE CONSTRAINT TRIGGER reject_bad_mx
|
||||
AFTER INSERT ON labs_mx_1220102
|
||||
DEFERRABLE INITIALLY DEFERRED
|
||||
FOR EACH ROW EXECUTE PROCEDURE reject_bad_mx();
|
||||
BEGIN;
|
||||
INSERT INTO objects_mx VALUES (1, 'apple');
|
||||
INSERT INTO objects_mx VALUES (2, 'BAD');
|
||||
INSERT INTO labs_mx VALUES (8, 'Aperture Science');
|
||||
INSERT INTO labs_mx VALUES (9, 'BAD');
|
||||
COMMIT;
|
||||
WARNING: illegal value
|
||||
WARNING: failed to commit transaction on localhost:57637
|
||||
WARNING: could not commit transaction for shard 1220103 on any active node
|
||||
WARNING: could not commit transaction for shard 1220102 on any active node
|
||||
ERROR: could not commit transaction on any active node
|
||||
-- data should NOT be persisted
|
||||
SELECT * FROM objects_mx WHERE id = 1;
|
||||
id | name
|
||||
----+------
|
||||
(0 rows)
|
||||
|
||||
SELECT * FROM labs_mx WHERE id = 8;
|
||||
id | name
|
||||
----+------
|
||||
(0 rows)
|
||||
|
||||
-- what if one shard (objects_mx) succeeds but another (labs_mx) completely fails?
|
||||
\c - - - :worker_1_port
|
||||
DROP TRIGGER reject_bad_mx ON objects_mx_1220103;
|
||||
BEGIN;
|
||||
INSERT INTO objects_mx VALUES (1, 'apple');
|
||||
INSERT INTO labs_mx VALUES (8, 'Aperture Science');
|
||||
INSERT INTO labs_mx VALUES (9, 'BAD');
|
||||
COMMIT;
|
||||
WARNING: illegal value
|
||||
WARNING: failed to commit transaction on localhost:57637
|
||||
WARNING: could not commit transaction for shard 1220103 on any active node
|
||||
WARNING: could not commit transaction for shard 1220102 on any active node
|
||||
ERROR: could not commit transaction on any active node
|
||||
-- no data should persists
|
||||
SELECT * FROM objects_mx WHERE id = 1;
|
||||
id | name
|
||||
----+------
|
||||
(0 rows)
|
||||
|
||||
SELECT * FROM labs_mx WHERE id = 8;
|
||||
id | name
|
||||
----+------
|
||||
(0 rows)
|
||||
|
|
@ -0,0 +1,840 @@
|
|||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1250000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1250000;
|
||||
\c - - - :master_port
|
||||
CREATE TABLE reference_table_test (value_1 int, value_2 float, value_3 text, value_4 timestamp);
|
||||
SELECT create_reference_table('reference_table_test');
|
||||
create_reference_table
|
||||
------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
INSERT INTO reference_table_test VALUES (1, 1.0, '1', '2016-12-01');
|
||||
INSERT INTO reference_table_test VALUES (2, 2.0, '2', '2016-12-02');
|
||||
INSERT INTO reference_table_test VALUES (3, 3.0, '3', '2016-12-03');
|
||||
INSERT INTO reference_table_test VALUES (4, 4.0, '4', '2016-12-04');
|
||||
INSERT INTO reference_table_test VALUES (5, 5.0, '5', '2016-12-05');
|
||||
\c - - - :worker_1_port
|
||||
-- run some queries on top of the data
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
reference_table_test;
|
||||
value_1 | value_2 | value_3 | value_4
|
||||
---------+---------+---------+--------------------------
|
||||
1 | 1 | 1 | Thu Dec 01 00:00:00 2016
|
||||
2 | 2 | 2 | Fri Dec 02 00:00:00 2016
|
||||
3 | 3 | 3 | Sat Dec 03 00:00:00 2016
|
||||
4 | 4 | 4 | Sun Dec 04 00:00:00 2016
|
||||
5 | 5 | 5 | Mon Dec 05 00:00:00 2016
|
||||
(5 rows)
|
||||
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
value_1 = 1;
|
||||
value_1 | value_2 | value_3 | value_4
|
||||
---------+---------+---------+--------------------------
|
||||
1 | 1 | 1 | Thu Dec 01 00:00:00 2016
|
||||
(1 row)
|
||||
|
||||
SELECT
|
||||
value_1,
|
||||
value_2
|
||||
FROM
|
||||
reference_table_test
|
||||
ORDER BY
|
||||
2 ASC LIMIT 3;
|
||||
value_1 | value_2
|
||||
---------+---------
|
||||
1 | 1
|
||||
2 | 2
|
||||
3 | 3
|
||||
(3 rows)
|
||||
|
||||
SELECT
|
||||
value_1, value_3
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
value_2 >= 4
|
||||
ORDER BY
|
||||
2 LIMIT 3;
|
||||
value_1 | value_3
|
||||
---------+---------
|
||||
4 | 4
|
||||
5 | 5
|
||||
(2 rows)
|
||||
|
||||
SELECT
|
||||
value_1, 15 * value_2
|
||||
FROM
|
||||
reference_table_test
|
||||
ORDER BY
|
||||
2 ASC
|
||||
LIMIT 2;
|
||||
value_1 | ?column?
|
||||
---------+----------
|
||||
1 | 15
|
||||
2 | 30
|
||||
(2 rows)
|
||||
|
||||
SELECT
|
||||
value_1, 15 * value_2
|
||||
FROM
|
||||
reference_table_test
|
||||
ORDER BY
|
||||
2 ASC LIMIT 2 OFFSET 2;
|
||||
value_1 | ?column?
|
||||
---------+----------
|
||||
3 | 45
|
||||
4 | 60
|
||||
(2 rows)
|
||||
|
||||
SELECT
|
||||
value_2, value_4
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
value_2 = 2 OR value_2 = 3;
|
||||
value_2 | value_4
|
||||
---------+--------------------------
|
||||
2 | Fri Dec 02 00:00:00 2016
|
||||
3 | Sat Dec 03 00:00:00 2016
|
||||
(2 rows)
|
||||
|
||||
SELECT
|
||||
value_2, value_4
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
value_2 = 2 AND value_2 = 3;
|
||||
value_2 | value_4
|
||||
---------+---------
|
||||
(0 rows)
|
||||
|
||||
SELECT
|
||||
value_2, value_4
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
value_3 = '2' OR value_1 = 3;
|
||||
value_2 | value_4
|
||||
---------+--------------------------
|
||||
2 | Fri Dec 02 00:00:00 2016
|
||||
3 | Sat Dec 03 00:00:00 2016
|
||||
(2 rows)
|
||||
|
||||
SELECT
|
||||
value_2, value_4
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
(
|
||||
value_3 = '2' OR value_1 = 3
|
||||
)
|
||||
AND FALSE;
|
||||
value_2 | value_4
|
||||
---------+---------
|
||||
(0 rows)
|
||||
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
value_2 IN
|
||||
(
|
||||
SELECT
|
||||
value_3::FLOAT
|
||||
FROM
|
||||
reference_table_test
|
||||
)
|
||||
AND value_1 < 3;
|
||||
value_1 | value_2 | value_3 | value_4
|
||||
---------+---------+---------+--------------------------
|
||||
1 | 1 | 1 | Thu Dec 01 00:00:00 2016
|
||||
2 | 2 | 2 | Fri Dec 02 00:00:00 2016
|
||||
(2 rows)
|
||||
|
||||
SELECT
|
||||
value_4
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
value_3 IN
|
||||
(
|
||||
'1', '2'
|
||||
);
|
||||
value_4
|
||||
--------------------------
|
||||
Thu Dec 01 00:00:00 2016
|
||||
Fri Dec 02 00:00:00 2016
|
||||
(2 rows)
|
||||
|
||||
SELECT
|
||||
date_part('day', value_4)
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
value_3 IN
|
||||
(
|
||||
'5', '2'
|
||||
);
|
||||
date_part
|
||||
-----------
|
||||
2
|
||||
5
|
||||
(2 rows)
|
||||
|
||||
SELECT
|
||||
value_4
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
value_2 <= 2 AND value_2 >= 4;
|
||||
value_4
|
||||
---------
|
||||
(0 rows)
|
||||
|
||||
SELECT
|
||||
value_4
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
value_2 <= 20 AND value_2 >= 4;
|
||||
value_4
|
||||
--------------------------
|
||||
Sun Dec 04 00:00:00 2016
|
||||
Mon Dec 05 00:00:00 2016
|
||||
(2 rows)
|
||||
|
||||
SELECT
|
||||
value_4
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
value_2 >= 5 AND value_2 <= random();
|
||||
value_4
|
||||
---------
|
||||
(0 rows)
|
||||
|
||||
SELECT
|
||||
value_1
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
value_4 BETWEEN '2016-12-01' AND '2016-12-03';
|
||||
value_1
|
||||
---------
|
||||
1
|
||||
2
|
||||
3
|
||||
(3 rows)
|
||||
|
||||
SELECT
|
||||
value_1
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
FALSE;
|
||||
value_1
|
||||
---------
|
||||
(0 rows)
|
||||
|
||||
SELECT
|
||||
value_1
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
int4eq(1, 2);
|
||||
value_1
|
||||
---------
|
||||
(0 rows)
|
||||
|
||||
-- rename output name and do some operations
|
||||
SELECT
|
||||
value_1 as id, value_2 * 15 as age
|
||||
FROM
|
||||
reference_table_test;
|
||||
id | age
|
||||
----+-----
|
||||
1 | 15
|
||||
2 | 30
|
||||
3 | 45
|
||||
4 | 60
|
||||
5 | 75
|
||||
(5 rows)
|
||||
|
||||
-- queries with CTEs are supported
|
||||
WITH some_data AS ( SELECT value_2, value_4 FROM reference_table_test WHERE value_2 >=3)
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
some_data;
|
||||
value_2 | value_4
|
||||
---------+--------------------------
|
||||
3 | Sat Dec 03 00:00:00 2016
|
||||
4 | Sun Dec 04 00:00:00 2016
|
||||
5 | Mon Dec 05 00:00:00 2016
|
||||
(3 rows)
|
||||
|
||||
-- queries with CTEs are supported even if CTE is not referenced inside query
|
||||
WITH some_data AS ( SELECT value_2, value_4 FROM reference_table_test WHERE value_2 >=3)
|
||||
SELECT * FROM reference_table_test ORDER BY 1 LIMIT 1;
|
||||
value_1 | value_2 | value_3 | value_4
|
||||
---------+---------+---------+--------------------------
|
||||
1 | 1 | 1 | Thu Dec 01 00:00:00 2016
|
||||
(1 row)
|
||||
|
||||
-- queries which involve functions in FROM clause are supported if it goes to a single worker.
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
reference_table_test, position('om' in 'Thomas')
|
||||
WHERE
|
||||
value_1 = 1;
|
||||
value_1 | value_2 | value_3 | value_4 | position
|
||||
---------+---------+---------+--------------------------+----------
|
||||
1 | 1 | 1 | Thu Dec 01 00:00:00 2016 | 3
|
||||
(1 row)
|
||||
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
reference_table_test, position('om' in 'Thomas')
|
||||
WHERE
|
||||
value_1 = 1 OR value_1 = 2;
|
||||
value_1 | value_2 | value_3 | value_4 | position
|
||||
---------+---------+---------+--------------------------+----------
|
||||
1 | 1 | 1 | Thu Dec 01 00:00:00 2016 | 3
|
||||
2 | 2 | 2 | Fri Dec 02 00:00:00 2016 | 3
|
||||
(2 rows)
|
||||
|
||||
-- set operations are supported
|
||||
(SELECT * FROM reference_table_test WHERE value_1 = 1)
|
||||
UNION
|
||||
(SELECT * FROM reference_table_test WHERE value_1 = 3);
|
||||
value_1 | value_2 | value_3 | value_4
|
||||
---------+---------+---------+--------------------------
|
||||
1 | 1 | 1 | Thu Dec 01 00:00:00 2016
|
||||
3 | 3 | 3 | Sat Dec 03 00:00:00 2016
|
||||
(2 rows)
|
||||
|
||||
(SELECT * FROM reference_table_test WHERE value_1 = 1)
|
||||
EXCEPT
|
||||
(SELECT * FROM reference_table_test WHERE value_1 = 3);
|
||||
value_1 | value_2 | value_3 | value_4
|
||||
---------+---------+---------+--------------------------
|
||||
1 | 1 | 1 | Thu Dec 01 00:00:00 2016
|
||||
(1 row)
|
||||
|
||||
(SELECT * FROM reference_table_test WHERE value_1 = 1)
|
||||
INTERSECT
|
||||
(SELECT * FROM reference_table_test WHERE value_1 = 3);
|
||||
value_1 | value_2 | value_3 | value_4
|
||||
---------+---------+---------+---------
|
||||
(0 rows)
|
||||
|
||||
-- to make the tests more interested for aggregation tests, ingest some more data
|
||||
\c - - - :master_port
|
||||
INSERT INTO reference_table_test VALUES (1, 1.0, '1', '2016-12-01');
|
||||
INSERT INTO reference_table_test VALUES (2, 2.0, '2', '2016-12-02');
|
||||
INSERT INTO reference_table_test VALUES (3, 3.0, '3', '2016-12-03');
|
||||
\c - - - :worker_1_port
|
||||
-- some aggregations
|
||||
SELECT
|
||||
value_4, SUM(value_2)
|
||||
FROM
|
||||
reference_table_test
|
||||
GROUP BY
|
||||
value_4
|
||||
HAVING
|
||||
SUM(value_2) > 3
|
||||
ORDER BY
|
||||
1;
|
||||
value_4 | sum
|
||||
--------------------------+-----
|
||||
Fri Dec 02 00:00:00 2016 | 4
|
||||
Sat Dec 03 00:00:00 2016 | 6
|
||||
Sun Dec 04 00:00:00 2016 | 4
|
||||
Mon Dec 05 00:00:00 2016 | 5
|
||||
(4 rows)
|
||||
|
||||
SELECT
|
||||
value_4,
|
||||
value_3,
|
||||
SUM(value_2)
|
||||
FROM
|
||||
reference_table_test
|
||||
GROUP BY
|
||||
GROUPING sets ((value_4), (value_3))
|
||||
ORDER BY 1, 2, 3;
|
||||
value_4 | value_3 | sum
|
||||
--------------------------+---------+-----
|
||||
Thu Dec 01 00:00:00 2016 | | 2
|
||||
Fri Dec 02 00:00:00 2016 | | 4
|
||||
Sat Dec 03 00:00:00 2016 | | 6
|
||||
Sun Dec 04 00:00:00 2016 | | 4
|
||||
Mon Dec 05 00:00:00 2016 | | 5
|
||||
| 1 | 2
|
||||
| 2 | 4
|
||||
| 3 | 6
|
||||
| 4 | 4
|
||||
| 5 | 5
|
||||
(10 rows)
|
||||
|
||||
-- distinct clauses also work fine
|
||||
SELECT DISTINCT
|
||||
value_4
|
||||
FROM
|
||||
reference_table_test
|
||||
ORDER BY
|
||||
1;
|
||||
value_4
|
||||
--------------------------
|
||||
Thu Dec 01 00:00:00 2016
|
||||
Fri Dec 02 00:00:00 2016
|
||||
Sat Dec 03 00:00:00 2016
|
||||
Sun Dec 04 00:00:00 2016
|
||||
Mon Dec 05 00:00:00 2016
|
||||
(5 rows)
|
||||
|
||||
-- window functions are also supported
|
||||
SELECT
|
||||
value_4, RANK() OVER (PARTITION BY value_1 ORDER BY value_4)
|
||||
FROM
|
||||
reference_table_test;
|
||||
value_4 | rank
|
||||
--------------------------+------
|
||||
Thu Dec 01 00:00:00 2016 | 1
|
||||
Thu Dec 01 00:00:00 2016 | 1
|
||||
Fri Dec 02 00:00:00 2016 | 1
|
||||
Fri Dec 02 00:00:00 2016 | 1
|
||||
Sat Dec 03 00:00:00 2016 | 1
|
||||
Sat Dec 03 00:00:00 2016 | 1
|
||||
Sun Dec 04 00:00:00 2016 | 1
|
||||
Mon Dec 05 00:00:00 2016 | 1
|
||||
(8 rows)
|
||||
|
||||
-- window functions are also supported
|
||||
SELECT
|
||||
value_4, AVG(value_1) OVER (PARTITION BY value_4 ORDER BY value_4)
|
||||
FROM
|
||||
reference_table_test;
|
||||
value_4 | avg
|
||||
--------------------------+------------------------
|
||||
Thu Dec 01 00:00:00 2016 | 1.00000000000000000000
|
||||
Thu Dec 01 00:00:00 2016 | 1.00000000000000000000
|
||||
Fri Dec 02 00:00:00 2016 | 2.0000000000000000
|
||||
Fri Dec 02 00:00:00 2016 | 2.0000000000000000
|
||||
Sat Dec 03 00:00:00 2016 | 3.0000000000000000
|
||||
Sat Dec 03 00:00:00 2016 | 3.0000000000000000
|
||||
Sun Dec 04 00:00:00 2016 | 4.0000000000000000
|
||||
Mon Dec 05 00:00:00 2016 | 5.0000000000000000
|
||||
(8 rows)
|
||||
|
||||
SELECT
|
||||
count(DISTINCT CASE
|
||||
WHEN
|
||||
value_2 >= 3
|
||||
THEN
|
||||
value_2
|
||||
ELSE
|
||||
NULL
|
||||
END) as c
|
||||
FROM
|
||||
reference_table_test;
|
||||
c
|
||||
---
|
||||
3
|
||||
(1 row)
|
||||
|
||||
SELECT
|
||||
value_1,
|
||||
count(DISTINCT CASE
|
||||
WHEN
|
||||
value_2 >= 3
|
||||
THEN
|
||||
value_2
|
||||
ELSE
|
||||
NULL
|
||||
END) as c
|
||||
FROM
|
||||
reference_table_test
|
||||
GROUP BY
|
||||
value_1
|
||||
ORDER BY
|
||||
1;
|
||||
value_1 | c
|
||||
---------+---
|
||||
1 | 0
|
||||
2 | 0
|
||||
3 | 1
|
||||
4 | 1
|
||||
5 | 1
|
||||
(5 rows)
|
||||
|
||||
-- selects inside a transaction works fine as well
|
||||
BEGIN;
|
||||
SELECT * FROM reference_table_test;
|
||||
value_1 | value_2 | value_3 | value_4
|
||||
---------+---------+---------+--------------------------
|
||||
1 | 1 | 1 | Thu Dec 01 00:00:00 2016
|
||||
2 | 2 | 2 | Fri Dec 02 00:00:00 2016
|
||||
3 | 3 | 3 | Sat Dec 03 00:00:00 2016
|
||||
4 | 4 | 4 | Sun Dec 04 00:00:00 2016
|
||||
5 | 5 | 5 | Mon Dec 05 00:00:00 2016
|
||||
1 | 1 | 1 | Thu Dec 01 00:00:00 2016
|
||||
2 | 2 | 2 | Fri Dec 02 00:00:00 2016
|
||||
3 | 3 | 3 | Sat Dec 03 00:00:00 2016
|
||||
(8 rows)
|
||||
|
||||
SELECT * FROM reference_table_test WHERE value_1 = 1;
|
||||
value_1 | value_2 | value_3 | value_4
|
||||
---------+---------+---------+--------------------------
|
||||
1 | 1 | 1 | Thu Dec 01 00:00:00 2016
|
||||
1 | 1 | 1 | Thu Dec 01 00:00:00 2016
|
||||
(2 rows)
|
||||
|
||||
END;
|
||||
-- cursor queries also works fine
|
||||
BEGIN;
|
||||
DECLARE test_cursor CURSOR FOR
|
||||
SELECT *
|
||||
FROM reference_table_test
|
||||
WHERE value_1 = 1 OR value_1 = 2
|
||||
ORDER BY value_1;
|
||||
FETCH test_cursor;
|
||||
value_1 | value_2 | value_3 | value_4
|
||||
---------+---------+---------+--------------------------
|
||||
1 | 1 | 1 | Thu Dec 01 00:00:00 2016
|
||||
(1 row)
|
||||
|
||||
FETCH ALL test_cursor;
|
||||
value_1 | value_2 | value_3 | value_4
|
||||
---------+---------+---------+--------------------------
|
||||
1 | 1 | 1 | Thu Dec 01 00:00:00 2016
|
||||
2 | 2 | 2 | Fri Dec 02 00:00:00 2016
|
||||
2 | 2 | 2 | Fri Dec 02 00:00:00 2016
|
||||
(3 rows)
|
||||
|
||||
FETCH test_cursor; -- fetch one row after the last
|
||||
value_1 | value_2 | value_3 | value_4
|
||||
---------+---------+---------+---------
|
||||
(0 rows)
|
||||
|
||||
END;
|
||||
-- table creation queries inside can be router plannable
|
||||
CREATE TEMP TABLE temp_reference_test as
|
||||
SELECT *
|
||||
FROM reference_table_test
|
||||
WHERE value_1 = 1;
|
||||
\c - - - :master_port
|
||||
-- all kinds of joins are supported among reference tables
|
||||
-- first create two more tables
|
||||
CREATE TABLE reference_table_test_second (value_1 int, value_2 float, value_3 text, value_4 timestamp);
|
||||
SELECT create_reference_table('reference_table_test_second');
|
||||
create_reference_table
|
||||
------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
CREATE TABLE reference_table_test_third (value_1 int, value_2 float, value_3 text, value_4 timestamp);
|
||||
SELECT create_reference_table('reference_table_test_third');
|
||||
create_reference_table
|
||||
------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- ingest some data to both tables
|
||||
INSERT INTO reference_table_test_second VALUES (1, 1.0, '1', '2016-12-01');
|
||||
INSERT INTO reference_table_test_second VALUES (2, 2.0, '2', '2016-12-02');
|
||||
INSERT INTO reference_table_test_second VALUES (3, 3.0, '3', '2016-12-03');
|
||||
INSERT INTO reference_table_test_third VALUES (4, 4.0, '4', '2016-12-04');
|
||||
INSERT INTO reference_table_test_third VALUES (5, 5.0, '5', '2016-12-05');
|
||||
\c - - - :worker_2_port
|
||||
-- some very basic tests
|
||||
SELECT
|
||||
DISTINCT t1.value_1
|
||||
FROM
|
||||
reference_table_test t1, reference_table_test_second t2
|
||||
WHERE
|
||||
t1.value_2 = t2.value_2
|
||||
ORDER BY
|
||||
1;
|
||||
value_1
|
||||
---------
|
||||
1
|
||||
2
|
||||
3
|
||||
(3 rows)
|
||||
|
||||
SELECT
|
||||
DISTINCT t1.value_1
|
||||
FROM
|
||||
reference_table_test t1, reference_table_test_third t3
|
||||
WHERE
|
||||
t1.value_2 = t3.value_2
|
||||
ORDER BY
|
||||
1;
|
||||
value_1
|
||||
---------
|
||||
4
|
||||
5
|
||||
(2 rows)
|
||||
|
||||
SELECT
|
||||
DISTINCT t2.value_1
|
||||
FROM
|
||||
reference_table_test_second t2, reference_table_test_third t3
|
||||
WHERE
|
||||
t2.value_2 = t3.value_2
|
||||
ORDER BY
|
||||
1;
|
||||
value_1
|
||||
---------
|
||||
(0 rows)
|
||||
|
||||
-- join on different columns and different data types via casts
|
||||
SELECT
|
||||
DISTINCT t1.value_1
|
||||
FROM
|
||||
reference_table_test t1, reference_table_test_second t2
|
||||
WHERE
|
||||
t1.value_2 = t2.value_1
|
||||
ORDER BY
|
||||
1;
|
||||
value_1
|
||||
---------
|
||||
1
|
||||
2
|
||||
3
|
||||
(3 rows)
|
||||
|
||||
SELECT
|
||||
DISTINCT t1.value_1
|
||||
FROM
|
||||
reference_table_test t1, reference_table_test_second t2
|
||||
WHERE
|
||||
t1.value_2 = t2.value_3::int
|
||||
ORDER BY
|
||||
1;
|
||||
value_1
|
||||
---------
|
||||
1
|
||||
2
|
||||
3
|
||||
(3 rows)
|
||||
|
||||
SELECT
|
||||
DISTINCT t1.value_1
|
||||
FROM
|
||||
reference_table_test t1, reference_table_test_second t2
|
||||
WHERE
|
||||
t1.value_2 = date_part('day', t2.value_4)
|
||||
ORDER BY
|
||||
1;
|
||||
value_1
|
||||
---------
|
||||
1
|
||||
2
|
||||
3
|
||||
(3 rows)
|
||||
|
||||
-- ingest a common row to see more meaningful results with joins involving 3 tables
|
||||
\c - - - :master_port
|
||||
INSERT INTO reference_table_test_third VALUES (3, 3.0, '3', '2016-12-03');
|
||||
\c - - - :worker_1_port
|
||||
SELECT
|
||||
DISTINCT t1.value_1
|
||||
FROM
|
||||
reference_table_test t1, reference_table_test_second t2, reference_table_test_third t3
|
||||
WHERE
|
||||
t1.value_2 = date_part('day', t2.value_4) AND t3.value_2 = t1.value_2
|
||||
ORDER BY
|
||||
1;
|
||||
value_1
|
||||
---------
|
||||
3
|
||||
(1 row)
|
||||
|
||||
-- same query on different columns
|
||||
SELECT
|
||||
DISTINCT t1.value_1
|
||||
FROM
|
||||
reference_table_test t1, reference_table_test_second t2, reference_table_test_third t3
|
||||
WHERE
|
||||
t1.value_1 = date_part('day', t2.value_4) AND t3.value_2 = t1.value_1
|
||||
ORDER BY
|
||||
1;
|
||||
value_1
|
||||
---------
|
||||
3
|
||||
(1 row)
|
||||
|
||||
-- with the JOIN syntax
|
||||
SELECT
|
||||
DISTINCT t1.value_1
|
||||
FROM
|
||||
reference_table_test t1 JOIN reference_table_test_second t2 USING (value_1)
|
||||
JOIN reference_table_test_third t3 USING (value_1)
|
||||
ORDER BY
|
||||
1;
|
||||
value_1
|
||||
---------
|
||||
3
|
||||
(1 row)
|
||||
|
||||
-- and left/right joins
|
||||
SELECT
|
||||
DISTINCT t1.value_1
|
||||
FROM
|
||||
reference_table_test t1 LEFT JOIN reference_table_test_second t2 USING (value_1)
|
||||
LEFT JOIN reference_table_test_third t3 USING (value_1)
|
||||
ORDER BY
|
||||
1;
|
||||
value_1
|
||||
---------
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
(5 rows)
|
||||
|
||||
SELECT
|
||||
DISTINCT t1.value_1
|
||||
FROM
|
||||
reference_table_test t1 RIGHT JOIN reference_table_test_second t2 USING (value_1)
|
||||
RIGHT JOIN reference_table_test_third t3 USING (value_1)
|
||||
ORDER BY
|
||||
1;
|
||||
value_1
|
||||
---------
|
||||
3
|
||||
|
||||
(2 rows)
|
||||
|
||||
\c - - - :master_port
|
||||
SET citus.shard_count TO 6;
|
||||
SET citus.shard_replication_factor TO 1;
|
||||
SET citus.replication_model TO streaming;
|
||||
CREATE TABLE colocated_table_test (value_1 int, value_2 float, value_3 text, value_4 timestamp);
|
||||
SELECT create_distributed_table('colocated_table_test', 'value_1');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
CREATE TABLE colocated_table_test_2 (value_1 int, value_2 float, value_3 text, value_4 timestamp);
|
||||
SELECT create_distributed_table('colocated_table_test_2', 'value_1');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
DELETE FROM reference_table_test;
|
||||
INSERT INTO reference_table_test VALUES (1, 1.0, '1', '2016-12-01');
|
||||
INSERT INTO reference_table_test VALUES (2, 2.0, '2', '2016-12-02');
|
||||
INSERT INTO colocated_table_test VALUES (1, 1.0, '1', '2016-12-01');
|
||||
INSERT INTO colocated_table_test VALUES (2, 2.0, '2', '2016-12-02');
|
||||
INSERT INTO colocated_table_test_2 VALUES (1, 1.0, '1', '2016-12-01');
|
||||
INSERT INTO colocated_table_test_2 VALUES (2, 2.0, '2', '2016-12-02');
|
||||
\c - - - :worker_1_port
|
||||
SET client_min_messages TO DEBUG1;
|
||||
SET citus.log_multi_join_order TO TRUE;
|
||||
SELECT
|
||||
reference_table_test.value_1
|
||||
FROM
|
||||
reference_table_test, colocated_table_test
|
||||
WHERE
|
||||
colocated_table_test.value_1 = reference_table_test.value_1;
|
||||
LOG: join order: [ "colocated_table_test" ][ broadcast join "reference_table_test" ]
|
||||
value_1
|
||||
---------
|
||||
1
|
||||
2
|
||||
(2 rows)
|
||||
|
||||
SELECT
|
||||
colocated_table_test.value_2
|
||||
FROM
|
||||
reference_table_test, colocated_table_test
|
||||
WHERE
|
||||
colocated_table_test.value_2 = reference_table_test.value_2;
|
||||
LOG: join order: [ "colocated_table_test" ][ broadcast join "reference_table_test" ]
|
||||
value_2
|
||||
---------
|
||||
1
|
||||
2
|
||||
(2 rows)
|
||||
|
||||
SELECT
|
||||
colocated_table_test.value_2
|
||||
FROM
|
||||
colocated_table_test, reference_table_test
|
||||
WHERE
|
||||
reference_table_test.value_1 = colocated_table_test.value_1;
|
||||
LOG: join order: [ "colocated_table_test" ][ broadcast join "reference_table_test" ]
|
||||
value_2
|
||||
---------
|
||||
1
|
||||
2
|
||||
(2 rows)
|
||||
|
||||
SELECT
|
||||
colocated_table_test.value_2
|
||||
FROM
|
||||
reference_table_test, colocated_table_test, colocated_table_test_2
|
||||
WHERE
|
||||
colocated_table_test.value_2 = reference_table_test.value_2;
|
||||
LOG: join order: [ "colocated_table_test" ][ broadcast join "reference_table_test" ][ cartesian product "colocated_table_test_2" ]
|
||||
ERROR: cannot perform distributed planning on this query
|
||||
DETAIL: Cartesian products are currently unsupported
|
||||
SELECT
|
||||
colocated_table_test.value_2
|
||||
FROM
|
||||
reference_table_test, colocated_table_test, colocated_table_test_2
|
||||
WHERE
|
||||
colocated_table_test.value_1 = colocated_table_test_2.value_1 AND colocated_table_test.value_2 = reference_table_test.value_2;
|
||||
LOG: join order: [ "colocated_table_test" ][ broadcast join "reference_table_test" ][ local partition join "colocated_table_test_2" ]
|
||||
value_2
|
||||
---------
|
||||
1
|
||||
2
|
||||
(2 rows)
|
||||
|
||||
SET citus.task_executor_type to "task-tracker";
|
||||
SELECT
|
||||
colocated_table_test.value_2
|
||||
FROM
|
||||
reference_table_test, colocated_table_test, colocated_table_test_2
|
||||
WHERE
|
||||
colocated_table_test.value_2 = colocated_table_test_2.value_2 AND colocated_table_test.value_2 = reference_table_test.value_2;
|
||||
LOG: join order: [ "colocated_table_test" ][ broadcast join "reference_table_test" ][ dual partition join "colocated_table_test_2" ]
|
||||
value_2
|
||||
---------
|
||||
1
|
||||
2
|
||||
(2 rows)
|
||||
|
||||
SELECT
|
||||
reference_table_test.value_2
|
||||
FROM
|
||||
reference_table_test, colocated_table_test, colocated_table_test_2
|
||||
WHERE
|
||||
colocated_table_test.value_1 = reference_table_test.value_1 AND colocated_table_test_2.value_1 = reference_table_test.value_1;
|
||||
LOG: join order: [ "colocated_table_test" ][ broadcast join "reference_table_test" ][ dual partition join "colocated_table_test_2" ]
|
||||
value_2
|
||||
---------
|
||||
1
|
||||
2
|
||||
(2 rows)
|
||||
|
||||
SET client_min_messages TO NOTICE;
|
||||
SET citus.log_multi_join_order TO FALSE;
|
||||
-- clean up tables
|
||||
\c - - - :master_port
|
||||
DROP TABLE reference_table_test, reference_table_test_second, reference_table_test_third;;
|
|
@ -0,0 +1,13 @@
|
|||
-- Test two concurrent reparttition joins from two different workers
|
||||
-- This test runs the below query from the :worker_1_port and the
|
||||
-- concurrent test runs the same query on :worker_2_port. Note that, both
|
||||
-- tests use the same sequence ids but the queries should not fail.
|
||||
\c - - - :worker_1_port
|
||||
SET citus.task_executor_type TO "task-tracker";
|
||||
CREATE TEMP TABLE t1 AS
|
||||
SELECT
|
||||
l1.l_comment
|
||||
FROM
|
||||
lineitem_mx l1, orders_mx l2
|
||||
WHERE
|
||||
l1.l_comment = l2.o_comment;
|
|
@ -0,0 +1,13 @@
|
|||
-- Test two concurrent reparttition joins from two different workers
|
||||
-- This test runs the below query from the :worker_2_port and the
|
||||
-- concurrent test runs the same query on :worker_1_port. Note that, both
|
||||
-- tests use the same sequence ids but the queries should not fail.
|
||||
\c - - - :worker_2_port
|
||||
SET citus.task_executor_type TO "task-tracker";
|
||||
CREATE TEMP TABLE t1 AS
|
||||
SELECT
|
||||
l1.l_comment
|
||||
FROM
|
||||
lineitem_mx l1, orders_mx l2
|
||||
WHERE
|
||||
l1.l_comment = l2.o_comment;
|
|
@ -0,0 +1,210 @@
|
|||
--
|
||||
-- MULTI_MX_REPARTITION_UDT_PREPARE
|
||||
--
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 535000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 535000;
|
||||
-- START type creation
|
||||
CREATE TYPE test_udt AS (i integer, i2 integer);
|
||||
-- ... as well as a function to use as its comparator...
|
||||
CREATE FUNCTION equal_test_udt_function(test_udt, test_udt) RETURNS boolean
|
||||
AS 'select $1.i = $2.i AND $1.i2 = $2.i2;'
|
||||
LANGUAGE SQL
|
||||
IMMUTABLE
|
||||
RETURNS NULL ON NULL INPUT;
|
||||
-- ... use that function to create a custom equality operator...
|
||||
CREATE OPERATOR = (
|
||||
LEFTARG = test_udt,
|
||||
RIGHTARG = test_udt,
|
||||
PROCEDURE = equal_test_udt_function,
|
||||
COMMUTATOR = =,
|
||||
HASHES
|
||||
);
|
||||
-- ... and create a custom operator family for hash indexes...
|
||||
CREATE OPERATOR FAMILY tudt_op_fam USING hash;
|
||||
-- ... create a test HASH function. Though it is a poor hash function,
|
||||
-- it is acceptable for our tests
|
||||
CREATE FUNCTION test_udt_hash(test_udt) RETURNS int
|
||||
AS 'SELECT hashtext( ($1.i + $1.i2)::text);'
|
||||
LANGUAGE SQL
|
||||
IMMUTABLE
|
||||
RETURNS NULL ON NULL INPUT;
|
||||
-- We need to define two different operator classes for the composite types
|
||||
-- One uses BTREE the other uses HASH
|
||||
CREATE OPERATOR CLASS tudt_op_fam_clas3
|
||||
DEFAULT FOR TYPE test_udt USING BTREE AS
|
||||
OPERATOR 3 = (test_udt, test_udt);
|
||||
CREATE OPERATOR CLASS tudt_op_fam_class
|
||||
DEFAULT FOR TYPE test_udt USING HASH AS
|
||||
OPERATOR 1 = (test_udt, test_udt),
|
||||
FUNCTION 1 test_udt_hash(test_udt);
|
||||
-- END type creation
|
||||
CREATE TABLE repartition_udt (
|
||||
pk integer not null,
|
||||
udtcol test_udt,
|
||||
txtcol text
|
||||
);
|
||||
CREATE TABLE repartition_udt_other (
|
||||
pk integer not null,
|
||||
udtcol test_udt,
|
||||
txtcol text
|
||||
);
|
||||
-- Connect directly to a worker, create and drop the type, then
|
||||
-- proceed with type creation as above; thus the OIDs will be different.
|
||||
-- so that the OID is off.
|
||||
\c - - - :worker_1_port
|
||||
CREATE TYPE test_udt AS (i integer, i2 integer);
|
||||
DROP TYPE test_udt CASCADE;
|
||||
-- START type creation
|
||||
CREATE TYPE test_udt AS (i integer, i2 integer);
|
||||
-- ... as well as a function to use as its comparator...
|
||||
CREATE FUNCTION equal_test_udt_function(test_udt, test_udt) RETURNS boolean
|
||||
AS 'select $1.i = $2.i AND $1.i2 = $2.i2;'
|
||||
LANGUAGE SQL
|
||||
IMMUTABLE
|
||||
RETURNS NULL ON NULL INPUT;
|
||||
-- ... use that function to create a custom equality operator...
|
||||
CREATE OPERATOR = (
|
||||
LEFTARG = test_udt,
|
||||
RIGHTARG = test_udt,
|
||||
PROCEDURE = equal_test_udt_function,
|
||||
COMMUTATOR = =,
|
||||
HASHES
|
||||
);
|
||||
-- ... and create a custom operator family for hash indexes...
|
||||
CREATE OPERATOR FAMILY tudt_op_fam USING hash;
|
||||
-- ... create a test HASH function. Though it is a poor hash function,
|
||||
-- it is acceptable for our tests
|
||||
CREATE FUNCTION test_udt_hash(test_udt) RETURNS int
|
||||
AS 'SELECT hashtext( ($1.i + $1.i2)::text);'
|
||||
LANGUAGE SQL
|
||||
IMMUTABLE
|
||||
RETURNS NULL ON NULL INPUT;
|
||||
-- We need to define two different operator classes for the composite types
|
||||
-- One uses BTREE the other uses HASH
|
||||
CREATE OPERATOR CLASS tudt_op_fam_clas3
|
||||
DEFAULT FOR TYPE test_udt USING BTREE AS
|
||||
OPERATOR 3 = (test_udt, test_udt);
|
||||
CREATE OPERATOR CLASS tudt_op_fam_class
|
||||
DEFAULT FOR TYPE test_udt USING HASH AS
|
||||
OPERATOR 1 = (test_udt, test_udt),
|
||||
FUNCTION 1 test_udt_hash(test_udt);
|
||||
-- END type creation
|
||||
\c - - - :worker_2_port
|
||||
-- START type creation
|
||||
CREATE TYPE test_udt AS (i integer, i2 integer);
|
||||
-- ... as well as a function to use as its comparator...
|
||||
CREATE FUNCTION equal_test_udt_function(test_udt, test_udt) RETURNS boolean
|
||||
AS 'select $1.i = $2.i AND $1.i2 = $2.i2;'
|
||||
LANGUAGE SQL
|
||||
IMMUTABLE
|
||||
RETURNS NULL ON NULL INPUT;
|
||||
-- ... use that function to create a custom equality operator...
|
||||
CREATE OPERATOR = (
|
||||
LEFTARG = test_udt,
|
||||
RIGHTARG = test_udt,
|
||||
PROCEDURE = equal_test_udt_function,
|
||||
COMMUTATOR = =,
|
||||
HASHES
|
||||
);
|
||||
-- ... and create a custom operator family for hash indexes...
|
||||
CREATE OPERATOR FAMILY tudt_op_fam USING hash;
|
||||
-- ... create a test HASH function. Though it is a poor hash function,
|
||||
-- it is acceptable for our tests
|
||||
CREATE FUNCTION test_udt_hash(test_udt) RETURNS int
|
||||
AS 'SELECT hashtext( ($1.i + $1.i2)::text);'
|
||||
LANGUAGE SQL
|
||||
IMMUTABLE
|
||||
RETURNS NULL ON NULL INPUT;
|
||||
-- We need to define two different operator classes for the composite types
|
||||
-- One uses BTREE the other uses HASH
|
||||
CREATE OPERATOR CLASS tudt_op_fam_clas3
|
||||
DEFAULT FOR TYPE test_udt USING BTREE AS
|
||||
OPERATOR 3 = (test_udt, test_udt);
|
||||
CREATE OPERATOR CLASS tudt_op_fam_class
|
||||
DEFAULT FOR TYPE test_udt USING HASH AS
|
||||
OPERATOR 1 = (test_udt, test_udt),
|
||||
FUNCTION 1 test_udt_hash(test_udt);
|
||||
-- END type creation
|
||||
-- Connect to master
|
||||
\c - - - :master_port
|
||||
-- Distribute and populate the two tables.
|
||||
SET citus.shard_replication_factor TO 1;
|
||||
SET citus.replication_model TO streaming;
|
||||
SET citus.shard_count TO 3;
|
||||
SELECT create_distributed_table('repartition_udt', 'pk');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SET citus.shard_count TO 5;
|
||||
SELECT create_distributed_table('repartition_udt_other', 'pk');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
INSERT INTO repartition_udt values (1, '(1,1)'::test_udt, 'foo');
|
||||
INSERT INTO repartition_udt values (2, '(1,2)'::test_udt, 'foo');
|
||||
INSERT INTO repartition_udt values (3, '(1,3)'::test_udt, 'foo');
|
||||
INSERT INTO repartition_udt values (4, '(2,1)'::test_udt, 'foo');
|
||||
INSERT INTO repartition_udt values (5, '(2,2)'::test_udt, 'foo');
|
||||
INSERT INTO repartition_udt values (6, '(2,3)'::test_udt, 'foo');
|
||||
INSERT INTO repartition_udt_other values (7, '(1,1)'::test_udt, 'foo');
|
||||
INSERT INTO repartition_udt_other values (8, '(1,2)'::test_udt, 'foo');
|
||||
INSERT INTO repartition_udt_other values (9, '(1,3)'::test_udt, 'foo');
|
||||
INSERT INTO repartition_udt_other values (10, '(2,1)'::test_udt, 'foo');
|
||||
INSERT INTO repartition_udt_other values (11, '(2,2)'::test_udt, 'foo');
|
||||
INSERT INTO repartition_udt_other values (12, '(2,3)'::test_udt, 'foo');
|
||||
SET client_min_messages = LOG;
|
||||
-- Query that should result in a repartition join on int column, and be empty.
|
||||
SELECT * FROM repartition_udt JOIN repartition_udt_other
|
||||
ON repartition_udt.pk = repartition_udt_other.pk
|
||||
WHERE repartition_udt.pk > 1;
|
||||
pk | udtcol | txtcol | pk | udtcol | txtcol
|
||||
----+--------+--------+----+--------+--------
|
||||
(0 rows)
|
||||
|
||||
-- Query that should result in a repartition join on UDT column.
|
||||
SET citus.large_table_shard_count = 1;
|
||||
SET citus.task_executor_type = 'task-tracker';
|
||||
SET citus.log_multi_join_order = true;
|
||||
EXPLAIN SELECT * FROM repartition_udt JOIN repartition_udt_other
|
||||
ON repartition_udt.udtcol = repartition_udt_other.udtcol
|
||||
WHERE repartition_udt.pk > 1;
|
||||
LOG: join order: [ "repartition_udt" ][ dual partition join "repartition_udt_other" ]
|
||||
QUERY PLAN
|
||||
-------------------------------------------------------------------------
|
||||
Distributed Query into pg_merge_job_535003
|
||||
Executor: Task-Tracker
|
||||
Task Count: 4
|
||||
Tasks Shown: None, not supported for re-partition queries
|
||||
-> MapMergeJob
|
||||
Map Task Count: 3
|
||||
Merge Task Count: 4
|
||||
-> MapMergeJob
|
||||
Map Task Count: 5
|
||||
Merge Task Count: 4
|
||||
Master Query
|
||||
-> Seq Scan on pg_merge_job_535003 (cost=0.00..0.00 rows=0 width=0)
|
||||
(12 rows)
|
||||
|
||||
SELECT * FROM repartition_udt JOIN repartition_udt_other
|
||||
ON repartition_udt.udtcol = repartition_udt_other.udtcol
|
||||
WHERE repartition_udt.pk > 1
|
||||
ORDER BY repartition_udt.pk;
|
||||
LOG: join order: [ "repartition_udt" ][ dual partition join "repartition_udt_other" ]
|
||||
pk | udtcol | txtcol | pk | udtcol | txtcol
|
||||
----+--------+--------+----+--------+--------
|
||||
2 | (1,2) | foo | 8 | (1,2) | foo
|
||||
3 | (1,3) | foo | 9 | (1,3) | foo
|
||||
4 | (2,1) | foo | 10 | (2,1) | foo
|
||||
5 | (2,2) | foo | 11 | (2,2) | foo
|
||||
6 | (2,3) | foo | 12 | (2,3) | foo
|
||||
(5 rows)
|
||||
|
||||
|
||||
\c - - - :worker_1_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 535000;
|
||||
\c - - - :worker_2_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 535000;
|
|
@ -0,0 +1,32 @@
|
|||
--
|
||||
-- MULTI_MX_REPARTITION_W1_UDT
|
||||
--
|
||||
\c - - - :worker_1_port
|
||||
SET client_min_messages = LOG;
|
||||
-- Query that should result in a repartition join on UDT column.
|
||||
SET citus.large_table_shard_count = 1;
|
||||
SET citus.task_executor_type = 'task-tracker';
|
||||
SET citus.log_multi_join_order = true;
|
||||
-- Query that should result in a repartition join on int column, and be empty.
|
||||
SELECT * FROM repartition_udt JOIN repartition_udt_other
|
||||
ON repartition_udt.pk = repartition_udt_other.pk
|
||||
WHERE repartition_udt.pk > 1;
|
||||
LOG: join order: [ "repartition_udt" ][ local partition join "repartition_udt_other" ]
|
||||
pk | udtcol | txtcol | pk | udtcol | txtcol
|
||||
----+--------+--------+----+--------+--------
|
||||
(0 rows)
|
||||
|
||||
SELECT * FROM repartition_udt JOIN repartition_udt_other
|
||||
ON repartition_udt.udtcol = repartition_udt_other.udtcol
|
||||
WHERE repartition_udt.pk > 1
|
||||
ORDER BY repartition_udt.pk;
|
||||
LOG: join order: [ "repartition_udt" ][ dual partition join "repartition_udt_other" ]
|
||||
pk | udtcol | txtcol | pk | udtcol | txtcol
|
||||
----+--------+--------+----+--------+--------
|
||||
2 | (1,2) | foo | 8 | (1,2) | foo
|
||||
3 | (1,3) | foo | 9 | (1,3) | foo
|
||||
4 | (2,1) | foo | 10 | (2,1) | foo
|
||||
5 | (2,2) | foo | 11 | (2,2) | foo
|
||||
6 | (2,3) | foo | 12 | (2,3) | foo
|
||||
(5 rows)
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
--
|
||||
-- MULTI_MX_REPARTITION_W2_UDT
|
||||
--
|
||||
\c - - - :worker_2_port
|
||||
SET client_min_messages = LOG;
|
||||
-- Query that should result in a repartition join on UDT column.
|
||||
SET citus.large_table_shard_count = 1;
|
||||
SET citus.task_executor_type = 'task-tracker';
|
||||
SET citus.log_multi_join_order = true;
|
||||
-- Query that should result in a repartition join on int column, and be empty.
|
||||
SELECT * FROM repartition_udt JOIN repartition_udt_other
|
||||
ON repartition_udt.pk = repartition_udt_other.pk
|
||||
WHERE repartition_udt.pk > 1;
|
||||
LOG: join order: [ "repartition_udt" ][ local partition join "repartition_udt_other" ]
|
||||
pk | udtcol | txtcol | pk | udtcol | txtcol
|
||||
----+--------+--------+----+--------+--------
|
||||
(0 rows)
|
||||
|
||||
SELECT * FROM repartition_udt JOIN repartition_udt_other
|
||||
ON repartition_udt.udtcol = repartition_udt_other.udtcol
|
||||
WHERE repartition_udt.pk > 1
|
||||
ORDER BY repartition_udt.pk;
|
||||
LOG: join order: [ "repartition_udt" ][ dual partition join "repartition_udt_other" ]
|
||||
pk | udtcol | txtcol | pk | udtcol | txtcol
|
||||
----+--------+--------+----+--------+--------
|
||||
2 | (1,2) | foo | 8 | (1,2) | foo
|
||||
3 | (1,3) | foo | 9 | (1,3) | foo
|
||||
4 | (2,1) | foo | 10 | (2,1) | foo
|
||||
5 | (2,2) | foo | 11 | (2,2) | foo
|
||||
6 | (2,3) | foo | 12 | (2,3) | foo
|
||||
(5 rows)
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,355 @@
|
|||
--
|
||||
-- MULTI_MX_SCHEMA_SUPPORT
|
||||
--
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1210000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1210000;
|
||||
-- connect to a worker node and run some queries
|
||||
\c - - - :worker_1_port
|
||||
-- test very basic queries
|
||||
SELECT * FROM nation_hash ORDER BY n_nationkey LIMIT 4;
|
||||
n_nationkey | n_name | n_regionkey | n_comment
|
||||
-------------+---------------------------+-------------+-------------------------------------------------------------------------------------------------------------
|
||||
0 | ALGERIA | 0 | haggle. carefully final deposits detect slyly agai
|
||||
1 | ARGENTINA | 1 | al foxes promise slyly according to the regular accounts. bold requests alon
|
||||
2 | BRAZIL | 1 | y alongside of the pending deposits. carefully special packages are about the ironic forges. slyly special
|
||||
3 | CANADA | 1 | eas hang ironic, silent packages. slyly regular packages are furiously over the tithes. fluffily bold
|
||||
(4 rows)
|
||||
|
||||
SELECT * FROM citus_mx_test_schema.nation_hash ORDER BY n_nationkey LIMIT 4;
|
||||
n_nationkey | n_name | n_regionkey | n_comment
|
||||
-------------+---------------------------+-------------+-------------------------------------------------------------------------------------------------------------
|
||||
0 | ALGERIA | 0 | haggle. carefully final deposits detect slyly agai
|
||||
1 | ARGENTINA | 1 | al foxes promise slyly according to the regular accounts. bold requests alon
|
||||
2 | BRAZIL | 1 | y alongside of the pending deposits. carefully special packages are about the ironic forges. slyly special
|
||||
3 | CANADA | 1 | eas hang ironic, silent packages. slyly regular packages are furiously over the tithes. fluffily bold
|
||||
(4 rows)
|
||||
|
||||
-- test cursors
|
||||
SET search_path TO public;
|
||||
BEGIN;
|
||||
DECLARE test_cursor CURSOR FOR
|
||||
SELECT *
|
||||
FROM nation_hash
|
||||
WHERE n_nationkey = 1;
|
||||
FETCH test_cursor;
|
||||
n_nationkey | n_name | n_regionkey | n_comment
|
||||
-------------+---------------------------+-------------+------------------------------------------------------------------------------
|
||||
1 | ARGENTINA | 1 | al foxes promise slyly according to the regular accounts. bold requests alon
|
||||
(1 row)
|
||||
|
||||
END;
|
||||
-- test with search_path is set
|
||||
SET search_path TO citus_mx_test_schema;
|
||||
BEGIN;
|
||||
DECLARE test_cursor CURSOR FOR
|
||||
SELECT *
|
||||
FROM nation_hash
|
||||
WHERE n_nationkey = 1;
|
||||
FETCH test_cursor;
|
||||
n_nationkey | n_name | n_regionkey | n_comment
|
||||
-------------+---------------------------+-------------+------------------------------------------------------------------------------
|
||||
1 | ARGENTINA | 1 | al foxes promise slyly according to the regular accounts. bold requests alon
|
||||
(1 row)
|
||||
|
||||
END;
|
||||
-- test inserting to table in different schema
|
||||
SET search_path TO public;
|
||||
INSERT INTO citus_mx_test_schema.nation_hash(n_nationkey, n_name, n_regionkey) VALUES (100, 'TURKEY', 3);
|
||||
-- verify insertion
|
||||
SELECT * FROM citus_mx_test_schema.nation_hash WHERE n_nationkey = 100;
|
||||
n_nationkey | n_name | n_regionkey | n_comment
|
||||
-------------+---------------------------+-------------+-----------
|
||||
100 | TURKEY | 3 |
|
||||
(1 row)
|
||||
|
||||
-- test with search_path is set
|
||||
SET search_path TO citus_mx_test_schema;
|
||||
INSERT INTO nation_hash(n_nationkey, n_name, n_regionkey) VALUES (101, 'GERMANY', 3);
|
||||
-- verify insertion
|
||||
SELECT * FROM nation_hash WHERE n_nationkey = 101;
|
||||
n_nationkey | n_name | n_regionkey | n_comment
|
||||
-------------+---------------------------+-------------+-----------
|
||||
101 | GERMANY | 3 |
|
||||
(1 row)
|
||||
|
||||
-- TODO: add UPDATE/DELETE/UPSERT
|
||||
-- test UDFs with schemas
|
||||
SET search_path TO public;
|
||||
-- UDF in public, table in a schema other than public, search_path is not set
|
||||
SELECT simpleTestFunction(n_nationkey)::int FROM citus_mx_test_schema.nation_hash GROUP BY 1 ORDER BY 1 DESC LIMIT 5;
|
||||
simpletestfunction
|
||||
--------------------
|
||||
152
|
||||
151
|
||||
37
|
||||
35
|
||||
34
|
||||
(5 rows)
|
||||
|
||||
-- UDF in public, table in a schema other than public, search_path is set
|
||||
SET search_path TO citus_mx_test_schema;
|
||||
SELECT public.simpleTestFunction(n_nationkey)::int FROM citus_mx_test_schema.nation_hash GROUP BY 1 ORDER BY 1 DESC LIMIT 5;
|
||||
simpletestfunction
|
||||
--------------------
|
||||
152
|
||||
151
|
||||
37
|
||||
35
|
||||
34
|
||||
(5 rows)
|
||||
|
||||
-- UDF in schema, table in a schema other than public, search_path is not set
|
||||
SET search_path TO public;
|
||||
SELECT citus_mx_test_schema.simpleTestFunction2(n_nationkey)::int FROM citus_mx_test_schema.nation_hash GROUP BY 1 ORDER BY 1 DESC LIMIT 5;
|
||||
simpletestfunction2
|
||||
---------------------
|
||||
152
|
||||
151
|
||||
37
|
||||
35
|
||||
34
|
||||
(5 rows)
|
||||
|
||||
-- UDF in schema, table in a schema other than public, search_path is set
|
||||
SET search_path TO citus_mx_test_schema;
|
||||
SELECT simpleTestFunction2(n_nationkey)::int FROM nation_hash GROUP BY 1 ORDER BY 1 DESC LIMIT 5;
|
||||
simpletestfunction2
|
||||
---------------------
|
||||
152
|
||||
151
|
||||
37
|
||||
35
|
||||
34
|
||||
(5 rows)
|
||||
|
||||
-- test operators with schema
|
||||
SET search_path TO public;
|
||||
-- test with search_path is not set
|
||||
SELECT * FROM citus_mx_test_schema.nation_hash WHERE n_nationkey OPERATOR(citus_mx_test_schema.===) 1;
|
||||
n_nationkey | n_name | n_regionkey | n_comment
|
||||
-------------+---------------------------+-------------+------------------------------------------------------------------------------
|
||||
1 | ARGENTINA | 1 | al foxes promise slyly according to the regular accounts. bold requests alon
|
||||
(1 row)
|
||||
|
||||
-- test with search_path is set
|
||||
SET search_path TO citus_mx_test_schema;
|
||||
SELECT * FROM nation_hash WHERE n_nationkey OPERATOR(===) 1;
|
||||
n_nationkey | n_name | n_regionkey | n_comment
|
||||
-------------+---------------------------+-------------+------------------------------------------------------------------------------
|
||||
1 | ARGENTINA | 1 | al foxes promise slyly according to the regular accounts. bold requests alon
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM citus_mx_test_schema.nation_hash_collation_search_path;
|
||||
n_nationkey | n_name | n_regionkey | n_comment
|
||||
-------------+---------------------------+-------------+-------------------------------------------------------------------------------------------------------------
|
||||
1 | ARGENTINA | 1 | al foxes promise slyly according to the regular accounts. bold requests alon
|
||||
5 | ETHIOPIA | 0 | ven packages wake quickly. regu
|
||||
0 | ALGERIA | 0 | haggle. carefully final deposits detect slyly agai
|
||||
3 | CANADA | 1 | eas hang ironic, silent packages. slyly regular packages are furiously over the tithes. fluffily bold
|
||||
4 | EGYPT | 4 | y above the carefully unusual theodolites. final dugouts are quickly across the furiously regular d
|
||||
2 | BRAZIL | 1 | y alongside of the pending deposits. carefully special packages are about the ironic forges. slyly special
|
||||
(6 rows)
|
||||
|
||||
SELECT n_comment FROM citus_mx_test_schema.nation_hash_collation_search_path ORDER BY n_comment COLLATE citus_mx_test_schema.english;
|
||||
n_comment
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
al foxes promise slyly according to the regular accounts. bold requests alon
|
||||
eas hang ironic, silent packages. slyly regular packages are furiously over the tithes. fluffily bold
|
||||
haggle. carefully final deposits detect slyly agai
|
||||
ven packages wake quickly. regu
|
||||
y above the carefully unusual theodolites. final dugouts are quickly across the furiously regular d
|
||||
y alongside of the pending deposits. carefully special packages are about the ironic forges. slyly special
|
||||
(6 rows)
|
||||
|
||||
SET search_path TO citus_mx_test_schema;
|
||||
SELECT * FROM nation_hash_collation_search_path ORDER BY 1 DESC;
|
||||
n_nationkey | n_name | n_regionkey | n_comment
|
||||
-------------+---------------------------+-------------+-------------------------------------------------------------------------------------------------------------
|
||||
5 | ETHIOPIA | 0 | ven packages wake quickly. regu
|
||||
4 | EGYPT | 4 | y above the carefully unusual theodolites. final dugouts are quickly across the furiously regular d
|
||||
3 | CANADA | 1 | eas hang ironic, silent packages. slyly regular packages are furiously over the tithes. fluffily bold
|
||||
2 | BRAZIL | 1 | y alongside of the pending deposits. carefully special packages are about the ironic forges. slyly special
|
||||
1 | ARGENTINA | 1 | al foxes promise slyly according to the regular accounts. bold requests alon
|
||||
0 | ALGERIA | 0 | haggle. carefully final deposits detect slyly agai
|
||||
(6 rows)
|
||||
|
||||
SELECT n_comment FROM nation_hash_collation_search_path ORDER BY n_comment COLLATE english;
|
||||
n_comment
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
al foxes promise slyly according to the regular accounts. bold requests alon
|
||||
eas hang ironic, silent packages. slyly regular packages are furiously over the tithes. fluffily bold
|
||||
haggle. carefully final deposits detect slyly agai
|
||||
ven packages wake quickly. regu
|
||||
y above the carefully unusual theodolites. final dugouts are quickly across the furiously regular d
|
||||
y alongside of the pending deposits. carefully special packages are about the ironic forges. slyly special
|
||||
(6 rows)
|
||||
|
||||
SELECT * FROM citus_mx_test_schema.nation_hash_composite_types WHERE test_col = '(a,a)'::citus_mx_test_schema.new_composite_type ORDER BY 1::int DESC;
|
||||
n_nationkey | n_name | n_regionkey | n_comment | test_col
|
||||
-------------+---------------------------+-------------+----------------------------------------------------+----------
|
||||
0 | ALGERIA | 0 | haggle. carefully final deposits detect slyly agai | (a,a)
|
||||
(1 row)
|
||||
|
||||
--test with search_path is set
|
||||
SET search_path TO citus_mx_test_schema;
|
||||
SELECT * FROM nation_hash_composite_types WHERE test_col = '(a,a)'::new_composite_type ORDER BY 1::int DESC;
|
||||
n_nationkey | n_name | n_regionkey | n_comment | test_col
|
||||
-------------+---------------------------+-------------+----------------------------------------------------+----------
|
||||
0 | ALGERIA | 0 | haggle. carefully final deposits detect slyly agai | (a,a)
|
||||
(1 row)
|
||||
|
||||
-- check when search_path is public,
|
||||
-- join of two tables which are in different schemas,
|
||||
-- join on partition column
|
||||
SET search_path TO public;
|
||||
SELECT
|
||||
count (*)
|
||||
FROM
|
||||
citus_mx_test_schema_join_1.nation_hash n1, citus_mx_test_schema_join_2.nation_hash n2
|
||||
WHERE
|
||||
n1.n_nationkey = n2.n_nationkey;
|
||||
count
|
||||
-------
|
||||
25
|
||||
(1 row)
|
||||
|
||||
-- check when search_path is different than public,
|
||||
-- join of two tables which are in different schemas,
|
||||
-- join on partition column
|
||||
SET search_path TO citus_mx_test_schema_join_1;
|
||||
SELECT
|
||||
count (*)
|
||||
FROM
|
||||
nation_hash n1, citus_mx_test_schema_join_2.nation_hash n2
|
||||
WHERE
|
||||
n1.n_nationkey = n2.n_nationkey;
|
||||
count
|
||||
-------
|
||||
25
|
||||
(1 row)
|
||||
|
||||
-- check when search_path is public,
|
||||
-- join of two tables which are in same schemas,
|
||||
-- join on partition column
|
||||
SET search_path TO public;
|
||||
SELECT
|
||||
count (*)
|
||||
FROM
|
||||
citus_mx_test_schema_join_1.nation_hash n1, citus_mx_test_schema_join_1.nation_hash_2 n2
|
||||
WHERE
|
||||
n1.n_nationkey = n2.n_nationkey;
|
||||
count
|
||||
-------
|
||||
25
|
||||
(1 row)
|
||||
|
||||
-- check when search_path is different than public,
|
||||
-- join of two tables which are in same schemas,
|
||||
-- join on partition column
|
||||
SET search_path TO citus_mx_test_schema_join_1;
|
||||
SELECT
|
||||
count (*)
|
||||
FROM
|
||||
nation_hash n1, nation_hash_2 n2
|
||||
WHERE
|
||||
n1.n_nationkey = n2.n_nationkey;
|
||||
count
|
||||
-------
|
||||
25
|
||||
(1 row)
|
||||
|
||||
-- single repartition joins
|
||||
SET citus.task_executor_type TO "task-tracker";
|
||||
-- check when search_path is public,
|
||||
-- join of two tables which are in different schemas,
|
||||
-- join on partition column and non-partition column
|
||||
--SET search_path TO public;
|
||||
SELECT
|
||||
count (*)
|
||||
FROM
|
||||
citus_mx_test_schema_join_1.nation_hash n1, citus_mx_test_schema_join_2.nation_hash n2
|
||||
WHERE
|
||||
n1.n_nationkey = n2.n_regionkey;
|
||||
count
|
||||
-------
|
||||
25
|
||||
(1 row)
|
||||
|
||||
-- check when search_path is different than public,
|
||||
-- join of two tables which are in different schemas,
|
||||
-- join on partition column and non-partition column
|
||||
SET search_path TO citus_mx_test_schema_join_1;
|
||||
SELECT
|
||||
count (*)
|
||||
FROM
|
||||
nation_hash n1, citus_mx_test_schema_join_2.nation_hash n2
|
||||
WHERE
|
||||
n1.n_nationkey = n2.n_regionkey;
|
||||
count
|
||||
-------
|
||||
25
|
||||
(1 row)
|
||||
|
||||
-- check when search_path is different than public,
|
||||
-- join of two tables which are in same schemas,
|
||||
-- join on partition column and non-partition column
|
||||
SET search_path TO citus_mx_test_schema_join_1;
|
||||
SELECT
|
||||
count (*)
|
||||
FROM
|
||||
nation_hash n1, nation_hash_2 n2
|
||||
WHERE
|
||||
n1.n_nationkey = n2.n_regionkey;
|
||||
count
|
||||
-------
|
||||
25
|
||||
(1 row)
|
||||
|
||||
-- hash repartition joins
|
||||
-- check when search_path is public,
|
||||
-- join of two tables which are in different schemas,
|
||||
-- join on non-partition column
|
||||
SET search_path TO public;
|
||||
SELECT
|
||||
count (*)
|
||||
FROM
|
||||
citus_mx_test_schema_join_1.nation_hash n1, citus_mx_test_schema_join_2.nation_hash n2
|
||||
WHERE
|
||||
n1.n_regionkey = n2.n_regionkey;
|
||||
count
|
||||
-------
|
||||
125
|
||||
(1 row)
|
||||
|
||||
-- check when search_path is different than public,
|
||||
-- join of two tables which are in different schemas,
|
||||
-- join on non-partition column
|
||||
SET search_path TO citus_mx_test_schema_join_1;
|
||||
SELECT
|
||||
count (*)
|
||||
FROM
|
||||
nation_hash n1, citus_mx_test_schema_join_2.nation_hash n2
|
||||
WHERE
|
||||
n1.n_regionkey = n2.n_regionkey;
|
||||
count
|
||||
-------
|
||||
125
|
||||
(1 row)
|
||||
|
||||
-- check when search_path is different than public,
|
||||
-- join of two tables which are in same schemas,
|
||||
-- join on non-partition column
|
||||
SET search_path TO citus_mx_test_schema_join_1;
|
||||
SELECT
|
||||
count (*)
|
||||
FROM
|
||||
nation_hash n1, nation_hash_2 n2
|
||||
WHERE
|
||||
n1.n_regionkey = n2.n_regionkey;
|
||||
count
|
||||
-------
|
||||
125
|
||||
(1 row)
|
||||
|
||||
-- set task_executor back to real-time
|
||||
SET citus.task_executor_type TO "real-time";
|
|
@ -0,0 +1,111 @@
|
|||
--
|
||||
-- MULTI_MX_TPCH_QUERY1
|
||||
--
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1310000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1310000;
|
||||
-- connect to the schema node
|
||||
\c - - - :master_port
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
-- Query #1 from the TPC-H decision support benchmark
|
||||
SELECT
|
||||
l_returnflag,
|
||||
l_linestatus,
|
||||
sum(l_quantity) as sum_qty,
|
||||
sum(l_extendedprice) as sum_base_price,
|
||||
sum(l_extendedprice * (1 - l_discount)) as sum_disc_price,
|
||||
sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge,
|
||||
avg(l_quantity) as avg_qty,
|
||||
avg(l_extendedprice) as avg_price,
|
||||
avg(l_discount) as avg_disc,
|
||||
count(*) as count_order
|
||||
FROM
|
||||
lineitem_mx
|
||||
WHERE
|
||||
l_shipdate <= date '1998-12-01' - interval '90 days'
|
||||
GROUP BY
|
||||
l_returnflag,
|
||||
l_linestatus
|
||||
ORDER BY
|
||||
l_returnflag,
|
||||
l_linestatus;
|
||||
l_returnflag | l_linestatus | sum_qty | sum_base_price | sum_disc_price | sum_charge | avg_qty | avg_price | avg_disc | count_order
|
||||
--------------+--------------+-----------+----------------+----------------+------------------+---------------------+--------------------+------------------------+-------------
|
||||
A | F | 75465.00 | 113619873.63 | 107841287.0728 | 112171153.245923 | 25.6334918478260870 | 38593.707075407609 | 0.05055027173913043478 | 2944
|
||||
N | F | 2022.00 | 3102551.45 | 2952540.7118 | 3072642.770652 | 26.6052631578947368 | 40823.045394736842 | 0.05263157894736842105 | 76
|
||||
N | O | 149778.00 | 224706948.16 | 213634857.6854 | 222134071.929801 | 25.4594594594594595 | 38195.979629440762 | 0.04939486656467788543 | 5883
|
||||
R | F | 73156.00 | 108937979.73 | 103516623.6698 | 107743533.784328 | 25.2175112030334367 | 37551.871675284385 | 0.04983798690106859704 | 2901
|
||||
(4 rows)
|
||||
|
||||
-- connect one of the workers
|
||||
\c - - - :worker_1_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1310000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1310000;
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
-- Query #1 from the TPC-H decision support benchmark
|
||||
SELECT
|
||||
l_returnflag,
|
||||
l_linestatus,
|
||||
sum(l_quantity) as sum_qty,
|
||||
sum(l_extendedprice) as sum_base_price,
|
||||
sum(l_extendedprice * (1 - l_discount)) as sum_disc_price,
|
||||
sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge,
|
||||
avg(l_quantity) as avg_qty,
|
||||
avg(l_extendedprice) as avg_price,
|
||||
avg(l_discount) as avg_disc,
|
||||
count(*) as count_order
|
||||
FROM
|
||||
lineitem_mx
|
||||
WHERE
|
||||
l_shipdate <= date '1998-12-01' - interval '90 days'
|
||||
GROUP BY
|
||||
l_returnflag,
|
||||
l_linestatus
|
||||
ORDER BY
|
||||
l_returnflag,
|
||||
l_linestatus;
|
||||
l_returnflag | l_linestatus | sum_qty | sum_base_price | sum_disc_price | sum_charge | avg_qty | avg_price | avg_disc | count_order
|
||||
--------------+--------------+-----------+----------------+----------------+------------------+---------------------+--------------------+------------------------+-------------
|
||||
A | F | 75465.00 | 113619873.63 | 107841287.0728 | 112171153.245923 | 25.6334918478260870 | 38593.707075407609 | 0.05055027173913043478 | 2944
|
||||
N | F | 2022.00 | 3102551.45 | 2952540.7118 | 3072642.770652 | 26.6052631578947368 | 40823.045394736842 | 0.05263157894736842105 | 76
|
||||
N | O | 149778.00 | 224706948.16 | 213634857.6854 | 222134071.929801 | 25.4594594594594595 | 38195.979629440762 | 0.04939486656467788543 | 5883
|
||||
R | F | 73156.00 | 108937979.73 | 103516623.6698 | 107743533.784328 | 25.2175112030334367 | 37551.871675284385 | 0.04983798690106859704 | 2901
|
||||
(4 rows)
|
||||
|
||||
-- connect to the other node
|
||||
\c - - - :worker_2_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1310000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1310000;
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
-- Query #1 from the TPC-H decision support benchmark
|
||||
SELECT
|
||||
l_returnflag,
|
||||
l_linestatus,
|
||||
sum(l_quantity) as sum_qty,
|
||||
sum(l_extendedprice) as sum_base_price,
|
||||
sum(l_extendedprice * (1 - l_discount)) as sum_disc_price,
|
||||
sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge,
|
||||
avg(l_quantity) as avg_qty,
|
||||
avg(l_extendedprice) as avg_price,
|
||||
avg(l_discount) as avg_disc,
|
||||
count(*) as count_order
|
||||
FROM
|
||||
lineitem_mx
|
||||
WHERE
|
||||
l_shipdate <= date '1998-12-01' - interval '90 days'
|
||||
GROUP BY
|
||||
l_returnflag,
|
||||
l_linestatus
|
||||
ORDER BY
|
||||
l_returnflag,
|
||||
l_linestatus;
|
||||
l_returnflag | l_linestatus | sum_qty | sum_base_price | sum_disc_price | sum_charge | avg_qty | avg_price | avg_disc | count_order
|
||||
--------------+--------------+-----------+----------------+----------------+------------------+---------------------+--------------------+------------------------+-------------
|
||||
A | F | 75465.00 | 113619873.63 | 107841287.0728 | 112171153.245923 | 25.6334918478260870 | 38593.707075407609 | 0.05055027173913043478 | 2944
|
||||
N | F | 2022.00 | 3102551.45 | 2952540.7118 | 3072642.770652 | 26.6052631578947368 | 40823.045394736842 | 0.05263157894736842105 | 76
|
||||
N | O | 149778.00 | 224706948.16 | 213634857.6854 | 222134071.929801 | 25.4594594594594595 | 38195.979629440762 | 0.04939486656467788543 | 5883
|
||||
R | F | 73156.00 | 108937979.73 | 103516623.6698 | 107743533.784328 | 25.2175112030334367 | 37551.871675284385 | 0.04983798690106859704 | 2901
|
||||
(4 rows)
|
||||
|
|
@ -0,0 +1,186 @@
|
|||
--
|
||||
-- MULTI_MX_TPCH_QUERY10
|
||||
--
|
||||
-- Query #10 from the TPC-H decision support benchmark. Unlike other TPC-H tests,
|
||||
-- we don't set citus.large_table_shard_count here, and instead use the default value
|
||||
-- coming from postgresql.conf or multi_task_tracker_executor.conf.
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1300000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1300000;
|
||||
-- connect to master
|
||||
\c - - - :master_port
|
||||
SELECT
|
||||
c_custkey,
|
||||
c_name,
|
||||
sum(l_extendedprice * (1 - l_discount)) as revenue,
|
||||
c_acctbal,
|
||||
n_name,
|
||||
c_address,
|
||||
c_phone,
|
||||
c_comment
|
||||
FROM
|
||||
customer_mx,
|
||||
orders_mx,
|
||||
lineitem_mx,
|
||||
nation_mx
|
||||
WHERE
|
||||
c_custkey = o_custkey
|
||||
AND l_orderkey = o_orderkey
|
||||
AND o_orderdate >= date '1993-10-01'
|
||||
AND o_orderdate < date '1993-10-01' + interval '3' month
|
||||
AND l_returnflag = 'R'
|
||||
AND c_nationkey = n_nationkey
|
||||
GROUP BY
|
||||
c_custkey,
|
||||
c_name,
|
||||
c_acctbal,
|
||||
c_phone,
|
||||
n_name,
|
||||
c_address,
|
||||
c_comment
|
||||
ORDER BY
|
||||
revenue DESC
|
||||
LIMIT 20;
|
||||
c_custkey | c_name | revenue | c_acctbal | n_name | c_address | c_phone | c_comment
|
||||
-----------+--------------------+-------------+-----------+---------------------------+---------------------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------
|
||||
436 | Customer#000000436 | 255187.7382 | 5896.87 | ROMANIA | 4DCNzAT842cVYTcaUS94kR0QXHSRM5oco0D6Z | 29-927-687-6390 | olites engage carefully. slyly ironic asymptotes about the ironi
|
||||
640 | Customer#000000640 | 251941.1430 | 3025.84 | BRAZIL | j3vjr0 n,pJFG4gIOtC | 12-702-315-6637 | lly. furiously quick deposits haggle quickly regular packages. pinto
|
||||
361 | Customer#000000361 | 239204.0858 | 7451.84 | SAUDI ARABIA | l0F8jMJVe63cb | 30-164-267-4590 | fully busy ideas. regular foxes cajole
|
||||
223 | Customer#000000223 | 218652.8040 | 7476.20 | SAUDI ARABIA | ftau6Pk,brboMyEl,,kFm | 30-193-643-1517 | al, regular requests run furiously blithely silent packages. blithely ironic accounts across the furious
|
||||
613 | Customer#000000613 | 186092.2017 | 6679.75 | EGYPT | AJT,26RbanTdEHOBgTWg | 14-275-416-1669 | ironic, pending deposits: quickl
|
||||
355 | Customer#000000355 | 168184.4825 | 8727.90 | KENYA | 205r3Xg9ZWjPZNX1z | 24-656-787-6091 | ly bold requests detect furiously. unusual instructions sleep aft
|
||||
872 | Customer#000000872 | 166831.7294 | -858.61 | PERU | vLP7iNZBK4B,HANFTKabVI3AO Y9O8H | 27-357-139-7164 | detect. packages wake slyly express foxes. even deposits ru
|
||||
805 | Customer#000000805 | 165239.8440 | 511.69 | IRAN | wCKx5zcHvwpSffyc9qfi9dvqcm9LT,cLAG | 20-732-989-5653 | busy sentiments. pending packages haggle among the express requests-- slyly regular excuses above the slyl
|
||||
427 | Customer#000000427 | 148033.5226 | 4376.80 | BRAZIL | LHzXa71U2AGqfbqj1yYYqw2MEXq99dWmY | 12-124-309-3821 | y even multipliers according to the regu
|
||||
581 | Customer#000000581 | 146369.1712 | 3242.10 | UNITED STATES | s9SoN9XeVuCri | 34-415-978-2518 | ns. quickly regular pinto beans must sleep fluffily
|
||||
679 | Customer#000000679 | 145188.0664 | 1394.44 | IRAN | IJf1FlZL9I9m,rvofcoKy5pRUOjUQV | 20-146-696-9508 | ely pending frays boost carefully
|
||||
160 | Customer#000000160 | 138511.7370 | 4363.17 | JORDAN | 5soVQ3dOCRBWBS | 23-428-666-4806 | olites. silently ironic accounts cajole furious
|
||||
883 | Customer#000000883 | 128224.1349 | 479.96 | CANADA | qVQ8rWNU5KZYDcS | 13-526-239-6950 | uctions are carefully across the regular, regular asymptote
|
||||
101 | Customer#000000101 | 124996.0120 | 7470.96 | BRAZIL | sMmL2rNeHDltovSm Y | 12-514-298-3699 | sleep. pending packages detect slyly ironic pack
|
||||
671 | Customer#000000671 | 124125.2191 | 3227.87 | VIETNAM | ic6qGrt0giB,HDEiBK,,FYGHXQpc | 31-593-213-9388 | bold ideas above the ironic packages affix blithely about the furiou
|
||||
526 | Customer#000000526 | 120324.0048 | 705.93 | ARGENTINA | 0oAVPhh1I4JdrDafVG2Z8 | 11-170-679-3115 | ctions cajole after the furiously unusual ideas. ironic packages among the instructions are carefully carefully iro
|
||||
367 | Customer#000000367 | 118572.6180 | 9108.65 | JORDAN | yZaDoEZCqt2VMTVKoZUkf6gJ4yj | 23-939-319-4691 | eodolites under the ironic, stealthy requests affix furiously among the unusual tit
|
||||
745 | Customer#000000745 | 113738.6908 | 7115.14 | CHINA | vjuHvDKdaomsivy l | 28-913-438-9403 | o beans. bold, regular theodolites haggle carefully about the quickl
|
||||
118 | Customer#000000118 | 113149.7832 | 3582.37 | CHINA | OVnFuHygK9wx3xpg8 | 28-639-943-7051 | uick packages alongside of the furiously final deposits haggle above the fluffily even foxes. blithely dogged dep
|
||||
50 | Customer#000000050 | 111600.5870 | 4266.13 | FRANCE | 9SzDYlkzxByyJ1QeTI o | 16-658-112-3221 | ts. furiously ironic accounts cajole furiously slyly ironic dinos.
|
||||
(20 rows)
|
||||
|
||||
-- connect one of the workers
|
||||
\c - - - :worker_1_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1300000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1300000;
|
||||
SELECT
|
||||
c_custkey,
|
||||
c_name,
|
||||
sum(l_extendedprice * (1 - l_discount)) as revenue,
|
||||
c_acctbal,
|
||||
n_name,
|
||||
c_address,
|
||||
c_phone,
|
||||
c_comment
|
||||
FROM
|
||||
customer_mx,
|
||||
orders_mx,
|
||||
lineitem_mx,
|
||||
nation_mx
|
||||
WHERE
|
||||
c_custkey = o_custkey
|
||||
AND l_orderkey = o_orderkey
|
||||
AND o_orderdate >= date '1993-10-01'
|
||||
AND o_orderdate < date '1993-10-01' + interval '3' month
|
||||
AND l_returnflag = 'R'
|
||||
AND c_nationkey = n_nationkey
|
||||
GROUP BY
|
||||
c_custkey,
|
||||
c_name,
|
||||
c_acctbal,
|
||||
c_phone,
|
||||
n_name,
|
||||
c_address,
|
||||
c_comment
|
||||
ORDER BY
|
||||
revenue DESC
|
||||
LIMIT 20;
|
||||
c_custkey | c_name | revenue | c_acctbal | n_name | c_address | c_phone | c_comment
|
||||
-----------+--------------------+-------------+-----------+---------------------------+---------------------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------
|
||||
436 | Customer#000000436 | 255187.7382 | 5896.87 | ROMANIA | 4DCNzAT842cVYTcaUS94kR0QXHSRM5oco0D6Z | 29-927-687-6390 | olites engage carefully. slyly ironic asymptotes about the ironi
|
||||
640 | Customer#000000640 | 251941.1430 | 3025.84 | BRAZIL | j3vjr0 n,pJFG4gIOtC | 12-702-315-6637 | lly. furiously quick deposits haggle quickly regular packages. pinto
|
||||
361 | Customer#000000361 | 239204.0858 | 7451.84 | SAUDI ARABIA | l0F8jMJVe63cb | 30-164-267-4590 | fully busy ideas. regular foxes cajole
|
||||
223 | Customer#000000223 | 218652.8040 | 7476.20 | SAUDI ARABIA | ftau6Pk,brboMyEl,,kFm | 30-193-643-1517 | al, regular requests run furiously blithely silent packages. blithely ironic accounts across the furious
|
||||
613 | Customer#000000613 | 186092.2017 | 6679.75 | EGYPT | AJT,26RbanTdEHOBgTWg | 14-275-416-1669 | ironic, pending deposits: quickl
|
||||
355 | Customer#000000355 | 168184.4825 | 8727.90 | KENYA | 205r3Xg9ZWjPZNX1z | 24-656-787-6091 | ly bold requests detect furiously. unusual instructions sleep aft
|
||||
872 | Customer#000000872 | 166831.7294 | -858.61 | PERU | vLP7iNZBK4B,HANFTKabVI3AO Y9O8H | 27-357-139-7164 | detect. packages wake slyly express foxes. even deposits ru
|
||||
805 | Customer#000000805 | 165239.8440 | 511.69 | IRAN | wCKx5zcHvwpSffyc9qfi9dvqcm9LT,cLAG | 20-732-989-5653 | busy sentiments. pending packages haggle among the express requests-- slyly regular excuses above the slyl
|
||||
427 | Customer#000000427 | 148033.5226 | 4376.80 | BRAZIL | LHzXa71U2AGqfbqj1yYYqw2MEXq99dWmY | 12-124-309-3821 | y even multipliers according to the regu
|
||||
581 | Customer#000000581 | 146369.1712 | 3242.10 | UNITED STATES | s9SoN9XeVuCri | 34-415-978-2518 | ns. quickly regular pinto beans must sleep fluffily
|
||||
679 | Customer#000000679 | 145188.0664 | 1394.44 | IRAN | IJf1FlZL9I9m,rvofcoKy5pRUOjUQV | 20-146-696-9508 | ely pending frays boost carefully
|
||||
160 | Customer#000000160 | 138511.7370 | 4363.17 | JORDAN | 5soVQ3dOCRBWBS | 23-428-666-4806 | olites. silently ironic accounts cajole furious
|
||||
883 | Customer#000000883 | 128224.1349 | 479.96 | CANADA | qVQ8rWNU5KZYDcS | 13-526-239-6950 | uctions are carefully across the regular, regular asymptote
|
||||
101 | Customer#000000101 | 124996.0120 | 7470.96 | BRAZIL | sMmL2rNeHDltovSm Y | 12-514-298-3699 | sleep. pending packages detect slyly ironic pack
|
||||
671 | Customer#000000671 | 124125.2191 | 3227.87 | VIETNAM | ic6qGrt0giB,HDEiBK,,FYGHXQpc | 31-593-213-9388 | bold ideas above the ironic packages affix blithely about the furiou
|
||||
526 | Customer#000000526 | 120324.0048 | 705.93 | ARGENTINA | 0oAVPhh1I4JdrDafVG2Z8 | 11-170-679-3115 | ctions cajole after the furiously unusual ideas. ironic packages among the instructions are carefully carefully iro
|
||||
367 | Customer#000000367 | 118572.6180 | 9108.65 | JORDAN | yZaDoEZCqt2VMTVKoZUkf6gJ4yj | 23-939-319-4691 | eodolites under the ironic, stealthy requests affix furiously among the unusual tit
|
||||
745 | Customer#000000745 | 113738.6908 | 7115.14 | CHINA | vjuHvDKdaomsivy l | 28-913-438-9403 | o beans. bold, regular theodolites haggle carefully about the quickl
|
||||
118 | Customer#000000118 | 113149.7832 | 3582.37 | CHINA | OVnFuHygK9wx3xpg8 | 28-639-943-7051 | uick packages alongside of the furiously final deposits haggle above the fluffily even foxes. blithely dogged dep
|
||||
50 | Customer#000000050 | 111600.5870 | 4266.13 | FRANCE | 9SzDYlkzxByyJ1QeTI o | 16-658-112-3221 | ts. furiously ironic accounts cajole furiously slyly ironic dinos.
|
||||
(20 rows)
|
||||
|
||||
-- connect to the other worker
|
||||
\c - - - :worker_2_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1300000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1300000;
|
||||
SELECT
|
||||
c_custkey,
|
||||
c_name,
|
||||
sum(l_extendedprice * (1 - l_discount)) as revenue,
|
||||
c_acctbal,
|
||||
n_name,
|
||||
c_address,
|
||||
c_phone,
|
||||
c_comment
|
||||
FROM
|
||||
customer_mx,
|
||||
orders_mx,
|
||||
lineitem_mx,
|
||||
nation_mx
|
||||
WHERE
|
||||
c_custkey = o_custkey
|
||||
AND l_orderkey = o_orderkey
|
||||
AND o_orderdate >= date '1993-10-01'
|
||||
AND o_orderdate < date '1993-10-01' + interval '3' month
|
||||
AND l_returnflag = 'R'
|
||||
AND c_nationkey = n_nationkey
|
||||
GROUP BY
|
||||
c_custkey,
|
||||
c_name,
|
||||
c_acctbal,
|
||||
c_phone,
|
||||
n_name,
|
||||
c_address,
|
||||
c_comment
|
||||
ORDER BY
|
||||
revenue DESC
|
||||
LIMIT 20;
|
||||
c_custkey | c_name | revenue | c_acctbal | n_name | c_address | c_phone | c_comment
|
||||
-----------+--------------------+-------------+-----------+---------------------------+---------------------------------------+-----------------+---------------------------------------------------------------------------------------------------------------------
|
||||
436 | Customer#000000436 | 255187.7382 | 5896.87 | ROMANIA | 4DCNzAT842cVYTcaUS94kR0QXHSRM5oco0D6Z | 29-927-687-6390 | olites engage carefully. slyly ironic asymptotes about the ironi
|
||||
640 | Customer#000000640 | 251941.1430 | 3025.84 | BRAZIL | j3vjr0 n,pJFG4gIOtC | 12-702-315-6637 | lly. furiously quick deposits haggle quickly regular packages. pinto
|
||||
361 | Customer#000000361 | 239204.0858 | 7451.84 | SAUDI ARABIA | l0F8jMJVe63cb | 30-164-267-4590 | fully busy ideas. regular foxes cajole
|
||||
223 | Customer#000000223 | 218652.8040 | 7476.20 | SAUDI ARABIA | ftau6Pk,brboMyEl,,kFm | 30-193-643-1517 | al, regular requests run furiously blithely silent packages. blithely ironic accounts across the furious
|
||||
613 | Customer#000000613 | 186092.2017 | 6679.75 | EGYPT | AJT,26RbanTdEHOBgTWg | 14-275-416-1669 | ironic, pending deposits: quickl
|
||||
355 | Customer#000000355 | 168184.4825 | 8727.90 | KENYA | 205r3Xg9ZWjPZNX1z | 24-656-787-6091 | ly bold requests detect furiously. unusual instructions sleep aft
|
||||
872 | Customer#000000872 | 166831.7294 | -858.61 | PERU | vLP7iNZBK4B,HANFTKabVI3AO Y9O8H | 27-357-139-7164 | detect. packages wake slyly express foxes. even deposits ru
|
||||
805 | Customer#000000805 | 165239.8440 | 511.69 | IRAN | wCKx5zcHvwpSffyc9qfi9dvqcm9LT,cLAG | 20-732-989-5653 | busy sentiments. pending packages haggle among the express requests-- slyly regular excuses above the slyl
|
||||
427 | Customer#000000427 | 148033.5226 | 4376.80 | BRAZIL | LHzXa71U2AGqfbqj1yYYqw2MEXq99dWmY | 12-124-309-3821 | y even multipliers according to the regu
|
||||
581 | Customer#000000581 | 146369.1712 | 3242.10 | UNITED STATES | s9SoN9XeVuCri | 34-415-978-2518 | ns. quickly regular pinto beans must sleep fluffily
|
||||
679 | Customer#000000679 | 145188.0664 | 1394.44 | IRAN | IJf1FlZL9I9m,rvofcoKy5pRUOjUQV | 20-146-696-9508 | ely pending frays boost carefully
|
||||
160 | Customer#000000160 | 138511.7370 | 4363.17 | JORDAN | 5soVQ3dOCRBWBS | 23-428-666-4806 | olites. silently ironic accounts cajole furious
|
||||
883 | Customer#000000883 | 128224.1349 | 479.96 | CANADA | qVQ8rWNU5KZYDcS | 13-526-239-6950 | uctions are carefully across the regular, regular asymptote
|
||||
101 | Customer#000000101 | 124996.0120 | 7470.96 | BRAZIL | sMmL2rNeHDltovSm Y | 12-514-298-3699 | sleep. pending packages detect slyly ironic pack
|
||||
671 | Customer#000000671 | 124125.2191 | 3227.87 | VIETNAM | ic6qGrt0giB,HDEiBK,,FYGHXQpc | 31-593-213-9388 | bold ideas above the ironic packages affix blithely about the furiou
|
||||
526 | Customer#000000526 | 120324.0048 | 705.93 | ARGENTINA | 0oAVPhh1I4JdrDafVG2Z8 | 11-170-679-3115 | ctions cajole after the furiously unusual ideas. ironic packages among the instructions are carefully carefully iro
|
||||
367 | Customer#000000367 | 118572.6180 | 9108.65 | JORDAN | yZaDoEZCqt2VMTVKoZUkf6gJ4yj | 23-939-319-4691 | eodolites under the ironic, stealthy requests affix furiously among the unusual tit
|
||||
745 | Customer#000000745 | 113738.6908 | 7115.14 | CHINA | vjuHvDKdaomsivy l | 28-913-438-9403 | o beans. bold, regular theodolites haggle carefully about the quickl
|
||||
118 | Customer#000000118 | 113149.7832 | 3582.37 | CHINA | OVnFuHygK9wx3xpg8 | 28-639-943-7051 | uick packages alongside of the furiously final deposits haggle above the fluffily even foxes. blithely dogged dep
|
||||
50 | Customer#000000050 | 111600.5870 | 4266.13 | FRANCE | 9SzDYlkzxByyJ1QeTI o | 16-658-112-3221 | ts. furiously ironic accounts cajole furiously slyly ironic dinos.
|
||||
(20 rows)
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
--
|
||||
-- MULTI_MX_TPCH_QUERY12
|
||||
--
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1290000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1290000;
|
||||
-- connect to the schema node
|
||||
\c - - - :master_port
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
-- Query #12 from the TPC-H decision support benchmark
|
||||
SELECT
|
||||
l_shipmode,
|
||||
sum(case
|
||||
when o_orderpriority = '1-URGENT'
|
||||
OR o_orderpriority = '2-HIGH'
|
||||
then 1
|
||||
else 0
|
||||
end) as high_line_count,
|
||||
sum(case
|
||||
when o_orderpriority <> '1-URGENT'
|
||||
AND o_orderpriority <> '2-HIGH'
|
||||
then 1
|
||||
else 0
|
||||
end) AS low_line_count
|
||||
FROM
|
||||
orders_mx,
|
||||
lineitem_mx
|
||||
WHERE
|
||||
o_orderkey = l_orderkey
|
||||
AND l_shipmode in ('MAIL', 'SHIP')
|
||||
AND l_commitdate < l_receiptdate
|
||||
AND l_shipdate < l_commitdate
|
||||
AND l_receiptdate >= date '1994-01-01'
|
||||
AND l_receiptdate < date '1994-01-01' + interval '1' year
|
||||
GROUP BY
|
||||
l_shipmode
|
||||
ORDER BY
|
||||
l_shipmode;
|
||||
l_shipmode | high_line_count | low_line_count
|
||||
------------+-----------------+----------------
|
||||
MAIL | 11 | 15
|
||||
SHIP | 11 | 19
|
||||
(2 rows)
|
||||
|
||||
-- connect one of the workers
|
||||
\c - - - :worker_1_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1290000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1290000;
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
-- Query #12 from the TPC-H decision support benchmark
|
||||
SELECT
|
||||
l_shipmode,
|
||||
sum(case
|
||||
when o_orderpriority = '1-URGENT'
|
||||
OR o_orderpriority = '2-HIGH'
|
||||
then 1
|
||||
else 0
|
||||
end) as high_line_count,
|
||||
sum(case
|
||||
when o_orderpriority <> '1-URGENT'
|
||||
AND o_orderpriority <> '2-HIGH'
|
||||
then 1
|
||||
else 0
|
||||
end) AS low_line_count
|
||||
FROM
|
||||
orders_mx,
|
||||
lineitem_mx
|
||||
WHERE
|
||||
o_orderkey = l_orderkey
|
||||
AND l_shipmode in ('MAIL', 'SHIP')
|
||||
AND l_commitdate < l_receiptdate
|
||||
AND l_shipdate < l_commitdate
|
||||
AND l_receiptdate >= date '1994-01-01'
|
||||
AND l_receiptdate < date '1994-01-01' + interval '1' year
|
||||
GROUP BY
|
||||
l_shipmode
|
||||
ORDER BY
|
||||
l_shipmode;
|
||||
l_shipmode | high_line_count | low_line_count
|
||||
------------+-----------------+----------------
|
||||
MAIL | 11 | 15
|
||||
SHIP | 11 | 19
|
||||
(2 rows)
|
||||
|
||||
-- connect to the other worker node
|
||||
\c - - - :worker_2_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1290000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1290000;
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
-- Query #12 from the TPC-H decision support benchmark
|
||||
SELECT
|
||||
l_shipmode,
|
||||
sum(case
|
||||
when o_orderpriority = '1-URGENT'
|
||||
OR o_orderpriority = '2-HIGH'
|
||||
then 1
|
||||
else 0
|
||||
end) as high_line_count,
|
||||
sum(case
|
||||
when o_orderpriority <> '1-URGENT'
|
||||
AND o_orderpriority <> '2-HIGH'
|
||||
then 1
|
||||
else 0
|
||||
end) AS low_line_count
|
||||
FROM
|
||||
orders_mx,
|
||||
lineitem_mx
|
||||
WHERE
|
||||
o_orderkey = l_orderkey
|
||||
AND l_shipmode in ('MAIL', 'SHIP')
|
||||
AND l_commitdate < l_receiptdate
|
||||
AND l_shipdate < l_commitdate
|
||||
AND l_receiptdate >= date '1994-01-01'
|
||||
AND l_receiptdate < date '1994-01-01' + interval '1' year
|
||||
GROUP BY
|
||||
l_shipmode
|
||||
ORDER BY
|
||||
l_shipmode;
|
||||
l_shipmode | high_line_count | low_line_count
|
||||
------------+-----------------+----------------
|
||||
MAIL | 11 | 15
|
||||
SHIP | 11 | 19
|
||||
(2 rows)
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
--
|
||||
-- MULTI_MX_TPCH_QUERY14
|
||||
--
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1280000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1280000;
|
||||
-- connect to the schema node
|
||||
\c - - - :master_port
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
-- Query #14 from the TPC-H decision support benchmark
|
||||
SELECT
|
||||
100.00 * sum(case
|
||||
when p_type like 'PROMO%'
|
||||
then l_extendedprice * (1 - l_discount)
|
||||
else 0
|
||||
end) / sum(l_extendedprice * (1 - l_discount)) as promo_revenue
|
||||
FROM
|
||||
lineitem_mx,
|
||||
part_mx
|
||||
WHERE
|
||||
l_partkey = p_partkey
|
||||
AND l_shipdate >= date '1995-09-01'
|
||||
AND l_shipdate < date '1995-09-01' + interval '1' year;
|
||||
promo_revenue
|
||||
---------------------
|
||||
32.1126387112005225
|
||||
(1 row)
|
||||
|
||||
-- connect one of the workers
|
||||
\c - - - :worker_1_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1280000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1280000;
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
-- Query #14 from the TPC-H decision support benchmark
|
||||
SELECT
|
||||
100.00 * sum(case
|
||||
when p_type like 'PROMO%'
|
||||
then l_extendedprice * (1 - l_discount)
|
||||
else 0
|
||||
end) / sum(l_extendedprice * (1 - l_discount)) as promo_revenue
|
||||
FROM
|
||||
lineitem_mx,
|
||||
part_mx
|
||||
WHERE
|
||||
l_partkey = p_partkey
|
||||
AND l_shipdate >= date '1995-09-01'
|
||||
AND l_shipdate < date '1995-09-01' + interval '1' year;
|
||||
promo_revenue
|
||||
---------------------
|
||||
32.1126387112005225
|
||||
(1 row)
|
||||
|
||||
-- connect to the other node
|
||||
\c - - - :worker_2_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1280000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1280000;
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
-- Query #14 from the TPC-H decision support benchmark
|
||||
SELECT
|
||||
100.00 * sum(case
|
||||
when p_type like 'PROMO%'
|
||||
then l_extendedprice * (1 - l_discount)
|
||||
else 0
|
||||
end) / sum(l_extendedprice * (1 - l_discount)) as promo_revenue
|
||||
FROM
|
||||
lineitem_mx,
|
||||
part_mx
|
||||
WHERE
|
||||
l_partkey = p_partkey
|
||||
AND l_shipdate >= date '1995-09-01'
|
||||
AND l_shipdate < date '1995-09-01' + interval '1' year;
|
||||
promo_revenue
|
||||
---------------------
|
||||
32.1126387112005225
|
||||
(1 row)
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
--
|
||||
-- MULTI_MX_TPCH_QUERY19
|
||||
--
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1270000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1270000;
|
||||
-- connect to the schema node
|
||||
\c - - - :master_port
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
-- Query #19 from the TPC-H decision support benchmark. Note that we modified
|
||||
-- the query from its original to make it work on smaller data sets.
|
||||
SELECT
|
||||
sum(l_extendedprice* (1 - l_discount)) as revenue
|
||||
FROM
|
||||
lineitem_mx,
|
||||
part_mx
|
||||
WHERE
|
||||
(
|
||||
p_partkey = l_partkey
|
||||
AND (p_brand = 'Brand#12' OR p_brand= 'Brand#14' OR p_brand='Brand#15')
|
||||
AND l_quantity >= 10
|
||||
AND l_shipmode in ('AIR', 'AIR REG', 'TRUCK')
|
||||
AND l_shipinstruct = 'DELIVER IN PERSON'
|
||||
)
|
||||
OR
|
||||
(
|
||||
p_partkey = l_partkey
|
||||
AND (p_brand = 'Brand#23' OR p_brand='Brand#24')
|
||||
AND l_quantity >= 20
|
||||
AND l_shipmode in ('AIR', 'AIR REG', 'TRUCK')
|
||||
AND l_shipinstruct = 'DELIVER IN PERSON'
|
||||
)
|
||||
OR
|
||||
(
|
||||
p_partkey = l_partkey
|
||||
AND (p_brand = 'Brand#33' OR p_brand = 'Brand#34' OR p_brand = 'Brand#35')
|
||||
AND l_quantity >= 1
|
||||
AND l_shipmode in ('AIR', 'AIR REG', 'TRUCK')
|
||||
AND l_shipinstruct = 'DELIVER IN PERSON'
|
||||
);
|
||||
revenue
|
||||
-------------
|
||||
144747.0857
|
||||
(1 row)
|
||||
|
||||
-- connect one of the workers
|
||||
\c - - - :worker_1_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1270000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1270000;
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
-- Query #19 from the TPC-H decision support benchmark. Note that we modified
|
||||
-- the query from its original to make it work on smaller data sets.
|
||||
SELECT
|
||||
sum(l_extendedprice* (1 - l_discount)) as revenue
|
||||
FROM
|
||||
lineitem_mx,
|
||||
part_mx
|
||||
WHERE
|
||||
(
|
||||
p_partkey = l_partkey
|
||||
AND (p_brand = 'Brand#12' OR p_brand= 'Brand#14' OR p_brand='Brand#15')
|
||||
AND l_quantity >= 10
|
||||
AND l_shipmode in ('AIR', 'AIR REG', 'TRUCK')
|
||||
AND l_shipinstruct = 'DELIVER IN PERSON'
|
||||
)
|
||||
OR
|
||||
(
|
||||
p_partkey = l_partkey
|
||||
AND (p_brand = 'Brand#23' OR p_brand='Brand#24')
|
||||
AND l_quantity >= 20
|
||||
AND l_shipmode in ('AIR', 'AIR REG', 'TRUCK')
|
||||
AND l_shipinstruct = 'DELIVER IN PERSON'
|
||||
)
|
||||
OR
|
||||
(
|
||||
p_partkey = l_partkey
|
||||
AND (p_brand = 'Brand#33' OR p_brand = 'Brand#34' OR p_brand = 'Brand#35')
|
||||
AND l_quantity >= 1
|
||||
AND l_shipmode in ('AIR', 'AIR REG', 'TRUCK')
|
||||
AND l_shipinstruct = 'DELIVER IN PERSON'
|
||||
);
|
||||
revenue
|
||||
-------------
|
||||
144747.0857
|
||||
(1 row)
|
||||
|
||||
-- connect to the other node
|
||||
\c - - - :worker_2_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1270000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1270000;
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
-- Query #19 from the TPC-H decision support benchmark. Note that we modified
|
||||
-- the query from its original to make it work on smaller data sets.
|
||||
SELECT
|
||||
sum(l_extendedprice* (1 - l_discount)) as revenue
|
||||
FROM
|
||||
lineitem_mx,
|
||||
part_mx
|
||||
WHERE
|
||||
(
|
||||
p_partkey = l_partkey
|
||||
AND (p_brand = 'Brand#12' OR p_brand= 'Brand#14' OR p_brand='Brand#15')
|
||||
AND l_quantity >= 10
|
||||
AND l_shipmode in ('AIR', 'AIR REG', 'TRUCK')
|
||||
AND l_shipinstruct = 'DELIVER IN PERSON'
|
||||
)
|
||||
OR
|
||||
(
|
||||
p_partkey = l_partkey
|
||||
AND (p_brand = 'Brand#23' OR p_brand='Brand#24')
|
||||
AND l_quantity >= 20
|
||||
AND l_shipmode in ('AIR', 'AIR REG', 'TRUCK')
|
||||
AND l_shipinstruct = 'DELIVER IN PERSON'
|
||||
)
|
||||
OR
|
||||
(
|
||||
p_partkey = l_partkey
|
||||
AND (p_brand = 'Brand#33' OR p_brand = 'Brand#34' OR p_brand = 'Brand#35')
|
||||
AND l_quantity >= 1
|
||||
AND l_shipmode in ('AIR', 'AIR REG', 'TRUCK')
|
||||
AND l_shipinstruct = 'DELIVER IN PERSON'
|
||||
);
|
||||
revenue
|
||||
-------------
|
||||
144747.0857
|
||||
(1 row)
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
--
|
||||
-- MULTI_MX_TPCH_QUERY3
|
||||
--
|
||||
-- Query #3 from the TPC-H decision support benchmark. Unlike other TPC-H tests,
|
||||
-- we don't set citus.large_table_shard_count here, and instead use the default value
|
||||
-- coming from postgresql.conf or multi_task_tracker_executor.conf.
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1260000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1260000;
|
||||
-- connect to the schema node
|
||||
\c - - - :master_port
|
||||
SELECT
|
||||
l_orderkey,
|
||||
sum(l_extendedprice * (1 - l_discount)) as revenue,
|
||||
o_orderdate,
|
||||
o_shippriority
|
||||
FROM
|
||||
customer_mx,
|
||||
orders_mx,
|
||||
lineitem_mx
|
||||
WHERE
|
||||
c_mktsegment = 'BUILDING'
|
||||
AND c_custkey = o_custkey
|
||||
AND l_orderkey = o_orderkey
|
||||
AND o_orderdate < date '1995-03-15'
|
||||
AND l_shipdate > date '1995-03-15'
|
||||
GROUP BY
|
||||
l_orderkey,
|
||||
o_orderdate,
|
||||
o_shippriority
|
||||
ORDER BY
|
||||
revenue DESC,
|
||||
o_orderdate;
|
||||
l_orderkey | revenue | o_orderdate | o_shippriority
|
||||
------------+-------------+-------------+----------------
|
||||
1637 | 268170.6408 | 02-08-1995 | 0
|
||||
9696 | 252014.5497 | 02-20-1995 | 0
|
||||
10916 | 242749.1996 | 03-11-1995 | 0
|
||||
450 | 221012.3165 | 03-05-1995 | 0
|
||||
5347 | 198353.7942 | 02-22-1995 | 0
|
||||
10691 | 112800.1020 | 03-14-1995 | 0
|
||||
386 | 104975.2484 | 01-25-1995 | 0
|
||||
5765 | 88222.7556 | 12-15-1994 | 0
|
||||
4707 | 88143.7774 | 02-27-1995 | 0
|
||||
5312 | 83750.7028 | 02-24-1995 | 0
|
||||
5728 | 70101.6400 | 12-11-1994 | 0
|
||||
577 | 57986.6224 | 12-19-1994 | 0
|
||||
12706 | 16636.6368 | 11-21-1994 | 0
|
||||
3844 | 8851.3200 | 12-29-1994 | 0
|
||||
11073 | 7433.6295 | 12-02-1994 | 0
|
||||
13924 | 3111.4970 | 12-20-1994 | 0
|
||||
(16 rows)
|
||||
|
||||
-- connect one of the workers
|
||||
\c - - - :worker_1_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1260000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1260000;
|
||||
SELECT
|
||||
l_orderkey,
|
||||
sum(l_extendedprice * (1 - l_discount)) as revenue,
|
||||
o_orderdate,
|
||||
o_shippriority
|
||||
FROM
|
||||
customer_mx,
|
||||
orders_mx,
|
||||
lineitem_mx
|
||||
WHERE
|
||||
c_mktsegment = 'BUILDING'
|
||||
AND c_custkey = o_custkey
|
||||
AND l_orderkey = o_orderkey
|
||||
AND o_orderdate < date '1995-03-15'
|
||||
AND l_shipdate > date '1995-03-15'
|
||||
GROUP BY
|
||||
l_orderkey,
|
||||
o_orderdate,
|
||||
o_shippriority
|
||||
ORDER BY
|
||||
revenue DESC,
|
||||
o_orderdate;
|
||||
l_orderkey | revenue | o_orderdate | o_shippriority
|
||||
------------+-------------+-------------+----------------
|
||||
1637 | 268170.6408 | 02-08-1995 | 0
|
||||
9696 | 252014.5497 | 02-20-1995 | 0
|
||||
10916 | 242749.1996 | 03-11-1995 | 0
|
||||
450 | 221012.3165 | 03-05-1995 | 0
|
||||
5347 | 198353.7942 | 02-22-1995 | 0
|
||||
10691 | 112800.1020 | 03-14-1995 | 0
|
||||
386 | 104975.2484 | 01-25-1995 | 0
|
||||
5765 | 88222.7556 | 12-15-1994 | 0
|
||||
4707 | 88143.7774 | 02-27-1995 | 0
|
||||
5312 | 83750.7028 | 02-24-1995 | 0
|
||||
5728 | 70101.6400 | 12-11-1994 | 0
|
||||
577 | 57986.6224 | 12-19-1994 | 0
|
||||
12706 | 16636.6368 | 11-21-1994 | 0
|
||||
3844 | 8851.3200 | 12-29-1994 | 0
|
||||
11073 | 7433.6295 | 12-02-1994 | 0
|
||||
13924 | 3111.4970 | 12-20-1994 | 0
|
||||
(16 rows)
|
||||
|
||||
-- connect to the other node
|
||||
\c - - - :worker_2_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1260000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1260000;
|
||||
SELECT
|
||||
l_orderkey,
|
||||
sum(l_extendedprice * (1 - l_discount)) as revenue,
|
||||
o_orderdate,
|
||||
o_shippriority
|
||||
FROM
|
||||
customer_mx,
|
||||
orders_mx,
|
||||
lineitem_mx
|
||||
WHERE
|
||||
c_mktsegment = 'BUILDING'
|
||||
AND c_custkey = o_custkey
|
||||
AND l_orderkey = o_orderkey
|
||||
AND o_orderdate < date '1995-03-15'
|
||||
AND l_shipdate > date '1995-03-15'
|
||||
GROUP BY
|
||||
l_orderkey,
|
||||
o_orderdate,
|
||||
o_shippriority
|
||||
ORDER BY
|
||||
revenue DESC,
|
||||
o_orderdate;
|
||||
l_orderkey | revenue | o_orderdate | o_shippriority
|
||||
------------+-------------+-------------+----------------
|
||||
1637 | 268170.6408 | 02-08-1995 | 0
|
||||
9696 | 252014.5497 | 02-20-1995 | 0
|
||||
10916 | 242749.1996 | 03-11-1995 | 0
|
||||
450 | 221012.3165 | 03-05-1995 | 0
|
||||
5347 | 198353.7942 | 02-22-1995 | 0
|
||||
10691 | 112800.1020 | 03-14-1995 | 0
|
||||
386 | 104975.2484 | 01-25-1995 | 0
|
||||
5765 | 88222.7556 | 12-15-1994 | 0
|
||||
4707 | 88143.7774 | 02-27-1995 | 0
|
||||
5312 | 83750.7028 | 02-24-1995 | 0
|
||||
5728 | 70101.6400 | 12-11-1994 | 0
|
||||
577 | 57986.6224 | 12-19-1994 | 0
|
||||
12706 | 16636.6368 | 11-21-1994 | 0
|
||||
3844 | 8851.3200 | 12-29-1994 | 0
|
||||
11073 | 7433.6295 | 12-02-1994 | 0
|
||||
13924 | 3111.4970 | 12-20-1994 | 0
|
||||
(16 rows)
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
--
|
||||
-- MULTI_MX_TPCH_QUERY6
|
||||
--
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1250000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1250000;
|
||||
-- connect to the schema node
|
||||
\c - - - :master_port
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
-- Query #6 from the TPC-H decision support benchmark
|
||||
SELECT
|
||||
sum(l_extendedprice * l_discount) as revenue
|
||||
FROM
|
||||
lineitem_mx
|
||||
WHERE
|
||||
l_shipdate >= date '1994-01-01'
|
||||
and l_shipdate < date '1994-01-01' + interval '1 year'
|
||||
and l_discount between 0.06 - 0.01 and 0.06 + 0.01
|
||||
and l_quantity < 24;
|
||||
revenue
|
||||
-------------
|
||||
243277.7858
|
||||
(1 row)
|
||||
|
||||
-- connect to one of the worker nodes
|
||||
\c - - - :worker_1_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1250000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1250000;
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
-- Query #6 from the TPC-H decision support benchmark
|
||||
SELECT
|
||||
sum(l_extendedprice * l_discount) as revenue
|
||||
FROM
|
||||
lineitem_mx
|
||||
WHERE
|
||||
l_shipdate >= date '1994-01-01'
|
||||
and l_shipdate < date '1994-01-01' + interval '1 year'
|
||||
and l_discount between 0.06 - 0.01 and 0.06 + 0.01
|
||||
and l_quantity < 24;
|
||||
revenue
|
||||
-------------
|
||||
243277.7858
|
||||
(1 row)
|
||||
|
||||
-- connect to the other worker node
|
||||
\c - - - :worker_2_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1250000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1250000;
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
-- Query #6 from the TPC-H decision support benchmark
|
||||
SELECT
|
||||
sum(l_extendedprice * l_discount) as revenue
|
||||
FROM
|
||||
lineitem_mx
|
||||
WHERE
|
||||
l_shipdate >= date '1994-01-01'
|
||||
and l_shipdate < date '1994-01-01' + interval '1 year'
|
||||
and l_discount between 0.06 - 0.01 and 0.06 + 0.01
|
||||
and l_quantity < 24;
|
||||
revenue
|
||||
-------------
|
||||
243277.7858
|
||||
(1 row)
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
--
|
||||
-- MULTI_MX_TPCH_QUERY7
|
||||
--
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1230000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1230000;
|
||||
-- connect to the schema node
|
||||
\c - - - :master_port
|
||||
-- Change configuration to treat lineitem AND orders tables as large
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
-- Query #7 from the TPC-H decision support benchmark
|
||||
SELECT
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year,
|
||||
sum(volume) as revenue
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
n1.n_name as supp_nation,
|
||||
n2.n_name as cust_nation,
|
||||
extract(year FROM l_shipdate) as l_year,
|
||||
l_extendedprice * (1 - l_discount) as volume
|
||||
FROM
|
||||
supplier_mx,
|
||||
lineitem_mx,
|
||||
orders_mx,
|
||||
customer_mx,
|
||||
nation_mx n1,
|
||||
nation_mx n2
|
||||
WHERE
|
||||
s_suppkey = l_suppkey
|
||||
AND o_orderkey = l_orderkey
|
||||
AND c_custkey = o_custkey
|
||||
AND s_nationkey = n1.n_nationkey
|
||||
AND c_nationkey = n2.n_nationkey
|
||||
AND (
|
||||
(n1.n_name = 'FRANCE' AND n2.n_name = 'GERMANY')
|
||||
OR (n1.n_name = 'GERMANY' AND n2.n_name = 'FRANCE')
|
||||
)
|
||||
AND l_shipdate between date '1995-01-01' AND date '1996-12-31'
|
||||
) as shipping
|
||||
GROUP BY
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year
|
||||
ORDER BY
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year;
|
||||
supp_nation | cust_nation | l_year | revenue
|
||||
---------------------------+---------------------------+--------+-----------
|
||||
GERMANY | FRANCE | 1995 | 2399.2948
|
||||
(1 row)
|
||||
|
||||
-- connect one of the workers
|
||||
\c - - - :worker_1_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1230000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1230000;
|
||||
-- Change configuration to treat lineitem AND orders tables as large
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
-- Query #7 from the TPC-H decision support benchmark
|
||||
SELECT
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year,
|
||||
sum(volume) as revenue
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
n1.n_name as supp_nation,
|
||||
n2.n_name as cust_nation,
|
||||
extract(year FROM l_shipdate) as l_year,
|
||||
l_extendedprice * (1 - l_discount) as volume
|
||||
FROM
|
||||
supplier_mx,
|
||||
lineitem_mx,
|
||||
orders_mx,
|
||||
customer_mx,
|
||||
nation_mx n1,
|
||||
nation_mx n2
|
||||
WHERE
|
||||
s_suppkey = l_suppkey
|
||||
AND o_orderkey = l_orderkey
|
||||
AND c_custkey = o_custkey
|
||||
AND s_nationkey = n1.n_nationkey
|
||||
AND c_nationkey = n2.n_nationkey
|
||||
AND (
|
||||
(n1.n_name = 'FRANCE' AND n2.n_name = 'GERMANY')
|
||||
OR (n1.n_name = 'GERMANY' AND n2.n_name = 'FRANCE')
|
||||
)
|
||||
AND l_shipdate between date '1995-01-01' AND date '1996-12-31'
|
||||
) as shipping
|
||||
GROUP BY
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year
|
||||
ORDER BY
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year;
|
||||
supp_nation | cust_nation | l_year | revenue
|
||||
---------------------------+---------------------------+--------+-----------
|
||||
GERMANY | FRANCE | 1995 | 2399.2948
|
||||
(1 row)
|
||||
|
||||
-- connect to the other worker node
|
||||
\c - - - :worker_2_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1230000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1230000;
|
||||
-- Change configuration to treat lineitem AND orders tables as large
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
-- Query #7 from the TPC-H decision support benchmark
|
||||
SELECT
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year,
|
||||
sum(volume) as revenue
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
n1.n_name as supp_nation,
|
||||
n2.n_name as cust_nation,
|
||||
extract(year FROM l_shipdate) as l_year,
|
||||
l_extendedprice * (1 - l_discount) as volume
|
||||
FROM
|
||||
supplier_mx,
|
||||
lineitem_mx,
|
||||
orders_mx,
|
||||
customer_mx,
|
||||
nation_mx n1,
|
||||
nation_mx n2
|
||||
WHERE
|
||||
s_suppkey = l_suppkey
|
||||
AND o_orderkey = l_orderkey
|
||||
AND c_custkey = o_custkey
|
||||
AND s_nationkey = n1.n_nationkey
|
||||
AND c_nationkey = n2.n_nationkey
|
||||
AND (
|
||||
(n1.n_name = 'FRANCE' AND n2.n_name = 'GERMANY')
|
||||
OR (n1.n_name = 'GERMANY' AND n2.n_name = 'FRANCE')
|
||||
)
|
||||
AND l_shipdate between date '1995-01-01' AND date '1996-12-31'
|
||||
) as shipping
|
||||
GROUP BY
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year
|
||||
ORDER BY
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year;
|
||||
supp_nation | cust_nation | l_year | revenue
|
||||
---------------------------+---------------------------+--------+-----------
|
||||
GERMANY | FRANCE | 1995 | 2399.2948
|
||||
(1 row)
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
--
|
||||
-- MULTI_MX_TPCH_QUERY7_NESTED
|
||||
--
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1240000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1240000;
|
||||
-- connect to the schema node
|
||||
\c - - - :master_port
|
||||
-- Change configuration to treat lineitem AND orders tables AS large
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
-- Query #7 from the TPC-H benchmark; modified to include sub-selects
|
||||
SELECT
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year,
|
||||
sum(volume) AS revenue
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
extract(year FROM l_shipdate) AS l_year,
|
||||
l_extendedprice * (1 - l_discount) AS volume
|
||||
FROM
|
||||
supplier_mx,
|
||||
lineitem_mx,
|
||||
orders_mx,
|
||||
customer_mx,
|
||||
(
|
||||
SELECT
|
||||
n1.n_nationkey AS supp_nation_key,
|
||||
n2.n_nationkey AS cust_nation_key,
|
||||
n1.n_name AS supp_nation,
|
||||
n2.n_name AS cust_nation
|
||||
FROM
|
||||
nation_mx n1,
|
||||
nation_mx n2
|
||||
WHERE
|
||||
(
|
||||
(n1.n_name = 'FRANCE' AND n2.n_name = 'GERMANY')
|
||||
OR (n1.n_name = 'GERMANY' AND n2.n_name = 'FRANCE')
|
||||
)
|
||||
) AS temp
|
||||
WHERE
|
||||
s_suppkey = l_suppkey
|
||||
AND o_orderkey = l_orderkey
|
||||
AND c_custkey = o_custkey
|
||||
AND s_nationkey = supp_nation_key
|
||||
AND c_nationkey = cust_nation_key
|
||||
AND l_shipdate between date '1995-01-01' AND date '1996-12-31'
|
||||
) AS shipping
|
||||
GROUP BY
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year
|
||||
ORDER BY
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year;
|
||||
supp_nation | cust_nation | l_year | revenue
|
||||
---------------------------+---------------------------+--------+-----------
|
||||
GERMANY | FRANCE | 1995 | 2399.2948
|
||||
(1 row)
|
||||
|
||||
-- connect to one of the workers
|
||||
\c - - - :worker_1_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1240000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1240000;
|
||||
-- Change configuration to treat lineitem AND orders tables AS large
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
-- Query #7 from the TPC-H benchmark; modified to include sub-selects
|
||||
SELECT
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year,
|
||||
sum(volume) AS revenue
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
extract(year FROM l_shipdate) AS l_year,
|
||||
l_extendedprice * (1 - l_discount) AS volume
|
||||
FROM
|
||||
supplier_mx,
|
||||
lineitem_mx,
|
||||
orders_mx,
|
||||
customer_mx,
|
||||
(
|
||||
SELECT
|
||||
n1.n_nationkey AS supp_nation_key,
|
||||
n2.n_nationkey AS cust_nation_key,
|
||||
n1.n_name AS supp_nation,
|
||||
n2.n_name AS cust_nation
|
||||
FROM
|
||||
nation_mx n1,
|
||||
nation_mx n2
|
||||
WHERE
|
||||
(
|
||||
(n1.n_name = 'FRANCE' AND n2.n_name = 'GERMANY')
|
||||
OR (n1.n_name = 'GERMANY' AND n2.n_name = 'FRANCE')
|
||||
)
|
||||
) AS temp
|
||||
WHERE
|
||||
s_suppkey = l_suppkey
|
||||
AND o_orderkey = l_orderkey
|
||||
AND c_custkey = o_custkey
|
||||
AND s_nationkey = supp_nation_key
|
||||
AND c_nationkey = cust_nation_key
|
||||
AND l_shipdate between date '1995-01-01' AND date '1996-12-31'
|
||||
) AS shipping
|
||||
GROUP BY
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year
|
||||
ORDER BY
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year;
|
||||
supp_nation | cust_nation | l_year | revenue
|
||||
---------------------------+---------------------------+--------+-----------
|
||||
GERMANY | FRANCE | 1995 | 2399.2948
|
||||
(1 row)
|
||||
|
||||
-- connect to the schema node
|
||||
\c - - - :worker_2_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1240000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1240000;
|
||||
-- Change configuration to treat lineitem AND orders tables AS large
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
-- Query #7 from the TPC-H benchmark; modified to include sub-selects
|
||||
SELECT
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year,
|
||||
sum(volume) AS revenue
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
extract(year FROM l_shipdate) AS l_year,
|
||||
l_extendedprice * (1 - l_discount) AS volume
|
||||
FROM
|
||||
supplier_mx,
|
||||
lineitem_mx,
|
||||
orders_mx,
|
||||
customer_mx,
|
||||
(
|
||||
SELECT
|
||||
n1.n_nationkey AS supp_nation_key,
|
||||
n2.n_nationkey AS cust_nation_key,
|
||||
n1.n_name AS supp_nation,
|
||||
n2.n_name AS cust_nation
|
||||
FROM
|
||||
nation_mx n1,
|
||||
nation_mx n2
|
||||
WHERE
|
||||
(
|
||||
(n1.n_name = 'FRANCE' AND n2.n_name = 'GERMANY')
|
||||
OR (n1.n_name = 'GERMANY' AND n2.n_name = 'FRANCE')
|
||||
)
|
||||
) AS temp
|
||||
WHERE
|
||||
s_suppkey = l_suppkey
|
||||
AND o_orderkey = l_orderkey
|
||||
AND c_custkey = o_custkey
|
||||
AND s_nationkey = supp_nation_key
|
||||
AND c_nationkey = cust_nation_key
|
||||
AND l_shipdate between date '1995-01-01' AND date '1996-12-31'
|
||||
) AS shipping
|
||||
GROUP BY
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year
|
||||
ORDER BY
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year;
|
||||
supp_nation | cust_nation | l_year | revenue
|
||||
---------------------------+---------------------------+--------+-----------
|
||||
GERMANY | FRANCE | 1995 | 2399.2948
|
||||
(1 row)
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
--
|
||||
-- MULTI_MX_COPY_DATA
|
||||
--
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 290000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 290000;
|
||||
|
||||
\COPY nation_hash FROM '@abs_srcdir@/data/nation.data' with delimiter '|';
|
||||
|
||||
SET search_path TO citus_mx_test_schema;
|
||||
\COPY nation_hash FROM '@abs_srcdir@/data/nation.data' with delimiter '|';
|
||||
\COPY citus_mx_test_schema_join_1.nation_hash FROM '@abs_srcdir@/data/nation.data' with delimiter '|';
|
||||
\COPY citus_mx_test_schema_join_1.nation_hash_2 FROM '@abs_srcdir@/data/nation.data' with delimiter '|';
|
||||
\COPY citus_mx_test_schema_join_2.nation_hash FROM '@abs_srcdir@/data/nation.data' with delimiter '|';
|
||||
|
||||
-- now try loading data from worker node
|
||||
\c - - - :worker_1_port
|
||||
SET search_path TO public;
|
||||
|
||||
\COPY lineitem_mx FROM '@abs_srcdir@/data/lineitem.1.data' with delimiter '|'
|
||||
\COPY lineitem_mx FROM '@abs_srcdir@/data/lineitem.2.data' with delimiter '|'
|
||||
|
||||
\COPY orders_mx FROM '@abs_srcdir@/data/orders.1.data' with delimiter '|'
|
||||
\COPY orders_mx FROM '@abs_srcdir@/data/orders.2.data' with delimiter '|'
|
||||
|
||||
-- and use second worker as well
|
||||
\c - - - :worker_2_port
|
||||
SET search_path TO public;
|
||||
|
||||
\COPY customer_mx FROM '@abs_srcdir@/data/customer.1.data' with delimiter '|'
|
||||
\COPY nation_mx FROM '@abs_srcdir@/data/nation.data' with delimiter '|'
|
||||
\COPY part_mx FROM '@abs_srcdir@/data/part.data' with delimiter '|'
|
||||
\COPY supplier_mx FROM '@abs_srcdir@/data/supplier.data' with delimiter '|'
|
|
@ -0,0 +1,29 @@
|
|||
# ----------
|
||||
# $Id$
|
||||
#
|
||||
# Regression tests for MX. This schedule runs tests for worker metadata
|
||||
# and MX tables. The tests mostly aim for running SQL queries from the worker
|
||||
# nodes and metadata operations from the schema node.
|
||||
#
|
||||
# Note that we use variant comparison files to test version dependent regression
|
||||
# test results. For more information:
|
||||
# http://www.postgresql.org/docs/9.5/static/regress-variant.html
|
||||
# ----------
|
||||
|
||||
# ---
|
||||
# Tests around schema changes, these are run first, so there's no preexisting objects.
|
||||
# ---
|
||||
test: multi_extension
|
||||
test: multi_cluster_management
|
||||
|
||||
test: multi_mx_create_table
|
||||
test: multi_mx_copy_data multi_mx_router_planner
|
||||
test: multi_mx_schema_support multi_mx_tpch_query1 multi_mx_tpch_query10
|
||||
test: multi_mx_tpch_query12 multi_mx_tpch_query14 multi_mx_tpch_query19
|
||||
test: multi_mx_tpch_query3 multi_mx_tpch_query6 multi_mx_tpch_query7
|
||||
test: multi_mx_tpch_query7_nested multi_mx_ddl
|
||||
test: multi_mx_repartition_udt_prepare
|
||||
test: multi_mx_repartition_join_w1 multi_mx_repartition_join_w2 multi_mx_repartition_udt_w1 multi_mx_repartition_udt_w2
|
||||
test: multi_mx_metadata multi_mx_modifications multi_mx_modifying_xacts
|
||||
test: multi_mx_explain
|
||||
test: multi_mx_reference_table
|
|
@ -0,0 +1,25 @@
|
|||
--
|
||||
-- MULTI_MX_COPY_DATA
|
||||
--
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 290000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 290000;
|
||||
\COPY nation_hash FROM '@abs_srcdir@/data/nation.data' with delimiter '|';
|
||||
SET search_path TO citus_mx_test_schema;
|
||||
\COPY nation_hash FROM '@abs_srcdir@/data/nation.data' with delimiter '|';
|
||||
\COPY citus_mx_test_schema_join_1.nation_hash FROM '@abs_srcdir@/data/nation.data' with delimiter '|';
|
||||
\COPY citus_mx_test_schema_join_1.nation_hash_2 FROM '@abs_srcdir@/data/nation.data' with delimiter '|';
|
||||
\COPY citus_mx_test_schema_join_2.nation_hash FROM '@abs_srcdir@/data/nation.data' with delimiter '|';
|
||||
-- now try loading data from worker node
|
||||
\c - - - :worker_1_port
|
||||
SET search_path TO public;
|
||||
\COPY lineitem_mx FROM '@abs_srcdir@/data/lineitem.1.data' with delimiter '|'
|
||||
\COPY lineitem_mx FROM '@abs_srcdir@/data/lineitem.2.data' with delimiter '|'
|
||||
\COPY orders_mx FROM '@abs_srcdir@/data/orders.1.data' with delimiter '|'
|
||||
\COPY orders_mx FROM '@abs_srcdir@/data/orders.2.data' with delimiter '|'
|
||||
-- and use second worker as well
|
||||
\c - - - :worker_2_port
|
||||
SET search_path TO public;
|
||||
\COPY customer_mx FROM '@abs_srcdir@/data/customer.1.data' with delimiter '|'
|
||||
\COPY nation_mx FROM '@abs_srcdir@/data/nation.data' with delimiter '|'
|
||||
\COPY part_mx FROM '@abs_srcdir@/data/part.data' with delimiter '|'
|
||||
\COPY supplier_mx FROM '@abs_srcdir@/data/supplier.data' with delimiter '|'
|
|
@ -15,3 +15,4 @@
|
|||
/multi_subquery_0.sql
|
||||
/worker_copy.sql
|
||||
/multi_complex_count_distinct.sql
|
||||
/multi_mx_copy_data.sql
|
||||
|
|
|
@ -0,0 +1,444 @@
|
|||
--
|
||||
-- MULTI_MX_CREATE_TABLE
|
||||
--
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1220000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1220000;
|
||||
|
||||
SELECT start_metadata_sync_to_node('localhost', :worker_1_port);
|
||||
SELECT start_metadata_sync_to_node('localhost', :worker_2_port);
|
||||
|
||||
-- create schema to test schema support
|
||||
CREATE SCHEMA citus_mx_test_schema;
|
||||
CREATE SCHEMA citus_mx_test_schema_join_1;
|
||||
CREATE SCHEMA citus_mx_test_schema_join_2;
|
||||
|
||||
-- create UDFs that we're going to use in our tests
|
||||
SET search_path TO public;
|
||||
CREATE OR REPLACE FUNCTION simpleTestFunction(theValue integer)
|
||||
RETURNS text AS
|
||||
$$
|
||||
DECLARE
|
||||
strresult text;
|
||||
BEGIN
|
||||
RETURN theValue * 3 / 2 + 1;
|
||||
END;
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
|
||||
SET search_path TO citus_mx_test_schema;
|
||||
CREATE OR REPLACE FUNCTION simpleTestFunction2(theValue integer)
|
||||
RETURNS text AS
|
||||
$$
|
||||
DECLARE
|
||||
strresult text;
|
||||
BEGIN
|
||||
RETURN theValue * 3 / 2 + 1;
|
||||
END;
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
|
||||
CREATE FUNCTION public.immutable_append_mx(old_values int[], new_value int)
|
||||
RETURNS int[] AS $$ SELECT old_values || new_value $$ LANGUAGE SQL IMMUTABLE;
|
||||
|
||||
CREATE OPERATOR citus_mx_test_schema.=== (
|
||||
LEFTARG = int,
|
||||
RIGHTARG = int,
|
||||
PROCEDURE = int4eq,
|
||||
COMMUTATOR = ===,
|
||||
NEGATOR = !==,
|
||||
HASHES, MERGES
|
||||
);
|
||||
|
||||
SET search_path TO public;
|
||||
CREATE COLLATION citus_mx_test_schema.english FROM "en_US";
|
||||
|
||||
CREATE TYPE citus_mx_test_schema.new_composite_type as (key1 text, key2 text);
|
||||
CREATE TYPE order_side_mx AS ENUM ('buy', 'sell');
|
||||
|
||||
-- now create required stuff in the worker 1
|
||||
\c - - - :worker_1_port
|
||||
|
||||
-- create schema to test schema support
|
||||
CREATE SCHEMA citus_mx_test_schema;
|
||||
CREATE SCHEMA citus_mx_test_schema_join_1;
|
||||
CREATE SCHEMA citus_mx_test_schema_join_2;
|
||||
|
||||
-- create UDFs in worker node
|
||||
CREATE OR REPLACE FUNCTION simpleTestFunction(theValue integer)
|
||||
RETURNS text AS
|
||||
$$
|
||||
DECLARE
|
||||
strresult text;
|
||||
BEGIN
|
||||
RETURN theValue * 3 / 2 + 1;
|
||||
END;
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
|
||||
SET search_path TO citus_mx_test_schema;
|
||||
CREATE OR REPLACE FUNCTION simpleTestFunction2(theValue integer)
|
||||
RETURNS text AS
|
||||
$$
|
||||
DECLARE
|
||||
strresult text;
|
||||
BEGIN
|
||||
RETURN theValue * 3 / 2 + 1;
|
||||
END;
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
|
||||
CREATE FUNCTION public.immutable_append_mx(old_values int[], new_value int)
|
||||
RETURNS int[] AS $$ SELECT old_values || new_value $$ LANGUAGE SQL IMMUTABLE;
|
||||
|
||||
-- create operator
|
||||
CREATE OPERATOR citus_mx_test_schema.=== (
|
||||
LEFTARG = int,
|
||||
RIGHTARG = int,
|
||||
PROCEDURE = int4eq,
|
||||
COMMUTATOR = ===,
|
||||
NEGATOR = !==,
|
||||
HASHES, MERGES
|
||||
);
|
||||
|
||||
SET search_path TO public;
|
||||
CREATE COLLATION citus_mx_test_schema.english FROM "en_US";
|
||||
|
||||
SET search_path TO public;
|
||||
CREATE TYPE citus_mx_test_schema.new_composite_type as (key1 text, key2 text);
|
||||
CREATE TYPE order_side_mx AS ENUM ('buy', 'sell');
|
||||
|
||||
-- now create required stuff in the worker 2
|
||||
\c - - - :worker_2_port
|
||||
|
||||
-- create schema to test schema support
|
||||
CREATE SCHEMA citus_mx_test_schema;
|
||||
CREATE SCHEMA citus_mx_test_schema_join_1;
|
||||
CREATE SCHEMA citus_mx_test_schema_join_2;
|
||||
|
||||
|
||||
-- create UDF
|
||||
CREATE OR REPLACE FUNCTION simpleTestFunction(theValue integer)
|
||||
RETURNS text AS
|
||||
$$
|
||||
DECLARE
|
||||
strresult text;
|
||||
BEGIN
|
||||
RETURN theValue * 3 / 2 + 1;
|
||||
END;
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
|
||||
SET search_path TO citus_mx_test_schema;
|
||||
CREATE OR REPLACE FUNCTION simpleTestFunction2(theValue integer)
|
||||
RETURNS text AS
|
||||
$$
|
||||
DECLARE
|
||||
strresult text;
|
||||
BEGIN
|
||||
RETURN theValue * 3 / 2 + 1;
|
||||
END;
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
|
||||
CREATE FUNCTION public.immutable_append_mx(old_values int[], new_value int)
|
||||
RETURNS int[] AS $$ SELECT old_values || new_value $$ LANGUAGE SQL IMMUTABLE;
|
||||
|
||||
-- create operator
|
||||
CREATE OPERATOR citus_mx_test_schema.=== (
|
||||
LEFTARG = int,
|
||||
RIGHTARG = int,
|
||||
PROCEDURE = int4eq,
|
||||
COMMUTATOR = ===,
|
||||
NEGATOR = !==,
|
||||
HASHES, MERGES
|
||||
);
|
||||
|
||||
|
||||
SET search_path TO public;
|
||||
CREATE COLLATION citus_mx_test_schema.english FROM "en_US";
|
||||
|
||||
SET search_path TO public;
|
||||
CREATE TYPE citus_mx_test_schema.new_composite_type as (key1 text, key2 text);
|
||||
CREATE TYPE order_side_mx AS ENUM ('buy', 'sell');
|
||||
|
||||
-- connect back to the master, and do some more tests
|
||||
\c - - - :master_port
|
||||
|
||||
SET citus.shard_replication_factor TO 1;
|
||||
SET citus.replication_model TO streaming;
|
||||
SET search_path TO public;
|
||||
|
||||
CREATE TABLE nation_hash(
|
||||
n_nationkey integer not null,
|
||||
n_name char(25) not null,
|
||||
n_regionkey integer not null,
|
||||
n_comment varchar(152)
|
||||
);
|
||||
|
||||
SET citus.shard_count TO 16;
|
||||
SELECT create_distributed_table('nation_hash', 'n_nationkey');
|
||||
|
||||
SET search_path TO citus_mx_test_schema;
|
||||
|
||||
-- create mx tables that we're going to use for our tests
|
||||
CREATE TABLE citus_mx_test_schema.nation_hash(
|
||||
n_nationkey integer not null,
|
||||
n_name char(25) not null,
|
||||
n_regionkey integer not null,
|
||||
n_comment varchar(152)
|
||||
);
|
||||
|
||||
SELECT create_distributed_table('nation_hash', 'n_nationkey');
|
||||
|
||||
CREATE TABLE citus_mx_test_schema_join_1.nation_hash (
|
||||
n_nationkey integer not null,
|
||||
n_name char(25) not null,
|
||||
n_regionkey integer not null,
|
||||
n_comment varchar(152));
|
||||
|
||||
SET citus.shard_count TO 4;
|
||||
SELECT create_distributed_table('citus_mx_test_schema_join_1.nation_hash', 'n_nationkey');
|
||||
|
||||
CREATE TABLE citus_mx_test_schema_join_1.nation_hash_2 (
|
||||
n_nationkey integer not null,
|
||||
n_name char(25) not null,
|
||||
n_regionkey integer not null,
|
||||
n_comment varchar(152));
|
||||
|
||||
SELECT create_distributed_table('citus_mx_test_schema_join_1.nation_hash_2', 'n_nationkey');
|
||||
|
||||
SET search_path TO citus_mx_test_schema_join_2;
|
||||
CREATE TABLE nation_hash (
|
||||
n_nationkey integer not null,
|
||||
n_name char(25) not null,
|
||||
n_regionkey integer not null,
|
||||
n_comment varchar(152));
|
||||
|
||||
SELECT create_distributed_table('nation_hash', 'n_nationkey');
|
||||
|
||||
SET search_path TO citus_mx_test_schema;
|
||||
CREATE TABLE nation_hash_collation_search_path(
|
||||
n_nationkey integer not null,
|
||||
n_name char(25) not null COLLATE english,
|
||||
n_regionkey integer not null,
|
||||
n_comment varchar(152)
|
||||
);
|
||||
SELECT create_distributed_table('nation_hash_collation_search_path', 'n_nationkey');
|
||||
|
||||
\COPY nation_hash_collation_search_path FROM STDIN with delimiter '|';
|
||||
0|ALGERIA|0|haggle. carefully final deposits detect slyly agai
|
||||
1|ARGENTINA|1|al foxes promise slyly according to the regular accounts. bold requests alon
|
||||
2|BRAZIL|1|y alongside of the pending deposits. carefully special packages are about the ironic forges. slyly special
|
||||
3|CANADA|1|eas hang ironic, silent packages. slyly regular packages are furiously over the tithes. fluffily bold
|
||||
4|EGYPT|4|y above the carefully unusual theodolites. final dugouts are quickly across the furiously regular d
|
||||
5|ETHIOPIA|0|ven packages wake quickly. regu
|
||||
\.
|
||||
|
||||
CREATE TABLE citus_mx_test_schema.nation_hash_composite_types(
|
||||
n_nationkey integer not null,
|
||||
n_name char(25) not null,
|
||||
n_regionkey integer not null,
|
||||
n_comment varchar(152),
|
||||
test_col citus_mx_test_schema.new_composite_type
|
||||
);
|
||||
|
||||
SELECT create_distributed_table('citus_mx_test_schema.nation_hash_composite_types', 'n_nationkey');
|
||||
|
||||
-- insert some data to verify composite type queries
|
||||
\COPY citus_mx_test_schema.nation_hash_composite_types FROM STDIN with delimiter '|';
|
||||
0|ALGERIA|0|haggle. carefully final deposits detect slyly agai|(a,a)
|
||||
1|ARGENTINA|1|al foxes promise slyly according to the regular accounts. bold requests alon|(a,b)
|
||||
2|BRAZIL|1|y alongside of the pending deposits. carefully special packages are about the ironic forges. slyly special |(a,c)
|
||||
3|CANADA|1|eas hang ironic, silent packages. slyly regular packages are furiously over the tithes. fluffily bold|(a,d)
|
||||
4|EGYPT|4|y above the carefully unusual theodolites. final dugouts are quickly across the furiously regular d|(a,e)
|
||||
5|ETHIOPIA|0|ven packages wake quickly. regu|(a,f)
|
||||
\.
|
||||
|
||||
-- now create tpch tables
|
||||
-- Create new table definitions for use in testing in distributed planning and
|
||||
-- execution functionality. Also create indexes to boost performance.
|
||||
SET search_path TO public;
|
||||
|
||||
CREATE TABLE lineitem_mx (
|
||||
l_orderkey bigint not null,
|
||||
l_partkey integer not null,
|
||||
l_suppkey integer not null,
|
||||
l_linenumber integer not null,
|
||||
l_quantity decimal(15, 2) not null,
|
||||
l_extendedprice decimal(15, 2) not null,
|
||||
l_discount decimal(15, 2) not null,
|
||||
l_tax decimal(15, 2) not null,
|
||||
l_returnflag char(1) not null,
|
||||
l_linestatus char(1) not null,
|
||||
l_shipdate date not null,
|
||||
l_commitdate date not null,
|
||||
l_receiptdate date not null,
|
||||
l_shipinstruct char(25) not null,
|
||||
l_shipmode char(10) not null,
|
||||
l_comment varchar(44) not null,
|
||||
PRIMARY KEY(l_orderkey, l_linenumber) );
|
||||
|
||||
SET citus.shard_count TO 16;
|
||||
SELECT create_distributed_table('lineitem_mx', 'l_orderkey');
|
||||
|
||||
CREATE INDEX lineitem_mx_time_index ON lineitem_mx (l_shipdate);
|
||||
|
||||
CREATE TABLE orders_mx (
|
||||
o_orderkey bigint not null,
|
||||
o_custkey integer not null,
|
||||
o_orderstatus char(1) not null,
|
||||
o_totalprice decimal(15,2) not null,
|
||||
o_orderdate date not null,
|
||||
o_orderpriority char(15) not null,
|
||||
o_clerk char(15) not null,
|
||||
o_shippriority integer not null,
|
||||
o_comment varchar(79) not null,
|
||||
PRIMARY KEY(o_orderkey) );
|
||||
SELECT create_distributed_table('orders_mx', 'o_orderkey');
|
||||
|
||||
CREATE TABLE customer_mx (
|
||||
c_custkey integer not null,
|
||||
c_name varchar(25) not null,
|
||||
c_address varchar(40) not null,
|
||||
c_nationkey integer not null,
|
||||
c_phone char(15) not null,
|
||||
c_acctbal decimal(15,2) not null,
|
||||
c_mktsegment char(10) not null,
|
||||
c_comment varchar(117) not null);
|
||||
|
||||
SET citus.shard_count TO 1;
|
||||
SELECT create_distributed_table('customer_mx', 'c_custkey');
|
||||
|
||||
CREATE TABLE nation_mx (
|
||||
n_nationkey integer not null,
|
||||
n_name char(25) not null,
|
||||
n_regionkey integer not null,
|
||||
n_comment varchar(152));
|
||||
|
||||
SELECT create_distributed_table('nation_mx', 'n_nationkey');
|
||||
|
||||
CREATE TABLE part_mx (
|
||||
p_partkey integer not null,
|
||||
p_name varchar(55) not null,
|
||||
p_mfgr char(25) not null,
|
||||
p_brand char(10) not null,
|
||||
p_type varchar(25) not null,
|
||||
p_size integer not null,
|
||||
p_container char(10) not null,
|
||||
p_retailprice decimal(15,2) not null,
|
||||
p_comment varchar(23) not null);
|
||||
|
||||
SELECT create_distributed_table('part_mx', 'p_partkey');
|
||||
|
||||
CREATE TABLE supplier_mx
|
||||
(
|
||||
s_suppkey integer not null,
|
||||
s_name char(25) not null,
|
||||
s_address varchar(40) not null,
|
||||
s_nationkey integer,
|
||||
s_phone char(15) not null,
|
||||
s_acctbal decimal(15,2) not null,
|
||||
s_comment varchar(101) not null
|
||||
);
|
||||
|
||||
SELECT create_distributed_table('supplier_mx', 's_suppkey');
|
||||
|
||||
-- Create test table for ddl
|
||||
CREATE TABLE mx_ddl_table (
|
||||
key int primary key,
|
||||
value int
|
||||
);
|
||||
|
||||
SET citus.shard_count TO 4;
|
||||
SELECT create_distributed_table('mx_ddl_table', 'key', 'hash');
|
||||
|
||||
-- Load some test data
|
||||
COPY mx_ddl_table (key, value) FROM STDIN WITH (FORMAT 'csv');
|
||||
1,10
|
||||
2,11
|
||||
3,21
|
||||
4,37
|
||||
5,60
|
||||
6,100
|
||||
10,200
|
||||
11,230
|
||||
\.
|
||||
|
||||
-- test table for modifications
|
||||
CREATE TABLE limit_orders_mx (
|
||||
id bigint PRIMARY KEY,
|
||||
symbol text NOT NULL,
|
||||
bidder_id bigint NOT NULL,
|
||||
placed_at timestamp NOT NULL,
|
||||
kind order_side_mx NOT NULL,
|
||||
limit_price decimal NOT NULL DEFAULT 0.00 CHECK (limit_price >= 0.00)
|
||||
);
|
||||
|
||||
SET citus.shard_count TO 2;
|
||||
SELECT create_distributed_table('limit_orders_mx', 'id');
|
||||
|
||||
-- test table for modifications
|
||||
CREATE TABLE multiple_hash_mx (
|
||||
category text NOT NULL,
|
||||
data text NOT NULL
|
||||
);
|
||||
|
||||
SELECT create_distributed_table('multiple_hash_mx', 'category');
|
||||
|
||||
SET citus.shard_count TO 4;
|
||||
CREATE TABLE app_analytics_events_mx (id bigserial, app_id integer, name text);
|
||||
SELECT create_distributed_table('app_analytics_events_mx', 'app_id');
|
||||
|
||||
|
||||
CREATE TABLE researchers_mx (
|
||||
id bigint NOT NULL,
|
||||
lab_id int NOT NULL,
|
||||
name text NOT NULL
|
||||
);
|
||||
|
||||
SET citus.shard_count TO 2;
|
||||
SELECT create_distributed_table('researchers_mx', 'lab_id');
|
||||
|
||||
CREATE TABLE labs_mx (
|
||||
id bigint NOT NULL,
|
||||
name text NOT NULL
|
||||
);
|
||||
|
||||
SET citus.shard_count TO 1;
|
||||
SELECT create_distributed_table('labs_mx', 'id');
|
||||
|
||||
-- now, for some special failures...
|
||||
CREATE TABLE objects_mx (
|
||||
id bigint PRIMARY KEY,
|
||||
name text NOT NULL
|
||||
);
|
||||
|
||||
SELECT create_distributed_table('objects_mx', 'id', 'hash');
|
||||
|
||||
CREATE TABLE articles_hash_mx (
|
||||
id bigint NOT NULL,
|
||||
author_id bigint NOT NULL,
|
||||
title varchar(20) NOT NULL,
|
||||
word_count integer
|
||||
);
|
||||
|
||||
-- this table is used in router executor tests
|
||||
CREATE TABLE articles_single_shard_hash_mx (LIKE articles_hash_mx);
|
||||
|
||||
SET citus.shard_count TO 2;
|
||||
SELECT create_distributed_table('articles_hash_mx', 'author_id');
|
||||
|
||||
SET citus.shard_count TO 1;
|
||||
SELECT create_distributed_table('articles_single_shard_hash_mx', 'author_id');
|
||||
|
||||
SET citus.shard_count TO 4;
|
||||
CREATE TABLE company_employees_mx (company_id int, employee_id int, manager_id int);
|
||||
SELECT create_distributed_table('company_employees_mx', 'company_id');
|
||||
|
||||
WITH shard_counts AS (
|
||||
SELECT logicalrelid, count(*) AS shard_count FROM pg_dist_shard GROUP BY logicalrelid
|
||||
)
|
||||
SELECT logicalrelid, colocationid, shard_count, partmethod, repmodel
|
||||
FROM pg_dist_partition NATURAL JOIN shard_counts
|
||||
ORDER BY colocationid, logicalrelid;
|
|
@ -0,0 +1,117 @@
|
|||
-- Tests related to distributed DDL commands on mx cluster
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1600000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1600000;
|
||||
|
||||
SELECT * FROM mx_ddl_table ORDER BY key;
|
||||
|
||||
-- CREATE INDEX
|
||||
CREATE INDEX ddl_test_index ON mx_ddl_table(value);
|
||||
|
||||
-- ADD COLUMN
|
||||
ALTER TABLE mx_ddl_table ADD COLUMN version INTEGER;
|
||||
|
||||
-- SET DEFAULT
|
||||
ALTER TABLE mx_ddl_table ALTER COLUMN version SET DEFAULT 1;
|
||||
|
||||
SELECT master_modify_multiple_shards('UPDATE mx_ddl_table SET version=0.1 WHERE version IS NULL');
|
||||
|
||||
-- SET NOT NULL
|
||||
ALTER TABLE mx_ddl_table ALTER COLUMN version SET NOT NULL;
|
||||
|
||||
|
||||
-- See that the changes are applied on schema node, worker tables and shards
|
||||
\d mx_ddl_table
|
||||
|
||||
\c - - - :worker_1_port
|
||||
|
||||
\d mx_ddl_table
|
||||
|
||||
\d mx_ddl_table_1600000
|
||||
|
||||
\c - - - :worker_2_port
|
||||
|
||||
\d mx_ddl_table
|
||||
|
||||
\d mx_ddl_table_1600001
|
||||
|
||||
INSERT INTO mx_ddl_table VALUES (37, 78, 2);
|
||||
INSERT INTO mx_ddl_table VALUES (38, 78);
|
||||
|
||||
-- Switch to the schema node
|
||||
\c - - - :master_port
|
||||
|
||||
|
||||
-- SET DATA TYPE
|
||||
ALTER TABLE mx_ddl_table ALTER COLUMN version SET DATA TYPE double precision;
|
||||
|
||||
INSERT INTO mx_ddl_table VALUES (78, 83, 2.1);
|
||||
|
||||
\c - - - :worker_1_port
|
||||
SELECT * FROM mx_ddl_table ORDER BY key;
|
||||
|
||||
-- Switch to the schema node
|
||||
\c - - - :master_port
|
||||
|
||||
-- DROP INDEX
|
||||
DROP INDEX ddl_test_index;
|
||||
|
||||
-- DROP DEFAULT
|
||||
ALTER TABLE mx_ddl_table ALTER COLUMN version DROP DEFAULT;
|
||||
|
||||
-- DROP NOT NULL
|
||||
ALTER TABLE mx_ddl_table ALTER COLUMN version DROP NOT NULL;
|
||||
|
||||
-- DROP COLUMN
|
||||
ALTER TABLE mx_ddl_table DROP COLUMN version;
|
||||
|
||||
|
||||
-- See that the changes are applied on schema node, worker tables and shards
|
||||
\d mx_ddl_table
|
||||
|
||||
\c - - - :worker_1_port
|
||||
|
||||
\d mx_ddl_table
|
||||
|
||||
\d mx_ddl_table_1600000
|
||||
|
||||
\c - - - :worker_2_port
|
||||
|
||||
\d mx_ddl_table
|
||||
|
||||
\d mx_ddl_table_1600001
|
||||
|
||||
-- Show that DDL commands are done within a two-phase commit transaction
|
||||
\c - - - :master_port
|
||||
|
||||
SET client_min_messages TO debug2;
|
||||
|
||||
CREATE INDEX ddl_test_index ON mx_ddl_table(value);
|
||||
|
||||
RESET client_min_messages;
|
||||
|
||||
DROP INDEX ddl_test_index;
|
||||
|
||||
-- show that sequences owned by mx tables result in unique values
|
||||
SET citus.shard_replication_factor TO 1;
|
||||
SET citus.shard_count TO 4;
|
||||
SET citus.replication_model TO streaming;
|
||||
CREATE TABLE mx_sequence(key INT, value BIGSERIAL);
|
||||
SELECT create_distributed_table('mx_sequence', 'key');
|
||||
|
||||
\c - - - :worker_1_port
|
||||
|
||||
SELECT groupid FROM pg_dist_local_group;
|
||||
SELECT * FROM mx_sequence_value_seq;
|
||||
|
||||
\c - - - :worker_2_port
|
||||
|
||||
SELECT groupid FROM pg_dist_local_group;
|
||||
SELECT * FROM mx_sequence_value_seq;
|
||||
|
||||
\c - - - :master_port
|
||||
|
||||
-- the type of sequences can't be changed
|
||||
ALTER TABLE mx_sequence ALTER value TYPE BIGINT;
|
||||
ALTER TABLE mx_sequence ALTER value TYPE INT;
|
||||
|
|
@ -0,0 +1,207 @@
|
|||
--
|
||||
-- MULTI_MX_EXPLAIN
|
||||
--
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1320000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1320000;
|
||||
\c - - - :worker_1_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1320000;
|
||||
\c - - - :worker_2_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1320000;
|
||||
\c - - - :master_port
|
||||
|
||||
\a\t
|
||||
|
||||
SET citus.task_executor_type TO 'real-time';
|
||||
SET citus.explain_distributed_queries TO on;
|
||||
|
||||
\c - - - :worker_1_port
|
||||
-- Function that parses explain output as JSON
|
||||
CREATE FUNCTION explain_json(query text)
|
||||
RETURNS jsonb
|
||||
AS $BODY$
|
||||
DECLARE
|
||||
result jsonb;
|
||||
BEGIN
|
||||
EXECUTE format('EXPLAIN (FORMAT JSON) %s', query) INTO result;
|
||||
RETURN result;
|
||||
END;
|
||||
$BODY$ LANGUAGE plpgsql;
|
||||
|
||||
-- Function that parses explain output as XML
|
||||
CREATE FUNCTION explain_xml(query text)
|
||||
RETURNS xml
|
||||
AS $BODY$
|
||||
DECLARE
|
||||
result xml;
|
||||
BEGIN
|
||||
EXECUTE format('EXPLAIN (FORMAT XML) %s', query) INTO result;
|
||||
RETURN result;
|
||||
END;
|
||||
$BODY$ LANGUAGE plpgsql;
|
||||
|
||||
\c - - - :worker_2_port
|
||||
-- Function that parses explain output as JSON
|
||||
CREATE FUNCTION explain_json(query text)
|
||||
RETURNS jsonb
|
||||
AS $BODY$
|
||||
DECLARE
|
||||
result jsonb;
|
||||
BEGIN
|
||||
EXECUTE format('EXPLAIN (FORMAT JSON) %s', query) INTO result;
|
||||
RETURN result;
|
||||
END;
|
||||
$BODY$ LANGUAGE plpgsql;
|
||||
|
||||
-- Function that parses explain output as XML
|
||||
CREATE FUNCTION explain_xml(query text)
|
||||
RETURNS xml
|
||||
AS $BODY$
|
||||
DECLARE
|
||||
result xml;
|
||||
BEGIN
|
||||
EXECUTE format('EXPLAIN (FORMAT XML) %s', query) INTO result;
|
||||
RETURN result;
|
||||
END;
|
||||
$BODY$ LANGUAGE plpgsql;
|
||||
|
||||
-- Test Text format
|
||||
EXPLAIN (COSTS FALSE, FORMAT TEXT)
|
||||
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
||||
|
||||
-- Test JSON format
|
||||
EXPLAIN (COSTS FALSE, FORMAT JSON)
|
||||
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
||||
|
||||
-- Validate JSON format
|
||||
SELECT true AS valid FROM explain_json($$
|
||||
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity$$);
|
||||
|
||||
\c - - - :worker_1_port
|
||||
-- Test XML format
|
||||
EXPLAIN (COSTS FALSE, FORMAT XML)
|
||||
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
||||
|
||||
-- Validate XML format
|
||||
SELECT true AS valid FROM explain_xml($$
|
||||
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity$$);
|
||||
|
||||
-- Test YAML format
|
||||
EXPLAIN (COSTS FALSE, FORMAT YAML)
|
||||
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
||||
|
||||
-- Test Text format
|
||||
EXPLAIN (COSTS FALSE, FORMAT TEXT)
|
||||
SELECT l_quantity, count(*) count_quantity FROM lineitem_mx
|
||||
GROUP BY l_quantity ORDER BY count_quantity, l_quantity;
|
||||
|
||||
\c - - - :worker_2_port
|
||||
-- Test verbose
|
||||
EXPLAIN (COSTS FALSE, VERBOSE TRUE)
|
||||
SELECT sum(l_quantity) / avg(l_quantity) FROM lineitem_mx;
|
||||
|
||||
-- Test join
|
||||
EXPLAIN (COSTS FALSE)
|
||||
SELECT * FROM lineitem_mx
|
||||
JOIN orders_mx ON l_orderkey = o_orderkey AND l_quantity < 5.0
|
||||
ORDER BY l_quantity LIMIT 10;
|
||||
|
||||
-- Test insert
|
||||
EXPLAIN (COSTS FALSE)
|
||||
INSERT INTO lineitem_mx VALUES(1,0);
|
||||
|
||||
-- Test update
|
||||
EXPLAIN (COSTS FALSE)
|
||||
UPDATE lineitem_mx
|
||||
SET l_suppkey = 12
|
||||
WHERE l_orderkey = 1 AND l_partkey = 0;
|
||||
|
||||
-- Test delete
|
||||
EXPLAIN (COSTS FALSE)
|
||||
DELETE FROM lineitem_mx
|
||||
WHERE l_orderkey = 1 AND l_partkey = 0;
|
||||
|
||||
-- Test single-shard SELECT
|
||||
EXPLAIN (COSTS FALSE)
|
||||
SELECT l_quantity FROM lineitem_mx WHERE l_orderkey = 5;
|
||||
|
||||
SELECT true AS valid FROM explain_xml($$
|
||||
SELECT l_quantity FROM lineitem_mx WHERE l_orderkey = 5$$);
|
||||
|
||||
SELECT true AS valid FROM explain_json($$
|
||||
SELECT l_quantity FROM lineitem_mx WHERE l_orderkey = 5$$);
|
||||
|
||||
-- Test CREATE TABLE ... AS
|
||||
EXPLAIN (COSTS FALSE)
|
||||
CREATE TABLE explain_result AS
|
||||
SELECT * FROM lineitem_mx;
|
||||
|
||||
-- Test all tasks output
|
||||
SET citus.explain_all_tasks TO on;
|
||||
|
||||
EXPLAIN (COSTS FALSE)
|
||||
SELECT avg(l_linenumber) FROM lineitem_mx WHERE l_orderkey > 9030;
|
||||
|
||||
SELECT true AS valid FROM explain_xml($$
|
||||
SELECT avg(l_linenumber) FROM lineitem_mx WHERE l_orderkey > 9030$$);
|
||||
|
||||
SELECT true AS valid FROM explain_json($$
|
||||
SELECT avg(l_linenumber) FROM lineitem_mx WHERE l_orderkey > 9030$$);
|
||||
|
||||
-- Test track tracker
|
||||
SET citus.task_executor_type TO 'task-tracker';
|
||||
SET citus.explain_all_tasks TO off;
|
||||
|
||||
EXPLAIN (COSTS FALSE)
|
||||
SELECT avg(l_linenumber) FROM lineitem_mx WHERE l_orderkey > 9030;
|
||||
|
||||
-- Test re-partition join
|
||||
SET citus.large_table_shard_count TO 1;
|
||||
|
||||
EXPLAIN (COSTS FALSE)
|
||||
SELECT count(*)
|
||||
FROM lineitem_mx, orders_mx, customer_mx, supplier_mx
|
||||
WHERE l_orderkey = o_orderkey
|
||||
AND o_custkey = c_custkey
|
||||
AND l_suppkey = s_suppkey;
|
||||
|
||||
EXPLAIN (COSTS FALSE, FORMAT JSON)
|
||||
SELECT count(*)
|
||||
FROM lineitem_mx, orders_mx, customer_mx, supplier_mx
|
||||
WHERE l_orderkey = o_orderkey
|
||||
AND o_custkey = c_custkey
|
||||
AND l_suppkey = s_suppkey;
|
||||
|
||||
SELECT true AS valid FROM explain_json($$
|
||||
SELECT count(*)
|
||||
FROM lineitem_mx, orders_mx, customer_mx, supplier_mx
|
||||
WHERE l_orderkey = o_orderkey
|
||||
AND o_custkey = c_custkey
|
||||
AND l_suppkey = s_suppkey$$);
|
||||
|
||||
EXPLAIN (COSTS FALSE, FORMAT XML)
|
||||
SELECT count(*)
|
||||
FROM lineitem_mx, orders_mx, customer_mx, supplier_mx
|
||||
WHERE l_orderkey = o_orderkey
|
||||
AND o_custkey = c_custkey
|
||||
AND l_suppkey = s_suppkey;
|
||||
|
||||
SELECT true AS valid FROM explain_xml($$
|
||||
SELECT count(*)
|
||||
FROM lineitem_mx, orders_mx, customer_mx, supplier_mx
|
||||
WHERE l_orderkey = o_orderkey
|
||||
AND o_custkey = c_custkey
|
||||
AND l_suppkey = s_suppkey$$);
|
||||
|
||||
EXPLAIN (COSTS FALSE, FORMAT YAML)
|
||||
SELECT count(*)
|
||||
FROM lineitem_mx, orders_mx, customer_mx, supplier_mx
|
||||
WHERE l_orderkey = o_orderkey
|
||||
AND o_custkey = c_custkey
|
||||
AND l_suppkey = s_suppkey;
|
|
@ -0,0 +1,162 @@
|
|||
-- Test creation of mx tables and metadata syncing
|
||||
|
||||
-- get rid of the previously created entries in pg_dist_transaction
|
||||
-- for the sake of getting consistent results in this test file
|
||||
SELECT recover_prepared_transactions();
|
||||
|
||||
CREATE TABLE distributed_mx_table (
|
||||
key text primary key,
|
||||
value jsonb
|
||||
);
|
||||
CREATE INDEX ON distributed_mx_table USING GIN (value);
|
||||
|
||||
SET citus.shard_replication_factor TO 1;
|
||||
SET citus.replication_model TO streaming;
|
||||
|
||||
SET citus.shard_count TO 4;
|
||||
SELECT create_distributed_table('distributed_mx_table', 'key');
|
||||
|
||||
-- Verify that we've logged commit records
|
||||
SELECT count(*) FROM pg_dist_transaction;
|
||||
|
||||
-- Confirm that the metadata transactions have been committed
|
||||
SELECT recover_prepared_transactions();
|
||||
|
||||
-- Verify that the commit records have been removed
|
||||
SELECT count(*) FROM pg_dist_transaction;
|
||||
|
||||
\c - - - :worker_1_port
|
||||
|
||||
\d distributed_mx_table
|
||||
|
||||
SELECT repmodel FROM pg_dist_partition
|
||||
WHERE logicalrelid = 'distributed_mx_table'::regclass;
|
||||
|
||||
SELECT count(*) FROM pg_dist_shard JOIN pg_dist_shard_placement USING (shardid)
|
||||
WHERE logicalrelid = 'distributed_mx_table'::regclass;
|
||||
|
||||
\c - - - :worker_2_port
|
||||
|
||||
\d distributed_mx_table
|
||||
|
||||
SELECT repmodel FROM pg_dist_partition
|
||||
WHERE logicalrelid = 'distributed_mx_table'::regclass;
|
||||
|
||||
SELECT count(*) FROM pg_dist_shard JOIN pg_dist_shard_placement USING (shardid)
|
||||
WHERE logicalrelid = 'distributed_mx_table'::regclass;
|
||||
|
||||
-- Create a table and then roll back the transaction
|
||||
\c - - - :master_port
|
||||
SET citus.shard_replication_factor TO 1;
|
||||
SET citus.replication_model TO streaming;
|
||||
|
||||
BEGIN;
|
||||
CREATE TABLE should_not_exist (
|
||||
key text primary key,
|
||||
value jsonb
|
||||
);
|
||||
SELECT create_distributed_table('should_not_exist', 'key');
|
||||
ABORT;
|
||||
|
||||
-- Verify that the table does not exist on the worker
|
||||
\c - - - :worker_1_port
|
||||
SELECT count(*) FROM pg_tables WHERE tablename = 'should_not_exist';
|
||||
|
||||
-- Ensure that we don't allow prepare on a metadata transaction
|
||||
\c - - - :master_port
|
||||
SET citus.shard_replication_factor TO 1;
|
||||
SET citus.replication_model TO streaming;
|
||||
|
||||
BEGIN;
|
||||
CREATE TABLE should_not_exist (
|
||||
key text primary key,
|
||||
value jsonb
|
||||
);
|
||||
SELECT create_distributed_table('should_not_exist', 'key');
|
||||
PREPARE TRANSACTION 'this_should_fail';
|
||||
|
||||
-- now show that we can create tables and schemas withing a single transaction
|
||||
BEGIN;
|
||||
CREATE SCHEMA IF NOT EXISTS citus_mx_schema_for_xacts;
|
||||
SET search_path TO citus_mx_schema_for_xacts;
|
||||
SET citus.shard_replication_factor TO 1;
|
||||
SET citus.shard_count TO 1;
|
||||
|
||||
CREATE TABLE objects_for_xacts (
|
||||
id bigint PRIMARY KEY,
|
||||
name text NOT NULL
|
||||
);
|
||||
SELECT create_distributed_table('objects_for_xacts', 'id');
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- see that the table actually created and distributed
|
||||
\c - - - :worker_1_port
|
||||
SELECT repmodel FROM pg_dist_partition
|
||||
WHERE logicalrelid = 'citus_mx_schema_for_xacts.objects_for_xacts'::regclass;
|
||||
|
||||
SELECT count(*) FROM pg_dist_shard JOIN pg_dist_shard_placement USING (shardid)
|
||||
WHERE logicalrelid = 'citus_mx_schema_for_xacts.objects_for_xacts'::regclass;
|
||||
|
||||
\c - - - :master_port
|
||||
SET citus.shard_replication_factor TO 1;
|
||||
SET citus.replication_model TO streaming;
|
||||
|
||||
-- now show that we can rollback on creating mx table, but shards remain....
|
||||
BEGIN;
|
||||
CREATE SCHEMA IF NOT EXISTS citus_mx_schema_for_xacts;
|
||||
SET search_path TO citus_mx_schema_for_xacts;
|
||||
SET citus.shard_replication_factor TO 1;
|
||||
SET citus.shard_count TO 2;
|
||||
|
||||
CREATE TABLE objects_for_xacts2 (
|
||||
id bigint PRIMARY KEY,
|
||||
name text NOT NULL
|
||||
);
|
||||
SELECT create_distributed_table('objects_for_xacts2', 'id');
|
||||
|
||||
ROLLBACK;
|
||||
|
||||
-- show that the table not exists on the schema node
|
||||
SELECT count(*) FROM pg_tables WHERE tablename = 'objects_for_xacts2' and schemaname = 'citus_mx_schema_for_xacts';
|
||||
|
||||
\c - - - :worker_1_port
|
||||
|
||||
-- the distributed table not exists on the worker node
|
||||
SELECT count(*) FROM pg_tables WHERE tablename = 'objects_for_xacts2' and schemaname = 'citus_mx_schema_for_xacts';
|
||||
-- but the shard exists since we do not create shards in a transaction
|
||||
SELECT count(*) FROM pg_tables WHERE tablename LIKE 'objects_for_xacts2_%' and schemaname = 'citus_mx_schema_for_xacts';
|
||||
|
||||
-- make sure that master_drop_all_shards does not work from the worker nodes
|
||||
SELECT master_drop_all_shards('citus_mx_schema_for_xacts.objects_for_xacts'::regclass, 'citus_mx_schema_for_xacts', 'objects_for_xacts');
|
||||
|
||||
-- Ensure pg_dist_transaction is empty for test
|
||||
SELECT recover_prepared_transactions();
|
||||
|
||||
-- Create some "fake" prepared transactions to recover
|
||||
\c - - - :worker_1_port
|
||||
|
||||
BEGIN;
|
||||
CREATE TABLE should_abort (value int);
|
||||
PREPARE TRANSACTION 'citus_0_should_abort';
|
||||
|
||||
BEGIN;
|
||||
CREATE TABLE should_commit (value int);
|
||||
PREPARE TRANSACTION 'citus_0_should_commit';
|
||||
|
||||
BEGIN;
|
||||
CREATE TABLE should_be_sorted_into_middle (value int);
|
||||
PREPARE TRANSACTION 'citus_0_should_be_sorted_into_middle';
|
||||
|
||||
\c - - - :master_port
|
||||
-- Add "fake" pg_dist_transaction records and run recovery
|
||||
INSERT INTO pg_dist_transaction VALUES (14, 'citus_0_should_commit');
|
||||
INSERT INTO pg_dist_transaction VALUES (14, 'citus_0_should_be_forgotten');
|
||||
|
||||
SELECT recover_prepared_transactions();
|
||||
SELECT count(*) FROM pg_dist_transaction;
|
||||
|
||||
-- Confirm that transactions were correctly rolled forward
|
||||
\c - - - :worker_1_port
|
||||
SELECT count(*) FROM pg_tables WHERE tablename = 'should_abort';
|
||||
SELECT count(*) FROM pg_tables WHERE tablename = 'should_commit';
|
|
@ -0,0 +1,282 @@
|
|||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1330000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1330000;
|
||||
|
||||
|
||||
-- ===================================================================
|
||||
-- test end-to-end modification functionality for mx tables
|
||||
-- ===================================================================
|
||||
|
||||
-- basic single-row INSERT
|
||||
INSERT INTO limit_orders_mx VALUES (32743, 'AAPL', 9580, '2004-10-19 10:23:54', 'buy',
|
||||
20.69);
|
||||
SELECT COUNT(*) FROM limit_orders_mx WHERE id = 32743;
|
||||
|
||||
-- now singe-row INSERT from a worker
|
||||
\c - - - :worker_1_port
|
||||
INSERT INTO limit_orders_mx VALUES (32744, 'AAPL', 9580, '2004-10-19 10:23:54', 'buy',
|
||||
20.69);
|
||||
SELECT COUNT(*) FROM limit_orders_mx WHERE id = 32744;
|
||||
|
||||
-- now singe-row INSERT to the other worker
|
||||
\c - - - :worker_2_port
|
||||
INSERT INTO limit_orders_mx VALUES (32745, 'AAPL', 9580, '2004-10-19 10:23:54', 'buy',
|
||||
20.69);
|
||||
SELECT COUNT(*) FROM limit_orders_mx WHERE id = 32745;
|
||||
|
||||
-- and see all the inserted rows
|
||||
SELECT * FROM limit_orders_mx;
|
||||
|
||||
-- basic single-row INSERT with RETURNING
|
||||
INSERT INTO limit_orders_mx VALUES (32746, 'AAPL', 9580, '2004-10-19 10:23:54', 'buy', 20.69) RETURNING *;
|
||||
|
||||
-- INSERT with DEFAULT in the target list
|
||||
INSERT INTO limit_orders_mx VALUES (12756, 'MSFT', 10959, '2013-05-08 07:29:23', 'sell',
|
||||
DEFAULT);
|
||||
SELECT * FROM limit_orders_mx WHERE id = 12756;
|
||||
|
||||
-- INSERT with expressions in target list
|
||||
INSERT INTO limit_orders_mx VALUES (430, upper('ibm'), 214, timestamp '2003-01-28 10:31:17' +
|
||||
interval '5 hours', 'buy', sqrt(2));
|
||||
SELECT * FROM limit_orders_mx WHERE id = 430;
|
||||
|
||||
-- INSERT without partition key
|
||||
INSERT INTO limit_orders_mx DEFAULT VALUES;
|
||||
|
||||
-- squelch WARNINGs that contain worker_port
|
||||
SET client_min_messages TO ERROR;
|
||||
|
||||
-- INSERT violating NOT NULL constraint
|
||||
INSERT INTO limit_orders_mx VALUES (NULL, 'T', 975234, DEFAULT);
|
||||
|
||||
-- INSERT violating column constraint
|
||||
INSERT INTO limit_orders_mx VALUES (18811, 'BUD', 14962, '2014-04-05 08:32:16', 'sell',
|
||||
-5.00);
|
||||
-- INSERT violating primary key constraint
|
||||
INSERT INTO limit_orders_mx VALUES (32743, 'LUV', 5994, '2001-04-16 03:37:28', 'buy', 0.58);
|
||||
|
||||
-- INSERT violating primary key constraint, with RETURNING specified.
|
||||
INSERT INTO limit_orders_mx VALUES (32743, 'LUV', 5994, '2001-04-16 03:37:28', 'buy', 0.58) RETURNING *;
|
||||
|
||||
-- INSERT, with RETURNING specified, failing with a non-constraint error
|
||||
INSERT INTO limit_orders_mx VALUES (34153, 'LEE', 5994, '2001-04-16 03:37:28', 'buy', 0.58) RETURNING id / 0;
|
||||
|
||||
SET client_min_messages TO DEFAULT;
|
||||
|
||||
-- commands with non-constant partition values are unsupported
|
||||
INSERT INTO limit_orders_mx VALUES (random() * 100, 'ORCL', 152, '2011-08-25 11:50:45',
|
||||
'sell', 0.58);
|
||||
|
||||
-- values for other columns are totally fine
|
||||
INSERT INTO limit_orders_mx VALUES (2036, 'GOOG', 5634, now(), 'buy', random());
|
||||
|
||||
-- commands with mutable functions in their quals
|
||||
DELETE FROM limit_orders_mx WHERE id = 246 AND bidder_id = (random() * 1000);
|
||||
|
||||
-- commands with mutable but non-volatile functions(ie: stable func.) in their quals
|
||||
-- (the cast to timestamp is because the timestamp_eq_timestamptz operator is stable)
|
||||
DELETE FROM limit_orders_mx WHERE id = 246 AND placed_at = current_timestamp::timestamp;
|
||||
|
||||
-- commands with multiple rows are unsupported
|
||||
INSERT INTO limit_orders_mx VALUES (DEFAULT), (DEFAULT);
|
||||
|
||||
-- INSERT ... SELECT ... FROM commands are unsupported from workers
|
||||
INSERT INTO limit_orders_mx SELECT * FROM limit_orders_mx;
|
||||
|
||||
-- connect back to the other node
|
||||
\c - - - :worker_1_port
|
||||
|
||||
-- commands containing a CTE are unsupported
|
||||
WITH deleted_orders AS (DELETE FROM limit_orders_mx RETURNING *)
|
||||
INSERT INTO limit_orders_mx DEFAULT VALUES;
|
||||
|
||||
-- test simple DELETE
|
||||
INSERT INTO limit_orders_mx VALUES (246, 'TSLA', 162, '2007-07-02 16:32:15', 'sell', 20.69);
|
||||
SELECT COUNT(*) FROM limit_orders_mx WHERE id = 246;
|
||||
|
||||
DELETE FROM limit_orders_mx WHERE id = 246;
|
||||
SELECT COUNT(*) FROM limit_orders_mx WHERE id = 246;
|
||||
|
||||
-- test simple DELETE with RETURNING
|
||||
DELETE FROM limit_orders_mx WHERE id = 430 RETURNING *;
|
||||
SELECT COUNT(*) FROM limit_orders_mx WHERE id = 430;
|
||||
|
||||
-- DELETE with expression in WHERE clause
|
||||
INSERT INTO limit_orders_mx VALUES (246, 'TSLA', 162, '2007-07-02 16:32:15', 'sell', 20.69);
|
||||
SELECT COUNT(*) FROM limit_orders_mx WHERE id = 246;
|
||||
|
||||
DELETE FROM limit_orders_mx WHERE id = (2 * 123);
|
||||
SELECT COUNT(*) FROM limit_orders_mx WHERE id = 246;
|
||||
|
||||
-- commands with no constraints on the partition key are not supported
|
||||
DELETE FROM limit_orders_mx WHERE bidder_id = 162;
|
||||
|
||||
-- commands with a USING clause are unsupported
|
||||
CREATE TABLE bidders ( name text, id bigint );
|
||||
DELETE FROM limit_orders_mx USING bidders WHERE limit_orders_mx.id = 246 AND
|
||||
limit_orders_mx.bidder_id = bidders.id AND
|
||||
bidders.name = 'Bernie Madoff';
|
||||
|
||||
-- commands containing a CTE are unsupported
|
||||
WITH deleted_orders AS (INSERT INTO limit_orders_mx DEFAULT VALUES RETURNING *)
|
||||
DELETE FROM limit_orders_mx;
|
||||
|
||||
-- cursors are not supported
|
||||
DELETE FROM limit_orders_mx WHERE CURRENT OF cursor_name;
|
||||
|
||||
INSERT INTO limit_orders_mx VALUES (246, 'TSLA', 162, '2007-07-02 16:32:15', 'sell', 20.69);
|
||||
|
||||
-- simple UPDATE
|
||||
UPDATE limit_orders_mx SET symbol = 'GM' WHERE id = 246;
|
||||
SELECT symbol FROM limit_orders_mx WHERE id = 246;
|
||||
|
||||
-- simple UPDATE with RETURNING
|
||||
UPDATE limit_orders_mx SET symbol = 'GM' WHERE id = 246 RETURNING *;
|
||||
|
||||
-- expression UPDATE
|
||||
UPDATE limit_orders_mx SET bidder_id = 6 * 3 WHERE id = 246;
|
||||
SELECT bidder_id FROM limit_orders_mx WHERE id = 246;
|
||||
|
||||
-- expression UPDATE with RETURNING
|
||||
UPDATE limit_orders_mx SET bidder_id = 6 * 5 WHERE id = 246 RETURNING *;
|
||||
|
||||
-- multi-column UPDATE
|
||||
UPDATE limit_orders_mx SET (kind, limit_price) = ('buy', DEFAULT) WHERE id = 246;
|
||||
SELECT kind, limit_price FROM limit_orders_mx WHERE id = 246;
|
||||
|
||||
-- multi-column UPDATE with RETURNING
|
||||
UPDATE limit_orders_mx SET (kind, limit_price) = ('buy', 999) WHERE id = 246 RETURNING *;
|
||||
|
||||
-- Test that on unique contraint violations, we fail fast
|
||||
INSERT INTO limit_orders_mx VALUES (275, 'ADR', 140, '2007-07-02 16:32:15', 'sell', 43.67);
|
||||
INSERT INTO limit_orders_mx VALUES (275, 'ADR', 140, '2007-07-02 16:32:15', 'sell', 43.67);
|
||||
|
||||
-- commands with no constraints on the partition key are not supported
|
||||
UPDATE limit_orders_mx SET limit_price = 0.00;
|
||||
|
||||
-- attempting to change the partition key is unsupported
|
||||
UPDATE limit_orders_mx SET id = 0 WHERE id = 246;
|
||||
|
||||
-- UPDATEs with a FROM clause are unsupported
|
||||
UPDATE limit_orders_mx SET limit_price = 0.00 FROM bidders
|
||||
WHERE limit_orders_mx.id = 246 AND
|
||||
limit_orders_mx.bidder_id = bidders.id AND
|
||||
bidders.name = 'Bernie Madoff';
|
||||
|
||||
-- commands containing a CTE are unsupported
|
||||
WITH deleted_orders AS (INSERT INTO limit_orders_mx DEFAULT VALUES RETURNING *)
|
||||
UPDATE limit_orders_mx SET symbol = 'GM';
|
||||
|
||||
SELECT symbol, bidder_id FROM limit_orders_mx WHERE id = 246;
|
||||
|
||||
-- updates referencing just a var are supported
|
||||
UPDATE limit_orders_mx SET bidder_id = id WHERE id = 246;
|
||||
|
||||
-- updates referencing a column are supported
|
||||
UPDATE limit_orders_mx SET bidder_id = bidder_id + 1 WHERE id = 246;
|
||||
|
||||
-- IMMUTABLE functions are allowed
|
||||
UPDATE limit_orders_mx SET symbol = LOWER(symbol) WHERE id = 246;
|
||||
|
||||
SELECT symbol, bidder_id FROM limit_orders_mx WHERE id = 246;
|
||||
|
||||
-- IMMUTABLE functions are allowed -- even in returning
|
||||
UPDATE limit_orders_mx SET symbol = UPPER(symbol) WHERE id = 246 RETURNING id, LOWER(symbol), symbol;
|
||||
|
||||
-- connect schema node to run the DDL
|
||||
\c - - - :master_port
|
||||
ALTER TABLE limit_orders_mx ADD COLUMN array_of_values integer[];
|
||||
|
||||
-- connect back to the other node
|
||||
\c - - - :worker_2_port
|
||||
|
||||
-- updates referencing STABLE functions are allowed
|
||||
UPDATE limit_orders_mx SET placed_at = LEAST(placed_at, now()::timestamp) WHERE id = 246;
|
||||
-- so are binary operators
|
||||
UPDATE limit_orders_mx SET array_of_values = 1 || array_of_values WHERE id = 246;
|
||||
|
||||
-- connect back to the other node
|
||||
\c - - - :worker_2_port
|
||||
|
||||
-- immutable function calls with vars are also allowed
|
||||
UPDATE limit_orders_mx
|
||||
SET array_of_values = immutable_append_mx(array_of_values, 2) WHERE id = 246;
|
||||
|
||||
CREATE FUNCTION stable_append_mx(old_values int[], new_value int)
|
||||
RETURNS int[] AS $$ BEGIN RETURN old_values || new_value; END; $$
|
||||
LANGUAGE plpgsql STABLE;
|
||||
|
||||
-- but STABLE function calls with vars are not allowed
|
||||
UPDATE limit_orders_mx
|
||||
SET array_of_values = stable_append_mx(array_of_values, 3) WHERE id = 246;
|
||||
|
||||
SELECT array_of_values FROM limit_orders_mx WHERE id = 246;
|
||||
|
||||
-- STRICT functions work as expected
|
||||
CREATE FUNCTION temp_strict_func(integer,integer) RETURNS integer AS
|
||||
'SELECT COALESCE($1, 2) + COALESCE($1, 3);' LANGUAGE SQL STABLE STRICT;
|
||||
UPDATE limit_orders_mx SET bidder_id = temp_strict_func(1, null) WHERE id = 246;
|
||||
|
||||
SELECT array_of_values FROM limit_orders_mx WHERE id = 246;
|
||||
|
||||
-- connect schema node to run the DDL
|
||||
\c - - - :master_port
|
||||
ALTER TABLE limit_orders_mx DROP array_of_values;
|
||||
|
||||
-- connect back to the other node
|
||||
\c - - - :worker_2_port
|
||||
|
||||
-- even in RETURNING
|
||||
UPDATE limit_orders_mx SET placed_at = placed_at WHERE id = 246 RETURNING NOW();
|
||||
|
||||
-- cursors are not supported
|
||||
UPDATE limit_orders_mx SET symbol = 'GM' WHERE CURRENT OF cursor_name;
|
||||
|
||||
-- check that multi-row UPDATE/DELETEs with RETURNING work
|
||||
INSERT INTO multiple_hash_mx VALUES ('0', '1');
|
||||
INSERT INTO multiple_hash_mx VALUES ('0', '2');
|
||||
INSERT INTO multiple_hash_mx VALUES ('0', '3');
|
||||
INSERT INTO multiple_hash_mx VALUES ('0', '4');
|
||||
INSERT INTO multiple_hash_mx VALUES ('0', '5');
|
||||
INSERT INTO multiple_hash_mx VALUES ('0', '6');
|
||||
|
||||
UPDATE multiple_hash_mx SET data = data ||'-1' WHERE category = '0' RETURNING *;
|
||||
DELETE FROM multiple_hash_mx WHERE category = '0' RETURNING *;
|
||||
|
||||
-- ensure returned row counters are correct
|
||||
\set QUIET off
|
||||
INSERT INTO multiple_hash_mx VALUES ('1', '1');
|
||||
INSERT INTO multiple_hash_mx VALUES ('1', '2');
|
||||
INSERT INTO multiple_hash_mx VALUES ('1', '3');
|
||||
INSERT INTO multiple_hash_mx VALUES ('2', '1');
|
||||
INSERT INTO multiple_hash_mx VALUES ('2', '2');
|
||||
INSERT INTO multiple_hash_mx VALUES ('2', '3');
|
||||
INSERT INTO multiple_hash_mx VALUES ('2', '3') RETURNING *;
|
||||
|
||||
-- check that update return the right number of rows
|
||||
-- one row
|
||||
UPDATE multiple_hash_mx SET data = data ||'-1' WHERE category = '1' AND data = '1';
|
||||
-- three rows
|
||||
UPDATE multiple_hash_mx SET data = data ||'-2' WHERE category = '1';
|
||||
-- three rows, with RETURNING
|
||||
UPDATE multiple_hash_mx SET data = data ||'-2' WHERE category = '1' RETURNING category;
|
||||
-- check
|
||||
SELECT * FROM multiple_hash_mx WHERE category = '1' ORDER BY category, data;
|
||||
|
||||
-- check that deletes return the right number of rows
|
||||
-- one row
|
||||
DELETE FROM multiple_hash_mx WHERE category = '2' AND data = '1';
|
||||
-- two rows
|
||||
DELETE FROM multiple_hash_mx WHERE category = '2';
|
||||
-- three rows, with RETURNING
|
||||
DELETE FROM multiple_hash_mx WHERE category = '1' RETURNING category;
|
||||
-- check
|
||||
SELECT * FROM multiple_hash_mx WHERE category = '1' ORDER BY category, data;
|
||||
SELECT * FROM multiple_hash_mx WHERE category = '2' ORDER BY category, data;
|
||||
|
||||
-- verify interaction of default values, SERIAL, and RETURNING
|
||||
\set QUIET on
|
||||
|
||||
INSERT INTO app_analytics_events_mx VALUES (DEFAULT, 101, 'Fauxkemon Geaux') RETURNING id;
|
||||
INSERT INTO app_analytics_events_mx (app_id, name) VALUES (102, 'Wayz') RETURNING id;
|
||||
INSERT INTO app_analytics_events_mx (app_id, name) VALUES (103, 'Mynt') RETURNING *;
|
|
@ -0,0 +1,330 @@
|
|||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1340000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1340000;
|
||||
|
||||
|
||||
-- ===================================================================
|
||||
-- test end-to-end modification functionality for mx tables in transactions
|
||||
-- ===================================================================
|
||||
|
||||
-- add some data
|
||||
INSERT INTO researchers_mx VALUES (1, 1, 'Donald Knuth');
|
||||
INSERT INTO researchers_mx VALUES (2, 1, 'Niklaus Wirth');
|
||||
INSERT INTO researchers_mx VALUES (3, 2, 'Tony Hoare');
|
||||
INSERT INTO researchers_mx VALUES (4, 2, 'Kenneth Iverson');
|
||||
|
||||
-- replace a researcher, reusing their id on the schema node
|
||||
BEGIN;
|
||||
DELETE FROM researchers_mx WHERE lab_id = 1 AND id = 2;
|
||||
INSERT INTO researchers_mx VALUES (2, 1, 'John Backus');
|
||||
COMMIT;
|
||||
SELECT name FROM researchers_mx WHERE lab_id = 1 AND id = 2;
|
||||
|
||||
-- do it on the worker node as well
|
||||
\c - - - :worker_1_port
|
||||
BEGIN;
|
||||
DELETE FROM researchers_mx WHERE lab_id = 1 AND id = 2;
|
||||
INSERT INTO researchers_mx VALUES (2, 1, 'John Backus Worker 1');
|
||||
COMMIT;
|
||||
SELECT name FROM researchers_mx WHERE lab_id = 1 AND id = 2;
|
||||
|
||||
-- do it on the worker other node as well
|
||||
\c - - - :worker_2_port
|
||||
BEGIN;
|
||||
DELETE FROM researchers_mx WHERE lab_id = 1 AND id = 2;
|
||||
INSERT INTO researchers_mx VALUES (2, 1, 'John Backus Worker 2');
|
||||
COMMIT;
|
||||
SELECT name FROM researchers_mx WHERE lab_id = 1 AND id = 2;
|
||||
|
||||
|
||||
\c - - - :master_port
|
||||
|
||||
-- abort a modification
|
||||
BEGIN;
|
||||
DELETE FROM researchers_mx WHERE lab_id = 1 AND id = 1;
|
||||
ABORT;
|
||||
|
||||
SELECT name FROM researchers_mx WHERE lab_id = 1 AND id = 1;
|
||||
|
||||
\c - - - :worker_1_port
|
||||
|
||||
-- abort a modification on the worker node
|
||||
BEGIN;
|
||||
DELETE FROM researchers_mx WHERE lab_id = 1 AND id = 1;
|
||||
ABORT;
|
||||
|
||||
SELECT name FROM researchers_mx WHERE lab_id = 1 AND id = 1;
|
||||
|
||||
\c - - - :worker_2_port
|
||||
|
||||
-- abort a modification on the other worker node
|
||||
BEGIN;
|
||||
DELETE FROM researchers_mx WHERE lab_id = 1 AND id = 1;
|
||||
ABORT;
|
||||
|
||||
SELECT name FROM researchers_mx WHERE lab_id = 1 AND id = 1;
|
||||
|
||||
|
||||
-- switch back to the first worker node
|
||||
\c - - - :worker_1_port
|
||||
|
||||
-- creating savepoints should work...
|
||||
BEGIN;
|
||||
INSERT INTO researchers_mx VALUES (5, 3, 'Dennis Ritchie');
|
||||
SAVEPOINT hire_thompson;
|
||||
INSERT INTO researchers_mx VALUES (6, 3, 'Ken Thompson');
|
||||
COMMIT;
|
||||
|
||||
SELECT name FROM researchers_mx WHERE lab_id = 3 AND id = 6;
|
||||
|
||||
-- even if created by PL/pgSQL...
|
||||
\set VERBOSITY terse
|
||||
BEGIN;
|
||||
DO $$
|
||||
BEGIN
|
||||
INSERT INTO researchers_mx VALUES (10, 10, 'Edsger Dijkstra');
|
||||
EXCEPTION
|
||||
WHEN not_null_violation THEN
|
||||
RAISE NOTICE 'caught not_null_violation';
|
||||
END $$;
|
||||
COMMIT;
|
||||
|
||||
-- but rollback should not
|
||||
BEGIN;
|
||||
INSERT INTO researchers_mx VALUES (7, 4, 'Jim Gray');
|
||||
SAVEPOINT hire_engelbart;
|
||||
INSERT INTO researchers_mx VALUES (8, 4, 'Douglas Engelbart');
|
||||
ROLLBACK TO hire_engelbart;
|
||||
COMMIT;
|
||||
|
||||
SELECT name FROM researchers_mx WHERE lab_id = 4;
|
||||
|
||||
BEGIN;
|
||||
DO $$
|
||||
BEGIN
|
||||
INSERT INTO researchers_mx VALUES (NULL, 10, 'Edsger Dijkstra');
|
||||
EXCEPTION
|
||||
WHEN not_null_violation THEN
|
||||
RAISE NOTICE 'caught not_null_violation';
|
||||
END $$;
|
||||
COMMIT;
|
||||
\set VERBOSITY default
|
||||
|
||||
|
||||
-- should be valid to edit labs_mx after researchers_mx...
|
||||
BEGIN;
|
||||
INSERT INTO researchers_mx VALUES (8, 5, 'Douglas Engelbart');
|
||||
INSERT INTO labs_mx VALUES (5, 'Los Alamos');
|
||||
COMMIT;
|
||||
|
||||
SELECT * FROM researchers_mx, labs_mx WHERE labs_mx.id = researchers_mx.lab_id;
|
||||
|
||||
-- but not the other way around (would require expanding xact participants)...
|
||||
BEGIN;
|
||||
INSERT INTO labs_mx VALUES (6, 'Bell labs_mx');
|
||||
INSERT INTO researchers_mx VALUES (9, 6, 'Leslie Lamport');
|
||||
COMMIT;
|
||||
|
||||
-- have the same test on the other worker node
|
||||
\c - - - :worker_2_port
|
||||
-- should be valid to edit labs_mx after researchers_mx...
|
||||
BEGIN;
|
||||
INSERT INTO researchers_mx VALUES (8, 5, 'Douglas Engelbart');
|
||||
INSERT INTO labs_mx VALUES (5, 'Los Alamos');
|
||||
COMMIT;
|
||||
|
||||
SELECT * FROM researchers_mx, labs_mx WHERE labs_mx.id = researchers_mx.lab_id;
|
||||
|
||||
-- but not the other way around (would require expanding xact participants)...
|
||||
BEGIN;
|
||||
INSERT INTO labs_mx VALUES (6, 'Bell labs_mx');
|
||||
INSERT INTO researchers_mx VALUES (9, 6, 'Leslie Lamport');
|
||||
COMMIT;
|
||||
|
||||
-- switch back to the worker node
|
||||
\c - - - :worker_1_port
|
||||
|
||||
-- this logic doesn't apply to router SELECTs occurring after a modification:
|
||||
-- selecting from the modified node is fine...
|
||||
BEGIN;
|
||||
INSERT INTO labs_mx VALUES (6, 'Bell labs_mx');
|
||||
SELECT count(*) FROM researchers_mx WHERE lab_id = 6;
|
||||
ABORT;
|
||||
|
||||
-- applies to DDL
|
||||
BEGIN;
|
||||
INSERT INTO labs_mx VALUES (6, 'Bell labs_mx');
|
||||
ALTER TABLE labs_mx ADD COLUMN text motto;
|
||||
COMMIT;
|
||||
|
||||
-- doesn't apply to COPY after modifications
|
||||
BEGIN;
|
||||
INSERT INTO labs_mx VALUES (6, 'Bell labs_mx');
|
||||
\copy labs_mx from stdin delimiter ','
|
||||
10,Weyland-Yutani-1
|
||||
\.
|
||||
COMMIT;
|
||||
|
||||
-- copy will also work if before any modifications
|
||||
BEGIN;
|
||||
\copy labs_mx from stdin delimiter ','
|
||||
10,Weyland-Yutani-2
|
||||
\.
|
||||
SELECT name FROM labs_mx WHERE id = 10;
|
||||
INSERT INTO labs_mx VALUES (6, 'Bell labs_mx');
|
||||
COMMIT;
|
||||
|
||||
\c - - - :worker_1_port
|
||||
-- test primary key violations
|
||||
BEGIN;
|
||||
INSERT INTO objects_mx VALUES (1, 'apple');
|
||||
INSERT INTO objects_mx VALUES (1, 'orange');
|
||||
COMMIT;
|
||||
|
||||
-- data shouldn't have persisted...
|
||||
SELECT * FROM objects_mx WHERE id = 1;
|
||||
|
||||
-- same test on the second worker node
|
||||
\c - - - :worker_2_port
|
||||
-- test primary key violations
|
||||
BEGIN;
|
||||
INSERT INTO objects_mx VALUES (1, 'apple');
|
||||
INSERT INTO objects_mx VALUES (1, 'orange');
|
||||
COMMIT;
|
||||
|
||||
-- data shouldn't have persisted...
|
||||
SELECT * FROM objects_mx WHERE id = 1;
|
||||
|
||||
-- create trigger on one worker to reject certain values
|
||||
\c - - - :worker_1_port
|
||||
|
||||
CREATE FUNCTION reject_bad_mx() RETURNS trigger AS $rb$
|
||||
BEGIN
|
||||
IF (NEW.name = 'BAD') THEN
|
||||
RAISE 'illegal value';
|
||||
END IF;
|
||||
|
||||
RETURN NEW;
|
||||
END;
|
||||
$rb$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE CONSTRAINT TRIGGER reject_bad_mx
|
||||
AFTER INSERT ON objects_mx_1220103
|
||||
DEFERRABLE INITIALLY IMMEDIATE
|
||||
FOR EACH ROW EXECUTE PROCEDURE reject_bad_mx();
|
||||
|
||||
-- test partial failure; statement 1 successed, statement 2 fails
|
||||
\set VERBOSITY terse
|
||||
BEGIN;
|
||||
INSERT INTO labs_mx VALUES (7, 'E Corp');
|
||||
INSERT INTO objects_mx VALUES (2, 'BAD');
|
||||
COMMIT;
|
||||
|
||||
-- data should NOT be persisted
|
||||
SELECT * FROM objects_mx WHERE id = 2;
|
||||
SELECT * FROM labs_mx WHERE id = 7;
|
||||
|
||||
-- same failure test from worker 2
|
||||
\c - - - :worker_2_port
|
||||
|
||||
-- test partial failure; statement 1 successed, statement 2 fails
|
||||
BEGIN;
|
||||
INSERT INTO labs_mx VALUES (7, 'E Corp');
|
||||
INSERT INTO objects_mx VALUES (2, 'BAD');
|
||||
COMMIT;
|
||||
|
||||
-- data should NOT be persisted
|
||||
SELECT * FROM objects_mx WHERE id = 2;
|
||||
SELECT * FROM labs_mx WHERE id = 7;
|
||||
|
||||
\c - - - :worker_1_port
|
||||
|
||||
-- what if there are errors on different shards at different times?
|
||||
\c - - - :worker_1_port
|
||||
|
||||
CREATE CONSTRAINT TRIGGER reject_bad_mx
|
||||
AFTER INSERT ON labs_mx_1220102
|
||||
DEFERRABLE INITIALLY IMMEDIATE
|
||||
FOR EACH ROW EXECUTE PROCEDURE reject_bad_mx();
|
||||
|
||||
BEGIN;
|
||||
INSERT INTO objects_mx VALUES (1, 'apple');
|
||||
INSERT INTO objects_mx VALUES (2, 'BAD');
|
||||
INSERT INTO labs_mx VALUES (8, 'Aperture Science');
|
||||
INSERT INTO labs_mx VALUES (9, 'BAD');
|
||||
COMMIT;
|
||||
|
||||
-- data should NOT be persisted
|
||||
SELECT * FROM objects_mx WHERE id = 1;
|
||||
SELECT * FROM labs_mx WHERE id = 8;
|
||||
|
||||
-- same test from the other worker
|
||||
\c - - - :worker_2_port
|
||||
|
||||
|
||||
BEGIN;
|
||||
INSERT INTO objects_mx VALUES (1, 'apple');
|
||||
INSERT INTO objects_mx VALUES (2, 'BAD');
|
||||
INSERT INTO labs_mx VALUES (8, 'Aperture Science');
|
||||
INSERT INTO labs_mx VALUES (9, 'BAD');
|
||||
COMMIT;
|
||||
|
||||
-- data should NOT be persisted
|
||||
SELECT * FROM objects_mx WHERE id = 1;
|
||||
SELECT * FROM labs_mx WHERE id = 8;
|
||||
|
||||
|
||||
-- what if the failures happen at COMMIT time?
|
||||
\c - - - :worker_1_port
|
||||
|
||||
DROP TRIGGER reject_bad_mx ON objects_mx_1220103;
|
||||
|
||||
CREATE CONSTRAINT TRIGGER reject_bad_mx
|
||||
AFTER INSERT ON objects_mx_1220103
|
||||
DEFERRABLE INITIALLY DEFERRED
|
||||
FOR EACH ROW EXECUTE PROCEDURE reject_bad_mx();
|
||||
|
||||
-- should be the same story as before, just at COMMIT time
|
||||
BEGIN;
|
||||
INSERT INTO objects_mx VALUES (1, 'apple');
|
||||
INSERT INTO objects_mx VALUES (2, 'BAD');
|
||||
INSERT INTO labs_mx VALUES (9, 'Umbrella Corporation');
|
||||
COMMIT;
|
||||
|
||||
-- data should NOT be persisted
|
||||
SELECT * FROM objects_mx WHERE id = 2;
|
||||
SELECT * FROM labs_mx WHERE id = 7;
|
||||
|
||||
|
||||
DROP TRIGGER reject_bad_mx ON labs_mx_1220102;
|
||||
|
||||
CREATE CONSTRAINT TRIGGER reject_bad_mx
|
||||
AFTER INSERT ON labs_mx_1220102
|
||||
DEFERRABLE INITIALLY DEFERRED
|
||||
FOR EACH ROW EXECUTE PROCEDURE reject_bad_mx();
|
||||
|
||||
BEGIN;
|
||||
INSERT INTO objects_mx VALUES (1, 'apple');
|
||||
INSERT INTO objects_mx VALUES (2, 'BAD');
|
||||
INSERT INTO labs_mx VALUES (8, 'Aperture Science');
|
||||
INSERT INTO labs_mx VALUES (9, 'BAD');
|
||||
COMMIT;
|
||||
|
||||
-- data should NOT be persisted
|
||||
SELECT * FROM objects_mx WHERE id = 1;
|
||||
SELECT * FROM labs_mx WHERE id = 8;
|
||||
|
||||
-- what if one shard (objects_mx) succeeds but another (labs_mx) completely fails?
|
||||
\c - - - :worker_1_port
|
||||
|
||||
DROP TRIGGER reject_bad_mx ON objects_mx_1220103;
|
||||
|
||||
BEGIN;
|
||||
INSERT INTO objects_mx VALUES (1, 'apple');
|
||||
INSERT INTO labs_mx VALUES (8, 'Aperture Science');
|
||||
INSERT INTO labs_mx VALUES (9, 'BAD');
|
||||
COMMIT;
|
||||
|
||||
-- no data should persists
|
||||
SELECT * FROM objects_mx WHERE id = 1;
|
||||
SELECT * FROM labs_mx WHERE id = 8;
|
|
@ -0,0 +1,521 @@
|
|||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1250000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1250000;
|
||||
|
||||
\c - - - :master_port
|
||||
CREATE TABLE reference_table_test (value_1 int, value_2 float, value_3 text, value_4 timestamp);
|
||||
SELECT create_reference_table('reference_table_test');
|
||||
|
||||
INSERT INTO reference_table_test VALUES (1, 1.0, '1', '2016-12-01');
|
||||
INSERT INTO reference_table_test VALUES (2, 2.0, '2', '2016-12-02');
|
||||
INSERT INTO reference_table_test VALUES (3, 3.0, '3', '2016-12-03');
|
||||
INSERT INTO reference_table_test VALUES (4, 4.0, '4', '2016-12-04');
|
||||
INSERT INTO reference_table_test VALUES (5, 5.0, '5', '2016-12-05');
|
||||
|
||||
\c - - - :worker_1_port
|
||||
-- run some queries on top of the data
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
reference_table_test;
|
||||
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
value_1 = 1;
|
||||
|
||||
SELECT
|
||||
value_1,
|
||||
value_2
|
||||
FROM
|
||||
reference_table_test
|
||||
ORDER BY
|
||||
2 ASC LIMIT 3;
|
||||
|
||||
SELECT
|
||||
value_1, value_3
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
value_2 >= 4
|
||||
ORDER BY
|
||||
2 LIMIT 3;
|
||||
|
||||
SELECT
|
||||
value_1, 15 * value_2
|
||||
FROM
|
||||
reference_table_test
|
||||
ORDER BY
|
||||
2 ASC
|
||||
LIMIT 2;
|
||||
|
||||
SELECT
|
||||
value_1, 15 * value_2
|
||||
FROM
|
||||
reference_table_test
|
||||
ORDER BY
|
||||
2 ASC LIMIT 2 OFFSET 2;
|
||||
|
||||
SELECT
|
||||
value_2, value_4
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
value_2 = 2 OR value_2 = 3;
|
||||
|
||||
SELECT
|
||||
value_2, value_4
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
value_2 = 2 AND value_2 = 3;
|
||||
|
||||
SELECT
|
||||
value_2, value_4
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
value_3 = '2' OR value_1 = 3;
|
||||
|
||||
SELECT
|
||||
value_2, value_4
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
(
|
||||
value_3 = '2' OR value_1 = 3
|
||||
)
|
||||
AND FALSE;
|
||||
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
value_2 IN
|
||||
(
|
||||
SELECT
|
||||
value_3::FLOAT
|
||||
FROM
|
||||
reference_table_test
|
||||
)
|
||||
AND value_1 < 3;
|
||||
|
||||
SELECT
|
||||
value_4
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
value_3 IN
|
||||
(
|
||||
'1', '2'
|
||||
);
|
||||
|
||||
SELECT
|
||||
date_part('day', value_4)
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
value_3 IN
|
||||
(
|
||||
'5', '2'
|
||||
);
|
||||
|
||||
SELECT
|
||||
value_4
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
value_2 <= 2 AND value_2 >= 4;
|
||||
|
||||
SELECT
|
||||
value_4
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
value_2 <= 20 AND value_2 >= 4;
|
||||
|
||||
SELECT
|
||||
value_4
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
value_2 >= 5 AND value_2 <= random();
|
||||
|
||||
SELECT
|
||||
value_1
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
value_4 BETWEEN '2016-12-01' AND '2016-12-03';
|
||||
|
||||
SELECT
|
||||
value_1
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
FALSE;
|
||||
SELECT
|
||||
value_1
|
||||
FROM
|
||||
reference_table_test
|
||||
WHERE
|
||||
int4eq(1, 2);
|
||||
|
||||
-- rename output name and do some operations
|
||||
SELECT
|
||||
value_1 as id, value_2 * 15 as age
|
||||
FROM
|
||||
reference_table_test;
|
||||
|
||||
-- queries with CTEs are supported
|
||||
WITH some_data AS ( SELECT value_2, value_4 FROM reference_table_test WHERE value_2 >=3)
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
some_data;
|
||||
|
||||
-- queries with CTEs are supported even if CTE is not referenced inside query
|
||||
WITH some_data AS ( SELECT value_2, value_4 FROM reference_table_test WHERE value_2 >=3)
|
||||
SELECT * FROM reference_table_test ORDER BY 1 LIMIT 1;
|
||||
|
||||
-- queries which involve functions in FROM clause are supported if it goes to a single worker.
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
reference_table_test, position('om' in 'Thomas')
|
||||
WHERE
|
||||
value_1 = 1;
|
||||
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
reference_table_test, position('om' in 'Thomas')
|
||||
WHERE
|
||||
value_1 = 1 OR value_1 = 2;
|
||||
|
||||
-- set operations are supported
|
||||
(SELECT * FROM reference_table_test WHERE value_1 = 1)
|
||||
UNION
|
||||
(SELECT * FROM reference_table_test WHERE value_1 = 3);
|
||||
|
||||
(SELECT * FROM reference_table_test WHERE value_1 = 1)
|
||||
EXCEPT
|
||||
(SELECT * FROM reference_table_test WHERE value_1 = 3);
|
||||
|
||||
(SELECT * FROM reference_table_test WHERE value_1 = 1)
|
||||
INTERSECT
|
||||
(SELECT * FROM reference_table_test WHERE value_1 = 3);
|
||||
|
||||
-- to make the tests more interested for aggregation tests, ingest some more data
|
||||
\c - - - :master_port
|
||||
INSERT INTO reference_table_test VALUES (1, 1.0, '1', '2016-12-01');
|
||||
INSERT INTO reference_table_test VALUES (2, 2.0, '2', '2016-12-02');
|
||||
INSERT INTO reference_table_test VALUES (3, 3.0, '3', '2016-12-03');
|
||||
\c - - - :worker_1_port
|
||||
|
||||
-- some aggregations
|
||||
SELECT
|
||||
value_4, SUM(value_2)
|
||||
FROM
|
||||
reference_table_test
|
||||
GROUP BY
|
||||
value_4
|
||||
HAVING
|
||||
SUM(value_2) > 3
|
||||
ORDER BY
|
||||
1;
|
||||
|
||||
SELECT
|
||||
value_4,
|
||||
value_3,
|
||||
SUM(value_2)
|
||||
FROM
|
||||
reference_table_test
|
||||
GROUP BY
|
||||
GROUPING sets ((value_4), (value_3))
|
||||
ORDER BY 1, 2, 3;
|
||||
|
||||
|
||||
-- distinct clauses also work fine
|
||||
SELECT DISTINCT
|
||||
value_4
|
||||
FROM
|
||||
reference_table_test
|
||||
ORDER BY
|
||||
1;
|
||||
|
||||
-- window functions are also supported
|
||||
SELECT
|
||||
value_4, RANK() OVER (PARTITION BY value_1 ORDER BY value_4)
|
||||
FROM
|
||||
reference_table_test;
|
||||
|
||||
-- window functions are also supported
|
||||
SELECT
|
||||
value_4, AVG(value_1) OVER (PARTITION BY value_4 ORDER BY value_4)
|
||||
FROM
|
||||
reference_table_test;
|
||||
|
||||
SELECT
|
||||
count(DISTINCT CASE
|
||||
WHEN
|
||||
value_2 >= 3
|
||||
THEN
|
||||
value_2
|
||||
ELSE
|
||||
NULL
|
||||
END) as c
|
||||
FROM
|
||||
reference_table_test;
|
||||
|
||||
SELECT
|
||||
value_1,
|
||||
count(DISTINCT CASE
|
||||
WHEN
|
||||
value_2 >= 3
|
||||
THEN
|
||||
value_2
|
||||
ELSE
|
||||
NULL
|
||||
END) as c
|
||||
FROM
|
||||
reference_table_test
|
||||
GROUP BY
|
||||
value_1
|
||||
ORDER BY
|
||||
1;
|
||||
|
||||
-- selects inside a transaction works fine as well
|
||||
|
||||
BEGIN;
|
||||
SELECT * FROM reference_table_test;
|
||||
SELECT * FROM reference_table_test WHERE value_1 = 1;
|
||||
END;
|
||||
|
||||
-- cursor queries also works fine
|
||||
BEGIN;
|
||||
DECLARE test_cursor CURSOR FOR
|
||||
SELECT *
|
||||
FROM reference_table_test
|
||||
WHERE value_1 = 1 OR value_1 = 2
|
||||
ORDER BY value_1;
|
||||
FETCH test_cursor;
|
||||
FETCH ALL test_cursor;
|
||||
FETCH test_cursor; -- fetch one row after the last
|
||||
END;
|
||||
|
||||
-- table creation queries inside can be router plannable
|
||||
CREATE TEMP TABLE temp_reference_test as
|
||||
SELECT *
|
||||
FROM reference_table_test
|
||||
WHERE value_1 = 1;
|
||||
|
||||
\c - - - :master_port
|
||||
-- all kinds of joins are supported among reference tables
|
||||
-- first create two more tables
|
||||
CREATE TABLE reference_table_test_second (value_1 int, value_2 float, value_3 text, value_4 timestamp);
|
||||
SELECT create_reference_table('reference_table_test_second');
|
||||
|
||||
CREATE TABLE reference_table_test_third (value_1 int, value_2 float, value_3 text, value_4 timestamp);
|
||||
SELECT create_reference_table('reference_table_test_third');
|
||||
|
||||
-- ingest some data to both tables
|
||||
INSERT INTO reference_table_test_second VALUES (1, 1.0, '1', '2016-12-01');
|
||||
INSERT INTO reference_table_test_second VALUES (2, 2.0, '2', '2016-12-02');
|
||||
INSERT INTO reference_table_test_second VALUES (3, 3.0, '3', '2016-12-03');
|
||||
|
||||
INSERT INTO reference_table_test_third VALUES (4, 4.0, '4', '2016-12-04');
|
||||
INSERT INTO reference_table_test_third VALUES (5, 5.0, '5', '2016-12-05');
|
||||
|
||||
\c - - - :worker_2_port
|
||||
|
||||
-- some very basic tests
|
||||
SELECT
|
||||
DISTINCT t1.value_1
|
||||
FROM
|
||||
reference_table_test t1, reference_table_test_second t2
|
||||
WHERE
|
||||
t1.value_2 = t2.value_2
|
||||
ORDER BY
|
||||
1;
|
||||
|
||||
SELECT
|
||||
DISTINCT t1.value_1
|
||||
FROM
|
||||
reference_table_test t1, reference_table_test_third t3
|
||||
WHERE
|
||||
t1.value_2 = t3.value_2
|
||||
ORDER BY
|
||||
1;
|
||||
|
||||
SELECT
|
||||
DISTINCT t2.value_1
|
||||
FROM
|
||||
reference_table_test_second t2, reference_table_test_third t3
|
||||
WHERE
|
||||
t2.value_2 = t3.value_2
|
||||
ORDER BY
|
||||
1;
|
||||
|
||||
-- join on different columns and different data types via casts
|
||||
SELECT
|
||||
DISTINCT t1.value_1
|
||||
FROM
|
||||
reference_table_test t1, reference_table_test_second t2
|
||||
WHERE
|
||||
t1.value_2 = t2.value_1
|
||||
ORDER BY
|
||||
1;
|
||||
|
||||
SELECT
|
||||
DISTINCT t1.value_1
|
||||
FROM
|
||||
reference_table_test t1, reference_table_test_second t2
|
||||
WHERE
|
||||
t1.value_2 = t2.value_3::int
|
||||
ORDER BY
|
||||
1;
|
||||
|
||||
SELECT
|
||||
DISTINCT t1.value_1
|
||||
FROM
|
||||
reference_table_test t1, reference_table_test_second t2
|
||||
WHERE
|
||||
t1.value_2 = date_part('day', t2.value_4)
|
||||
ORDER BY
|
||||
1;
|
||||
|
||||
-- ingest a common row to see more meaningful results with joins involving 3 tables
|
||||
\c - - - :master_port
|
||||
INSERT INTO reference_table_test_third VALUES (3, 3.0, '3', '2016-12-03');
|
||||
\c - - - :worker_1_port
|
||||
|
||||
SELECT
|
||||
DISTINCT t1.value_1
|
||||
FROM
|
||||
reference_table_test t1, reference_table_test_second t2, reference_table_test_third t3
|
||||
WHERE
|
||||
t1.value_2 = date_part('day', t2.value_4) AND t3.value_2 = t1.value_2
|
||||
ORDER BY
|
||||
1;
|
||||
|
||||
-- same query on different columns
|
||||
SELECT
|
||||
DISTINCT t1.value_1
|
||||
FROM
|
||||
reference_table_test t1, reference_table_test_second t2, reference_table_test_third t3
|
||||
WHERE
|
||||
t1.value_1 = date_part('day', t2.value_4) AND t3.value_2 = t1.value_1
|
||||
ORDER BY
|
||||
1;
|
||||
|
||||
-- with the JOIN syntax
|
||||
SELECT
|
||||
DISTINCT t1.value_1
|
||||
FROM
|
||||
reference_table_test t1 JOIN reference_table_test_second t2 USING (value_1)
|
||||
JOIN reference_table_test_third t3 USING (value_1)
|
||||
ORDER BY
|
||||
1;
|
||||
|
||||
-- and left/right joins
|
||||
SELECT
|
||||
DISTINCT t1.value_1
|
||||
FROM
|
||||
reference_table_test t1 LEFT JOIN reference_table_test_second t2 USING (value_1)
|
||||
LEFT JOIN reference_table_test_third t3 USING (value_1)
|
||||
ORDER BY
|
||||
1;
|
||||
|
||||
SELECT
|
||||
DISTINCT t1.value_1
|
||||
FROM
|
||||
reference_table_test t1 RIGHT JOIN reference_table_test_second t2 USING (value_1)
|
||||
RIGHT JOIN reference_table_test_third t3 USING (value_1)
|
||||
ORDER BY
|
||||
1;
|
||||
|
||||
\c - - - :master_port
|
||||
SET citus.shard_count TO 6;
|
||||
SET citus.shard_replication_factor TO 1;
|
||||
SET citus.replication_model TO streaming;
|
||||
|
||||
CREATE TABLE colocated_table_test (value_1 int, value_2 float, value_3 text, value_4 timestamp);
|
||||
SELECT create_distributed_table('colocated_table_test', 'value_1');
|
||||
|
||||
CREATE TABLE colocated_table_test_2 (value_1 int, value_2 float, value_3 text, value_4 timestamp);
|
||||
SELECT create_distributed_table('colocated_table_test_2', 'value_1');
|
||||
|
||||
DELETE FROM reference_table_test;
|
||||
INSERT INTO reference_table_test VALUES (1, 1.0, '1', '2016-12-01');
|
||||
INSERT INTO reference_table_test VALUES (2, 2.0, '2', '2016-12-02');
|
||||
|
||||
INSERT INTO colocated_table_test VALUES (1, 1.0, '1', '2016-12-01');
|
||||
INSERT INTO colocated_table_test VALUES (2, 2.0, '2', '2016-12-02');
|
||||
|
||||
INSERT INTO colocated_table_test_2 VALUES (1, 1.0, '1', '2016-12-01');
|
||||
INSERT INTO colocated_table_test_2 VALUES (2, 2.0, '2', '2016-12-02');
|
||||
|
||||
\c - - - :worker_1_port
|
||||
SET client_min_messages TO DEBUG1;
|
||||
SET citus.log_multi_join_order TO TRUE;
|
||||
|
||||
SELECT
|
||||
reference_table_test.value_1
|
||||
FROM
|
||||
reference_table_test, colocated_table_test
|
||||
WHERE
|
||||
colocated_table_test.value_1 = reference_table_test.value_1;
|
||||
|
||||
SELECT
|
||||
colocated_table_test.value_2
|
||||
FROM
|
||||
reference_table_test, colocated_table_test
|
||||
WHERE
|
||||
colocated_table_test.value_2 = reference_table_test.value_2;
|
||||
|
||||
SELECT
|
||||
colocated_table_test.value_2
|
||||
FROM
|
||||
colocated_table_test, reference_table_test
|
||||
WHERE
|
||||
reference_table_test.value_1 = colocated_table_test.value_1;
|
||||
|
||||
SELECT
|
||||
colocated_table_test.value_2
|
||||
FROM
|
||||
reference_table_test, colocated_table_test, colocated_table_test_2
|
||||
WHERE
|
||||
colocated_table_test.value_2 = reference_table_test.value_2;
|
||||
|
||||
SELECT
|
||||
colocated_table_test.value_2
|
||||
FROM
|
||||
reference_table_test, colocated_table_test, colocated_table_test_2
|
||||
WHERE
|
||||
colocated_table_test.value_1 = colocated_table_test_2.value_1 AND colocated_table_test.value_2 = reference_table_test.value_2;
|
||||
|
||||
SET citus.task_executor_type to "task-tracker";
|
||||
SELECT
|
||||
colocated_table_test.value_2
|
||||
FROM
|
||||
reference_table_test, colocated_table_test, colocated_table_test_2
|
||||
WHERE
|
||||
colocated_table_test.value_2 = colocated_table_test_2.value_2 AND colocated_table_test.value_2 = reference_table_test.value_2;
|
||||
|
||||
SELECT
|
||||
reference_table_test.value_2
|
||||
FROM
|
||||
reference_table_test, colocated_table_test, colocated_table_test_2
|
||||
WHERE
|
||||
colocated_table_test.value_1 = reference_table_test.value_1 AND colocated_table_test_2.value_1 = reference_table_test.value_1;
|
||||
|
||||
|
||||
SET client_min_messages TO NOTICE;
|
||||
SET citus.log_multi_join_order TO FALSE;
|
||||
|
||||
-- clean up tables
|
||||
\c - - - :master_port
|
||||
DROP TABLE reference_table_test, reference_table_test_second, reference_table_test_third;;
|
|
@ -0,0 +1,14 @@
|
|||
-- Test two concurrent reparttition joins from two different workers
|
||||
-- This test runs the below query from the :worker_1_port and the
|
||||
-- concurrent test runs the same query on :worker_2_port. Note that, both
|
||||
-- tests use the same sequence ids but the queries should not fail.
|
||||
\c - - - :worker_1_port
|
||||
|
||||
SET citus.task_executor_type TO "task-tracker";
|
||||
CREATE TEMP TABLE t1 AS
|
||||
SELECT
|
||||
l1.l_comment
|
||||
FROM
|
||||
lineitem_mx l1, orders_mx l2
|
||||
WHERE
|
||||
l1.l_comment = l2.o_comment;
|
|
@ -0,0 +1,14 @@
|
|||
-- Test two concurrent reparttition joins from two different workers
|
||||
-- This test runs the below query from the :worker_2_port and the
|
||||
-- concurrent test runs the same query on :worker_1_port. Note that, both
|
||||
-- tests use the same sequence ids but the queries should not fail.
|
||||
\c - - - :worker_2_port
|
||||
|
||||
SET citus.task_executor_type TO "task-tracker";
|
||||
CREATE TEMP TABLE t1 AS
|
||||
SELECT
|
||||
l1.l_comment
|
||||
FROM
|
||||
lineitem_mx l1, orders_mx l2
|
||||
WHERE
|
||||
l1.l_comment = l2.o_comment;
|
|
@ -0,0 +1,218 @@
|
|||
--
|
||||
-- MULTI_MX_REPARTITION_UDT_PREPARE
|
||||
--
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 535000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 535000;
|
||||
|
||||
-- START type creation
|
||||
|
||||
CREATE TYPE test_udt AS (i integer, i2 integer);
|
||||
|
||||
-- ... as well as a function to use as its comparator...
|
||||
CREATE FUNCTION equal_test_udt_function(test_udt, test_udt) RETURNS boolean
|
||||
AS 'select $1.i = $2.i AND $1.i2 = $2.i2;'
|
||||
LANGUAGE SQL
|
||||
IMMUTABLE
|
||||
RETURNS NULL ON NULL INPUT;
|
||||
|
||||
-- ... use that function to create a custom equality operator...
|
||||
CREATE OPERATOR = (
|
||||
LEFTARG = test_udt,
|
||||
RIGHTARG = test_udt,
|
||||
PROCEDURE = equal_test_udt_function,
|
||||
COMMUTATOR = =,
|
||||
HASHES
|
||||
);
|
||||
|
||||
-- ... and create a custom operator family for hash indexes...
|
||||
CREATE OPERATOR FAMILY tudt_op_fam USING hash;
|
||||
|
||||
-- ... create a test HASH function. Though it is a poor hash function,
|
||||
-- it is acceptable for our tests
|
||||
CREATE FUNCTION test_udt_hash(test_udt) RETURNS int
|
||||
AS 'SELECT hashtext( ($1.i + $1.i2)::text);'
|
||||
LANGUAGE SQL
|
||||
IMMUTABLE
|
||||
RETURNS NULL ON NULL INPUT;
|
||||
|
||||
|
||||
-- We need to define two different operator classes for the composite types
|
||||
-- One uses BTREE the other uses HASH
|
||||
CREATE OPERATOR CLASS tudt_op_fam_clas3
|
||||
DEFAULT FOR TYPE test_udt USING BTREE AS
|
||||
OPERATOR 3 = (test_udt, test_udt);
|
||||
|
||||
CREATE OPERATOR CLASS tudt_op_fam_class
|
||||
DEFAULT FOR TYPE test_udt USING HASH AS
|
||||
OPERATOR 1 = (test_udt, test_udt),
|
||||
FUNCTION 1 test_udt_hash(test_udt);
|
||||
|
||||
-- END type creation
|
||||
|
||||
CREATE TABLE repartition_udt (
|
||||
pk integer not null,
|
||||
udtcol test_udt,
|
||||
txtcol text
|
||||
);
|
||||
|
||||
CREATE TABLE repartition_udt_other (
|
||||
pk integer not null,
|
||||
udtcol test_udt,
|
||||
txtcol text
|
||||
);
|
||||
|
||||
-- Connect directly to a worker, create and drop the type, then
|
||||
-- proceed with type creation as above; thus the OIDs will be different.
|
||||
-- so that the OID is off.
|
||||
|
||||
\c - - - :worker_1_port
|
||||
|
||||
CREATE TYPE test_udt AS (i integer, i2 integer);
|
||||
DROP TYPE test_udt CASCADE;
|
||||
|
||||
-- START type creation
|
||||
|
||||
CREATE TYPE test_udt AS (i integer, i2 integer);
|
||||
|
||||
-- ... as well as a function to use as its comparator...
|
||||
CREATE FUNCTION equal_test_udt_function(test_udt, test_udt) RETURNS boolean
|
||||
AS 'select $1.i = $2.i AND $1.i2 = $2.i2;'
|
||||
LANGUAGE SQL
|
||||
IMMUTABLE
|
||||
RETURNS NULL ON NULL INPUT;
|
||||
|
||||
-- ... use that function to create a custom equality operator...
|
||||
CREATE OPERATOR = (
|
||||
LEFTARG = test_udt,
|
||||
RIGHTARG = test_udt,
|
||||
PROCEDURE = equal_test_udt_function,
|
||||
COMMUTATOR = =,
|
||||
HASHES
|
||||
);
|
||||
|
||||
-- ... and create a custom operator family for hash indexes...
|
||||
CREATE OPERATOR FAMILY tudt_op_fam USING hash;
|
||||
|
||||
-- ... create a test HASH function. Though it is a poor hash function,
|
||||
-- it is acceptable for our tests
|
||||
CREATE FUNCTION test_udt_hash(test_udt) RETURNS int
|
||||
AS 'SELECT hashtext( ($1.i + $1.i2)::text);'
|
||||
LANGUAGE SQL
|
||||
IMMUTABLE
|
||||
RETURNS NULL ON NULL INPUT;
|
||||
|
||||
|
||||
-- We need to define two different operator classes for the composite types
|
||||
-- One uses BTREE the other uses HASH
|
||||
CREATE OPERATOR CLASS tudt_op_fam_clas3
|
||||
DEFAULT FOR TYPE test_udt USING BTREE AS
|
||||
OPERATOR 3 = (test_udt, test_udt);
|
||||
|
||||
CREATE OPERATOR CLASS tudt_op_fam_class
|
||||
DEFAULT FOR TYPE test_udt USING HASH AS
|
||||
OPERATOR 1 = (test_udt, test_udt),
|
||||
FUNCTION 1 test_udt_hash(test_udt);
|
||||
|
||||
-- END type creation
|
||||
|
||||
\c - - - :worker_2_port
|
||||
|
||||
-- START type creation
|
||||
|
||||
CREATE TYPE test_udt AS (i integer, i2 integer);
|
||||
|
||||
-- ... as well as a function to use as its comparator...
|
||||
CREATE FUNCTION equal_test_udt_function(test_udt, test_udt) RETURNS boolean
|
||||
AS 'select $1.i = $2.i AND $1.i2 = $2.i2;'
|
||||
LANGUAGE SQL
|
||||
IMMUTABLE
|
||||
RETURNS NULL ON NULL INPUT;
|
||||
|
||||
-- ... use that function to create a custom equality operator...
|
||||
CREATE OPERATOR = (
|
||||
LEFTARG = test_udt,
|
||||
RIGHTARG = test_udt,
|
||||
PROCEDURE = equal_test_udt_function,
|
||||
COMMUTATOR = =,
|
||||
HASHES
|
||||
);
|
||||
|
||||
-- ... and create a custom operator family for hash indexes...
|
||||
CREATE OPERATOR FAMILY tudt_op_fam USING hash;
|
||||
|
||||
-- ... create a test HASH function. Though it is a poor hash function,
|
||||
-- it is acceptable for our tests
|
||||
CREATE FUNCTION test_udt_hash(test_udt) RETURNS int
|
||||
AS 'SELECT hashtext( ($1.i + $1.i2)::text);'
|
||||
LANGUAGE SQL
|
||||
IMMUTABLE
|
||||
RETURNS NULL ON NULL INPUT;
|
||||
|
||||
|
||||
-- We need to define two different operator classes for the composite types
|
||||
-- One uses BTREE the other uses HASH
|
||||
CREATE OPERATOR CLASS tudt_op_fam_clas3
|
||||
DEFAULT FOR TYPE test_udt USING BTREE AS
|
||||
OPERATOR 3 = (test_udt, test_udt);
|
||||
|
||||
CREATE OPERATOR CLASS tudt_op_fam_class
|
||||
DEFAULT FOR TYPE test_udt USING HASH AS
|
||||
OPERATOR 1 = (test_udt, test_udt),
|
||||
FUNCTION 1 test_udt_hash(test_udt);
|
||||
|
||||
-- END type creation
|
||||
|
||||
-- Connect to master
|
||||
|
||||
\c - - - :master_port
|
||||
|
||||
-- Distribute and populate the two tables.
|
||||
SET citus.shard_replication_factor TO 1;
|
||||
SET citus.replication_model TO streaming;
|
||||
|
||||
SET citus.shard_count TO 3;
|
||||
SELECT create_distributed_table('repartition_udt', 'pk');
|
||||
|
||||
SET citus.shard_count TO 5;
|
||||
SELECT create_distributed_table('repartition_udt_other', 'pk');
|
||||
|
||||
INSERT INTO repartition_udt values (1, '(1,1)'::test_udt, 'foo');
|
||||
INSERT INTO repartition_udt values (2, '(1,2)'::test_udt, 'foo');
|
||||
INSERT INTO repartition_udt values (3, '(1,3)'::test_udt, 'foo');
|
||||
INSERT INTO repartition_udt values (4, '(2,1)'::test_udt, 'foo');
|
||||
INSERT INTO repartition_udt values (5, '(2,2)'::test_udt, 'foo');
|
||||
INSERT INTO repartition_udt values (6, '(2,3)'::test_udt, 'foo');
|
||||
|
||||
INSERT INTO repartition_udt_other values (7, '(1,1)'::test_udt, 'foo');
|
||||
INSERT INTO repartition_udt_other values (8, '(1,2)'::test_udt, 'foo');
|
||||
INSERT INTO repartition_udt_other values (9, '(1,3)'::test_udt, 'foo');
|
||||
INSERT INTO repartition_udt_other values (10, '(2,1)'::test_udt, 'foo');
|
||||
INSERT INTO repartition_udt_other values (11, '(2,2)'::test_udt, 'foo');
|
||||
INSERT INTO repartition_udt_other values (12, '(2,3)'::test_udt, 'foo');
|
||||
|
||||
SET client_min_messages = LOG;
|
||||
|
||||
-- Query that should result in a repartition join on int column, and be empty.
|
||||
SELECT * FROM repartition_udt JOIN repartition_udt_other
|
||||
ON repartition_udt.pk = repartition_udt_other.pk
|
||||
WHERE repartition_udt.pk > 1;
|
||||
|
||||
-- Query that should result in a repartition join on UDT column.
|
||||
SET citus.large_table_shard_count = 1;
|
||||
SET citus.task_executor_type = 'task-tracker';
|
||||
SET citus.log_multi_join_order = true;
|
||||
|
||||
EXPLAIN SELECT * FROM repartition_udt JOIN repartition_udt_other
|
||||
ON repartition_udt.udtcol = repartition_udt_other.udtcol
|
||||
WHERE repartition_udt.pk > 1;
|
||||
|
||||
SELECT * FROM repartition_udt JOIN repartition_udt_other
|
||||
ON repartition_udt.udtcol = repartition_udt_other.udtcol
|
||||
WHERE repartition_udt.pk > 1
|
||||
ORDER BY repartition_udt.pk;
|
||||
|
||||
\c - - - :worker_1_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 535000;
|
||||
\c - - - :worker_2_port
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 535000;
|
|
@ -0,0 +1,20 @@
|
|||
--
|
||||
-- MULTI_MX_REPARTITION_W1_UDT
|
||||
--
|
||||
|
||||
\c - - - :worker_1_port
|
||||
SET client_min_messages = LOG;
|
||||
-- Query that should result in a repartition join on UDT column.
|
||||
SET citus.large_table_shard_count = 1;
|
||||
SET citus.task_executor_type = 'task-tracker';
|
||||
SET citus.log_multi_join_order = true;
|
||||
|
||||
-- Query that should result in a repartition join on int column, and be empty.
|
||||
SELECT * FROM repartition_udt JOIN repartition_udt_other
|
||||
ON repartition_udt.pk = repartition_udt_other.pk
|
||||
WHERE repartition_udt.pk > 1;
|
||||
|
||||
SELECT * FROM repartition_udt JOIN repartition_udt_other
|
||||
ON repartition_udt.udtcol = repartition_udt_other.udtcol
|
||||
WHERE repartition_udt.pk > 1
|
||||
ORDER BY repartition_udt.pk;
|
|
@ -0,0 +1,20 @@
|
|||
--
|
||||
-- MULTI_MX_REPARTITION_W2_UDT
|
||||
--
|
||||
|
||||
\c - - - :worker_2_port
|
||||
SET client_min_messages = LOG;
|
||||
-- Query that should result in a repartition join on UDT column.
|
||||
SET citus.large_table_shard_count = 1;
|
||||
SET citus.task_executor_type = 'task-tracker';
|
||||
SET citus.log_multi_join_order = true;
|
||||
|
||||
-- Query that should result in a repartition join on int column, and be empty.
|
||||
SELECT * FROM repartition_udt JOIN repartition_udt_other
|
||||
ON repartition_udt.pk = repartition_udt_other.pk
|
||||
WHERE repartition_udt.pk > 1;
|
||||
|
||||
SELECT * FROM repartition_udt JOIN repartition_udt_other
|
||||
ON repartition_udt.udtcol = repartition_udt_other.udtcol
|
||||
WHERE repartition_udt.pk > 1
|
||||
ORDER BY repartition_udt.pk;
|
|
@ -0,0 +1,658 @@
|
|||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 840000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 840000;
|
||||
|
||||
|
||||
-- ===================================================================
|
||||
-- test router planner functionality for single shard select queries
|
||||
-- ===================================================================
|
||||
|
||||
-- run all the router queries from the one of the workers
|
||||
|
||||
\c - - - :worker_1_port
|
||||
-- this table is used in a CTE test
|
||||
CREATE TABLE authors_hash_mx ( name text, id bigint );
|
||||
|
||||
-- create a bunch of test data
|
||||
INSERT INTO articles_hash_mx VALUES ( 1, 1, 'arsenous', 9572);
|
||||
INSERT INTO articles_hash_mx VALUES ( 2, 2, 'abducing', 13642);
|
||||
INSERT INTO articles_hash_mx VALUES ( 3, 3, 'asternal', 10480);
|
||||
INSERT INTO articles_hash_mx VALUES ( 4, 4, 'altdorfer', 14551);
|
||||
INSERT INTO articles_hash_mx VALUES ( 5, 5, 'aruru', 11389);
|
||||
INSERT INTO articles_hash_mx VALUES ( 6, 6, 'atlases', 15459);
|
||||
INSERT INTO articles_hash_mx VALUES ( 7, 7, 'aseptic', 12298);
|
||||
INSERT INTO articles_hash_mx VALUES ( 8, 8, 'agatized', 16368);
|
||||
INSERT INTO articles_hash_mx VALUES ( 9, 9, 'alligate', 438);
|
||||
INSERT INTO articles_hash_mx VALUES (10, 10, 'aggrandize', 17277);
|
||||
INSERT INTO articles_hash_mx VALUES (11, 1, 'alamo', 1347);
|
||||
INSERT INTO articles_hash_mx VALUES (12, 2, 'archiblast', 18185);
|
||||
INSERT INTO articles_hash_mx VALUES (13, 3, 'aseyev', 2255);
|
||||
INSERT INTO articles_hash_mx VALUES (14, 4, 'andesite', 19094);
|
||||
INSERT INTO articles_hash_mx VALUES (15, 5, 'adversa', 3164);
|
||||
INSERT INTO articles_hash_mx VALUES (16, 6, 'allonym', 2);
|
||||
INSERT INTO articles_hash_mx VALUES (17, 7, 'auriga', 4073);
|
||||
INSERT INTO articles_hash_mx VALUES (18, 8, 'assembly', 911);
|
||||
INSERT INTO articles_hash_mx VALUES (19, 9, 'aubergiste', 4981);
|
||||
INSERT INTO articles_hash_mx VALUES (20, 10, 'absentness', 1820);
|
||||
INSERT INTO articles_hash_mx VALUES (21, 1, 'arcading', 5890);
|
||||
INSERT INTO articles_hash_mx VALUES (22, 2, 'antipope', 2728);
|
||||
INSERT INTO articles_hash_mx VALUES (23, 3, 'abhorring', 6799);
|
||||
INSERT INTO articles_hash_mx VALUES (24, 4, 'audacious', 3637);
|
||||
INSERT INTO articles_hash_mx VALUES (25, 5, 'antehall', 7707);
|
||||
INSERT INTO articles_hash_mx VALUES (26, 6, 'abington', 4545);
|
||||
INSERT INTO articles_hash_mx VALUES (27, 7, 'arsenous', 8616);
|
||||
INSERT INTO articles_hash_mx VALUES (28, 8, 'aerophyte', 5454);
|
||||
INSERT INTO articles_hash_mx VALUES (29, 9, 'amateur', 9524);
|
||||
INSERT INTO articles_hash_mx VALUES (30, 10, 'andelee', 6363);
|
||||
INSERT INTO articles_hash_mx VALUES (31, 1, 'athwartships', 7271);
|
||||
INSERT INTO articles_hash_mx VALUES (32, 2, 'amazon', 11342);
|
||||
INSERT INTO articles_hash_mx VALUES (33, 3, 'autochrome', 8180);
|
||||
INSERT INTO articles_hash_mx VALUES (34, 4, 'amnestied', 12250);
|
||||
INSERT INTO articles_hash_mx VALUES (35, 5, 'aminate', 9089);
|
||||
INSERT INTO articles_hash_mx VALUES (36, 6, 'ablation', 13159);
|
||||
INSERT INTO articles_hash_mx VALUES (37, 7, 'archduchies', 9997);
|
||||
INSERT INTO articles_hash_mx VALUES (38, 8, 'anatine', 14067);
|
||||
INSERT INTO articles_hash_mx VALUES (39, 9, 'anchises', 10906);
|
||||
INSERT INTO articles_hash_mx VALUES (40, 10, 'attemper', 14976);
|
||||
INSERT INTO articles_hash_mx VALUES (41, 1, 'aznavour', 11814);
|
||||
INSERT INTO articles_hash_mx VALUES (42, 2, 'ausable', 15885);
|
||||
INSERT INTO articles_hash_mx VALUES (43, 3, 'affixal', 12723);
|
||||
INSERT INTO articles_hash_mx VALUES (44, 4, 'anteport', 16793);
|
||||
INSERT INTO articles_hash_mx VALUES (45, 5, 'afrasia', 864);
|
||||
INSERT INTO articles_hash_mx VALUES (46, 6, 'atlanta', 17702);
|
||||
INSERT INTO articles_hash_mx VALUES (47, 7, 'abeyance', 1772);
|
||||
INSERT INTO articles_hash_mx VALUES (48, 8, 'alkylic', 18610);
|
||||
INSERT INTO articles_hash_mx VALUES (49, 9, 'anyone', 2681);
|
||||
INSERT INTO articles_hash_mx VALUES (50, 10, 'anjanette', 19519);
|
||||
|
||||
|
||||
|
||||
SET citus.task_executor_type TO 'real-time';
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
SET client_min_messages TO 'DEBUG2';
|
||||
|
||||
-- insert a single row for the test
|
||||
INSERT INTO articles_single_shard_hash_mx VALUES (50, 10, 'anjanette', 19519);
|
||||
|
||||
-- single-shard tests
|
||||
|
||||
-- test simple select for a single row
|
||||
SELECT * FROM articles_hash_mx WHERE author_id = 10 AND id = 50;
|
||||
|
||||
-- get all titles by a single author
|
||||
SELECT title FROM articles_hash_mx WHERE author_id = 10;
|
||||
|
||||
-- try ordering them by word count
|
||||
SELECT title, word_count FROM articles_hash_mx
|
||||
WHERE author_id = 10
|
||||
ORDER BY word_count DESC NULLS LAST;
|
||||
|
||||
-- look at last two articles by an author
|
||||
SELECT title, id FROM articles_hash_mx
|
||||
WHERE author_id = 5
|
||||
ORDER BY id
|
||||
LIMIT 2;
|
||||
|
||||
-- find all articles by two authors in same shard
|
||||
-- but plan is not router executable due to order by
|
||||
SELECT title, author_id FROM articles_hash_mx
|
||||
WHERE author_id = 7 OR author_id = 8
|
||||
ORDER BY author_id ASC, id;
|
||||
|
||||
-- same query is router executable with no order by
|
||||
SELECT title, author_id FROM articles_hash_mx
|
||||
WHERE author_id = 7 OR author_id = 8;
|
||||
|
||||
-- add in some grouping expressions, still on same shard
|
||||
-- having queries unsupported in Citus
|
||||
SELECT author_id, sum(word_count) AS corpus_size FROM articles_hash_mx
|
||||
WHERE author_id = 1 OR author_id = 7 OR author_id = 8 OR author_id = 10
|
||||
GROUP BY author_id
|
||||
HAVING sum(word_count) > 1000
|
||||
ORDER BY sum(word_count) DESC;
|
||||
|
||||
-- however having clause is supported if it goes to a single shard
|
||||
SELECT author_id, sum(word_count) AS corpus_size FROM articles_hash_mx
|
||||
WHERE author_id = 1
|
||||
GROUP BY author_id
|
||||
HAVING sum(word_count) > 1000
|
||||
ORDER BY sum(word_count) DESC;
|
||||
|
||||
-- query is a single shard query but can't do shard pruning,
|
||||
-- not router-plannable due to <= and IN
|
||||
SELECT * FROM articles_hash_mx WHERE author_id <= 1;
|
||||
SELECT * FROM articles_hash_mx WHERE author_id IN (1, 3);
|
||||
|
||||
-- queries with CTEs are supported
|
||||
WITH first_author AS ( SELECT id FROM articles_hash_mx WHERE author_id = 1)
|
||||
SELECT * FROM first_author;
|
||||
|
||||
-- queries with CTEs are supported even if CTE is not referenced inside query
|
||||
WITH first_author AS ( SELECT id FROM articles_hash_mx WHERE author_id = 1)
|
||||
SELECT title FROM articles_hash_mx WHERE author_id = 1;
|
||||
|
||||
-- two CTE joins are supported if they go to the same worker
|
||||
WITH id_author AS ( SELECT id, author_id FROM articles_hash_mx WHERE author_id = 1),
|
||||
id_title AS (SELECT id, title from articles_hash_mx WHERE author_id = 1)
|
||||
SELECT * FROM id_author, id_title WHERE id_author.id = id_title.id;
|
||||
|
||||
WITH id_author AS ( SELECT id, author_id FROM articles_hash_mx WHERE author_id = 1),
|
||||
id_title AS (SELECT id, title from articles_hash_mx WHERE author_id = 3)
|
||||
SELECT * FROM id_author, id_title WHERE id_author.id = id_title.id;
|
||||
|
||||
-- CTE joins are not supported if table shards are at different workers
|
||||
WITH id_author AS ( SELECT id, author_id FROM articles_hash_mx WHERE author_id = 1),
|
||||
id_title AS (SELECT id, title from articles_hash_mx WHERE author_id = 2)
|
||||
SELECT * FROM id_author, id_title WHERE id_author.id = id_title.id;
|
||||
|
||||
-- recursive CTEs are supported when filtered on partition column
|
||||
|
||||
INSERT INTO company_employees_mx values(1, 1, 0);
|
||||
INSERT INTO company_employees_mx values(1, 2, 1);
|
||||
INSERT INTO company_employees_mx values(1, 3, 1);
|
||||
INSERT INTO company_employees_mx values(1, 4, 2);
|
||||
INSERT INTO company_employees_mx values(1, 5, 4);
|
||||
|
||||
INSERT INTO company_employees_mx values(3, 1, 0);
|
||||
INSERT INTO company_employees_mx values(3, 15, 1);
|
||||
INSERT INTO company_employees_mx values(3, 3, 1);
|
||||
|
||||
-- find employees at top 2 level within company hierarchy
|
||||
WITH RECURSIVE hierarchy as (
|
||||
SELECT *, 1 AS level
|
||||
FROM company_employees_mx
|
||||
WHERE company_id = 1 and manager_id = 0
|
||||
UNION
|
||||
SELECT ce.*, (h.level+1)
|
||||
FROM hierarchy h JOIN company_employees_mx ce
|
||||
ON (h.employee_id = ce.manager_id AND
|
||||
h.company_id = ce.company_id AND
|
||||
ce.company_id = 1))
|
||||
SELECT * FROM hierarchy WHERE LEVEL <= 2;
|
||||
|
||||
-- query becomes not router plannble and gets rejected
|
||||
-- if filter on company is dropped
|
||||
WITH RECURSIVE hierarchy as (
|
||||
SELECT *, 1 AS level
|
||||
FROM company_employees_mx
|
||||
WHERE company_id = 1 and manager_id = 0
|
||||
UNION
|
||||
SELECT ce.*, (h.level+1)
|
||||
FROM hierarchy h JOIN company_employees_mx ce
|
||||
ON (h.employee_id = ce.manager_id AND
|
||||
h.company_id = ce.company_id))
|
||||
SELECT * FROM hierarchy WHERE LEVEL <= 2;
|
||||
|
||||
-- logically wrong query, query involves different shards
|
||||
-- from the same table, but still router plannable due to
|
||||
-- shard being placed on the same worker.
|
||||
WITH RECURSIVE hierarchy as (
|
||||
SELECT *, 1 AS level
|
||||
FROM company_employees_mx
|
||||
WHERE company_id = 3 and manager_id = 0
|
||||
UNION
|
||||
SELECT ce.*, (h.level+1)
|
||||
FROM hierarchy h JOIN company_employees_mx ce
|
||||
ON (h.employee_id = ce.manager_id AND
|
||||
h.company_id = ce.company_id AND
|
||||
ce.company_id = 2))
|
||||
SELECT * FROM hierarchy WHERE LEVEL <= 2;
|
||||
|
||||
-- grouping sets are supported on single shard
|
||||
SELECT
|
||||
id, substring(title, 2, 1) AS subtitle, count(*)
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1 or author_id = 3
|
||||
GROUP BY GROUPING SETS ((id),(subtitle));
|
||||
|
||||
-- grouping sets are not supported on multiple shards
|
||||
SELECT
|
||||
id, substring(title, 2, 1) AS subtitle, count(*)
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1 or author_id = 2
|
||||
GROUP BY GROUPING SETS ((id),(subtitle));
|
||||
|
||||
-- queries which involve functions in FROM clause are supported if it goes to a single worker.
|
||||
SELECT * FROM articles_hash_mx, position('om' in 'Thomas') WHERE author_id = 1;
|
||||
|
||||
SELECT * FROM articles_hash_mx, position('om' in 'Thomas') WHERE author_id = 1 or author_id = 3;
|
||||
|
||||
-- they are not supported if multiple workers are involved
|
||||
SELECT * FROM articles_hash_mx, position('om' in 'Thomas') WHERE author_id = 1 or author_id = 2;
|
||||
|
||||
-- subqueries are not supported in WHERE clause in Citus
|
||||
SELECT * FROM articles_hash_mx WHERE author_id IN (SELECT id FROM authors_hash_mx WHERE name LIKE '%a');
|
||||
|
||||
SELECT * FROM articles_hash_mx WHERE author_id IN (SELECT author_id FROM articles_hash_mx WHERE author_id = 1 or author_id = 3);
|
||||
|
||||
SELECT * FROM articles_hash_mx WHERE author_id = (SELECT 1);
|
||||
|
||||
|
||||
-- subqueries are supported in FROM clause but they are not router plannable
|
||||
SELECT articles_hash_mx.id,test.word_count
|
||||
FROM articles_hash_mx, (SELECT id, word_count FROM articles_hash_mx) AS test WHERE test.id = articles_hash_mx.id
|
||||
ORDER BY articles_hash_mx.id;
|
||||
|
||||
|
||||
SELECT articles_hash_mx.id,test.word_count
|
||||
FROM articles_hash_mx, (SELECT id, word_count FROM articles_hash_mx) AS test
|
||||
WHERE test.id = articles_hash_mx.id and articles_hash_mx.author_id = 1
|
||||
ORDER BY articles_hash_mx.id;
|
||||
|
||||
-- subqueries are not supported in SELECT clause
|
||||
SELECT a.title AS name, (SELECT a2.id FROM articles_single_shard_hash_mx a2 WHERE a.id = a2.id LIMIT 1)
|
||||
AS special_price FROM articles_hash_mx a;
|
||||
|
||||
-- simple lookup query
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1;
|
||||
|
||||
-- below query hits a single shard, router plannable
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1 OR author_id = 17;
|
||||
|
||||
-- below query hits two shards, not router plannable + not router executable
|
||||
-- handled by real-time executor
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1 OR author_id = 18;
|
||||
|
||||
-- rename the output columns
|
||||
SELECT id as article_id, word_count * id as random_value
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1;
|
||||
|
||||
-- we can push down co-located joins to a single worker
|
||||
SELECT a.author_id as first_author, b.word_count as second_word_count
|
||||
FROM articles_hash_mx a, articles_hash_mx b
|
||||
WHERE a.author_id = 10 and a.author_id = b.author_id
|
||||
LIMIT 3;
|
||||
|
||||
-- following join is router plannable since the same worker
|
||||
-- has both shards
|
||||
SELECT a.author_id as first_author, b.word_count as second_word_count
|
||||
FROM articles_hash_mx a, articles_single_shard_hash_mx b
|
||||
WHERE a.author_id = 10 and a.author_id = b.author_id
|
||||
LIMIT 3;
|
||||
|
||||
-- following join is not router plannable since there are no
|
||||
-- workers containing both shards, added a CTE to make this fail
|
||||
-- at logical planner
|
||||
WITH single_shard as (SELECT * FROM articles_single_shard_hash_mx)
|
||||
SELECT a.author_id as first_author, b.word_count as second_word_count
|
||||
FROM articles_hash_mx a, single_shard b
|
||||
WHERE a.author_id = 2 and a.author_id = b.author_id
|
||||
LIMIT 3;
|
||||
|
||||
-- single shard select with limit is router plannable
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1
|
||||
LIMIT 3;
|
||||
|
||||
-- single shard select with limit + offset is router plannable
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1
|
||||
LIMIT 2
|
||||
OFFSET 1;
|
||||
|
||||
-- single shard select with limit + offset + order by is router plannable
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1
|
||||
ORDER BY id desc
|
||||
LIMIT 2
|
||||
OFFSET 1;
|
||||
|
||||
-- single shard select with group by on non-partition column is router plannable
|
||||
SELECT id
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1
|
||||
GROUP BY id
|
||||
ORDER BY id;
|
||||
|
||||
-- single shard select with distinct is router plannable
|
||||
SELECT distinct id
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1
|
||||
ORDER BY id;
|
||||
|
||||
-- single shard aggregate is router plannable
|
||||
SELECT avg(word_count)
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 2;
|
||||
|
||||
-- max, min, sum, count are router plannable on single shard
|
||||
SELECT max(word_count) as max, min(word_count) as min,
|
||||
sum(word_count) as sum, count(word_count) as cnt
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 2;
|
||||
|
||||
|
||||
-- queries with aggregates and group by supported on single shard
|
||||
SELECT max(word_count)
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1
|
||||
GROUP BY author_id;
|
||||
|
||||
|
||||
-- router plannable union queries are supported
|
||||
(SELECT * FROM articles_hash_mx WHERE author_id = 1)
|
||||
UNION
|
||||
(SELECT * FROM articles_hash_mx WHERE author_id = 3);
|
||||
|
||||
SELECT * FROM (
|
||||
(SELECT * FROM articles_hash_mx WHERE author_id = 1)
|
||||
UNION
|
||||
(SELECT * FROM articles_hash_mx WHERE author_id = 3)) uu;
|
||||
|
||||
(SELECT LEFT(title, 1) FROM articles_hash_mx WHERE author_id = 1)
|
||||
UNION
|
||||
(SELECT LEFT(title, 1) FROM articles_hash_mx WHERE author_id = 3);
|
||||
|
||||
(SELECT LEFT(title, 1) FROM articles_hash_mx WHERE author_id = 1)
|
||||
INTERSECT
|
||||
(SELECT LEFT(title, 1) FROM articles_hash_mx WHERE author_id = 3);
|
||||
|
||||
(SELECT LEFT(title, 2) FROM articles_hash_mx WHERE author_id = 1)
|
||||
EXCEPT
|
||||
(SELECT LEFT(title, 2) FROM articles_hash_mx WHERE author_id = 3);
|
||||
|
||||
-- union queries are not supported if not router plannable
|
||||
-- there is an inconsistency on shard pruning between
|
||||
-- ubuntu/mac disabling log messages for this queries only
|
||||
|
||||
SET client_min_messages to 'NOTICE';
|
||||
|
||||
(SELECT * FROM articles_hash_mx WHERE author_id = 1)
|
||||
UNION
|
||||
(SELECT * FROM articles_hash_mx WHERE author_id = 2);
|
||||
|
||||
|
||||
SELECT * FROM (
|
||||
(SELECT * FROM articles_hash_mx WHERE author_id = 1)
|
||||
UNION
|
||||
(SELECT * FROM articles_hash_mx WHERE author_id = 2)) uu;
|
||||
|
||||
-- error out for queries with repartition jobs
|
||||
SELECT *
|
||||
FROM articles_hash_mx a, articles_hash_mx b
|
||||
WHERE a.id = b.id AND a.author_id = 1;
|
||||
|
||||
-- queries which hit more than 1 shards are not router plannable or executable
|
||||
-- handled by real-time executor
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id >= 1 AND author_id <= 3;
|
||||
|
||||
SET citus.task_executor_type TO 'real-time';
|
||||
|
||||
-- Test various filtering options for router plannable check
|
||||
SET client_min_messages to 'DEBUG2';
|
||||
|
||||
-- this is definitely single shard
|
||||
-- and router plannable
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1 and author_id >= 1;
|
||||
|
||||
-- not router plannable due to or
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1 or id = 1;
|
||||
|
||||
-- router plannable
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1 and (id = 1 or id = 41);
|
||||
|
||||
-- router plannable
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1 and (id = random()::int * 0);
|
||||
|
||||
-- not router plannable due to function call on the right side
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = (random()::int * 0 + 1);
|
||||
|
||||
-- not router plannable due to or
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1 or id = 1;
|
||||
|
||||
-- router plannable due to abs(-1) getting converted to 1 by postgresql
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = abs(-1);
|
||||
|
||||
-- not router plannable due to abs() function
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE 1 = abs(author_id);
|
||||
|
||||
-- not router plannable due to abs() function
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = abs(author_id - 2);
|
||||
|
||||
-- router plannable, function on different field
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1 and (id = abs(id - 2));
|
||||
|
||||
-- not router plannable due to is true
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE (author_id = 1) is true;
|
||||
|
||||
-- router plannable, (boolean expression) = true is collapsed to (boolean expression)
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE (author_id = 1) = true;
|
||||
|
||||
-- router plannable, between operator is on another column
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE (author_id = 1) and id between 0 and 20;
|
||||
|
||||
-- router plannable, partition column expression is and'ed to rest
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE (author_id = 1) and (id = 1 or id = 31) and title like '%s';
|
||||
|
||||
-- router plannable, order is changed
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE (id = 1 or id = 31) and title like '%s' and (author_id = 1);
|
||||
|
||||
-- router plannable
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE (title like '%s' or title like 'a%') and (author_id = 1);
|
||||
|
||||
-- router plannable
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE (title like '%s' or title like 'a%') and (author_id = 1) and (word_count < 3000 or word_count > 8000);
|
||||
|
||||
-- window functions are supported if query is router plannable
|
||||
SELECT LAG(title, 1) over (ORDER BY word_count) prev, title, word_count
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 5;
|
||||
|
||||
SELECT LAG(title, 1) over (ORDER BY word_count) prev, title, word_count
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 5
|
||||
ORDER BY word_count DESC;
|
||||
|
||||
SELECT id, MIN(id) over (order by word_count)
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1;
|
||||
|
||||
SELECT id, word_count, AVG(word_count) over (order by word_count)
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1;
|
||||
|
||||
SELECT word_count, rank() OVER (PARTITION BY author_id ORDER BY word_count)
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1;
|
||||
|
||||
-- window functions are not supported for not router plannable queries
|
||||
SELECT id, MIN(id) over (order by word_count)
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1 or author_id = 2;
|
||||
|
||||
SELECT LAG(title, 1) over (ORDER BY word_count) prev, title, word_count
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 5 or author_id = 2;
|
||||
|
||||
-- complex query hitting a single shard
|
||||
SELECT
|
||||
count(DISTINCT CASE
|
||||
WHEN
|
||||
word_count > 100
|
||||
THEN
|
||||
id
|
||||
ELSE
|
||||
NULL
|
||||
END) as c
|
||||
FROM
|
||||
articles_hash_mx
|
||||
WHERE
|
||||
author_id = 5;
|
||||
|
||||
-- same query is not router plannable if hits multiple shards
|
||||
SELECT
|
||||
count(DISTINCT CASE
|
||||
WHEN
|
||||
word_count > 100
|
||||
THEN
|
||||
id
|
||||
ELSE
|
||||
NULL
|
||||
END) as c
|
||||
FROM
|
||||
articles_hash_mx
|
||||
GROUP BY
|
||||
author_id;
|
||||
|
||||
-- queries inside transactions can be router plannable
|
||||
BEGIN;
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1
|
||||
ORDER BY id;
|
||||
END;
|
||||
|
||||
-- cursor queries are router plannable
|
||||
BEGIN;
|
||||
DECLARE test_cursor CURSOR FOR
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1
|
||||
ORDER BY id;
|
||||
FETCH test_cursor;
|
||||
FETCH test_cursor;
|
||||
END;
|
||||
|
||||
-- queries inside copy can be router plannable
|
||||
COPY (
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1
|
||||
ORDER BY id) TO STDOUT;
|
||||
|
||||
-- table creation queries inside can be router plannable
|
||||
CREATE TEMP TABLE temp_articles_hash_mx as
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1
|
||||
ORDER BY id;
|
||||
|
||||
-- router plannable queries may include filter for aggragates
|
||||
SELECT count(*), count(*) FILTER (WHERE id < 3)
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1;
|
||||
|
||||
-- non-router plannable queries support filters as well
|
||||
SELECT count(*), count(*) FILTER (WHERE id < 3)
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1 or author_id = 2;
|
||||
|
||||
-- prepare queries can be router plannable
|
||||
PREPARE author_1_articles as
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1;
|
||||
|
||||
EXECUTE author_1_articles;
|
||||
|
||||
-- parametric prepare queries can be router plannable
|
||||
PREPARE author_articles(int) as
|
||||
SELECT *
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = $1;
|
||||
|
||||
EXECUTE author_articles(1);
|
||||
|
||||
-- queries inside plpgsql functions could be router plannable
|
||||
CREATE OR REPLACE FUNCTION author_articles_max_id() RETURNS int AS $$
|
||||
DECLARE
|
||||
max_id integer;
|
||||
BEGIN
|
||||
SELECT MAX(id) FROM articles_hash_mx ah
|
||||
WHERE author_id = 1
|
||||
into max_id;
|
||||
return max_id;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
SELECT author_articles_max_id();
|
||||
|
||||
-- plpgsql function that return query results are not router plannable
|
||||
CREATE OR REPLACE FUNCTION author_articles_id_word_count() RETURNS TABLE(id bigint, word_count int) AS $$
|
||||
DECLARE
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
SELECT ah.id, ah.word_count
|
||||
FROM articles_hash_mx ah
|
||||
WHERE author_id = 1;
|
||||
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
SELECT * FROM author_articles_id_word_count();
|
||||
|
||||
-- materialized views can be created for router plannable queries
|
||||
CREATE MATERIALIZED VIEW mv_articles_hash_mx AS
|
||||
SELECT * FROM articles_hash_mx WHERE author_id = 1;
|
||||
|
||||
SELECT * FROM mv_articles_hash_mx;
|
||||
|
||||
SET client_min_messages to 'INFO';
|
||||
DROP MATERIALIZED VIEW mv_articles_hash_mx;
|
||||
SET client_min_messages to 'DEBUG2';
|
||||
|
||||
CREATE MATERIALIZED VIEW mv_articles_hash_mx_error AS
|
||||
SELECT * FROM articles_hash_mx WHERE author_id in (1,2);
|
||||
|
||||
-- router planner/executor is disabled for task-tracker executor
|
||||
-- following query is router plannable, but router planner is disabled
|
||||
|
||||
-- TODO: Uncomment once we fix task-tracker issue
|
||||
--SET citus.task_executor_type to 'task-tracker';
|
||||
--SELECT id
|
||||
-- FROM articles_hash_mx
|
||||
-- WHERE author_id = 1;
|
||||
|
||||
-- insert query is router plannable even under task-tracker
|
||||
INSERT INTO articles_hash_mx VALUES (51, 1, 'amateus', 1814);
|
||||
|
||||
-- verify insert is successfull (not router plannable and executable)
|
||||
SELECT id
|
||||
FROM articles_hash_mx
|
||||
WHERE author_id = 1;
|
|
@ -0,0 +1,221 @@
|
|||
--
|
||||
-- MULTI_MX_SCHEMA_SUPPORT
|
||||
--
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1210000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1210000;
|
||||
|
||||
-- connect to a worker node and run some queries
|
||||
\c - - - :worker_1_port
|
||||
|
||||
-- test very basic queries
|
||||
SELECT * FROM nation_hash ORDER BY n_nationkey LIMIT 4;
|
||||
SELECT * FROM citus_mx_test_schema.nation_hash ORDER BY n_nationkey LIMIT 4;
|
||||
|
||||
|
||||
-- test cursors
|
||||
SET search_path TO public;
|
||||
BEGIN;
|
||||
DECLARE test_cursor CURSOR FOR
|
||||
SELECT *
|
||||
FROM nation_hash
|
||||
WHERE n_nationkey = 1;
|
||||
FETCH test_cursor;
|
||||
END;
|
||||
|
||||
-- test with search_path is set
|
||||
SET search_path TO citus_mx_test_schema;
|
||||
BEGIN;
|
||||
DECLARE test_cursor CURSOR FOR
|
||||
SELECT *
|
||||
FROM nation_hash
|
||||
WHERE n_nationkey = 1;
|
||||
FETCH test_cursor;
|
||||
END;
|
||||
|
||||
|
||||
-- test inserting to table in different schema
|
||||
SET search_path TO public;
|
||||
|
||||
INSERT INTO citus_mx_test_schema.nation_hash(n_nationkey, n_name, n_regionkey) VALUES (100, 'TURKEY', 3);
|
||||
|
||||
-- verify insertion
|
||||
SELECT * FROM citus_mx_test_schema.nation_hash WHERE n_nationkey = 100;
|
||||
|
||||
-- test with search_path is set
|
||||
SET search_path TO citus_mx_test_schema;
|
||||
|
||||
INSERT INTO nation_hash(n_nationkey, n_name, n_regionkey) VALUES (101, 'GERMANY', 3);
|
||||
|
||||
-- verify insertion
|
||||
SELECT * FROM nation_hash WHERE n_nationkey = 101;
|
||||
|
||||
-- TODO: add UPDATE/DELETE/UPSERT
|
||||
|
||||
|
||||
-- test UDFs with schemas
|
||||
SET search_path TO public;
|
||||
|
||||
|
||||
-- UDF in public, table in a schema other than public, search_path is not set
|
||||
SELECT simpleTestFunction(n_nationkey)::int FROM citus_mx_test_schema.nation_hash GROUP BY 1 ORDER BY 1 DESC LIMIT 5;
|
||||
|
||||
-- UDF in public, table in a schema other than public, search_path is set
|
||||
SET search_path TO citus_mx_test_schema;
|
||||
SELECT public.simpleTestFunction(n_nationkey)::int FROM citus_mx_test_schema.nation_hash GROUP BY 1 ORDER BY 1 DESC LIMIT 5;
|
||||
|
||||
|
||||
-- UDF in schema, table in a schema other than public, search_path is not set
|
||||
SET search_path TO public;
|
||||
SELECT citus_mx_test_schema.simpleTestFunction2(n_nationkey)::int FROM citus_mx_test_schema.nation_hash GROUP BY 1 ORDER BY 1 DESC LIMIT 5;
|
||||
|
||||
-- UDF in schema, table in a schema other than public, search_path is set
|
||||
SET search_path TO citus_mx_test_schema;
|
||||
SELECT simpleTestFunction2(n_nationkey)::int FROM nation_hash GROUP BY 1 ORDER BY 1 DESC LIMIT 5;
|
||||
|
||||
|
||||
-- test operators with schema
|
||||
SET search_path TO public;
|
||||
|
||||
-- test with search_path is not set
|
||||
SELECT * FROM citus_mx_test_schema.nation_hash WHERE n_nationkey OPERATOR(citus_mx_test_schema.===) 1;
|
||||
|
||||
-- test with search_path is set
|
||||
SET search_path TO citus_mx_test_schema;
|
||||
SELECT * FROM nation_hash WHERE n_nationkey OPERATOR(===) 1;
|
||||
|
||||
|
||||
SELECT * FROM citus_mx_test_schema.nation_hash_collation_search_path;
|
||||
SELECT n_comment FROM citus_mx_test_schema.nation_hash_collation_search_path ORDER BY n_comment COLLATE citus_mx_test_schema.english;
|
||||
|
||||
SET search_path TO citus_mx_test_schema;
|
||||
|
||||
SELECT * FROM nation_hash_collation_search_path ORDER BY 1 DESC;
|
||||
SELECT n_comment FROM nation_hash_collation_search_path ORDER BY n_comment COLLATE english;
|
||||
|
||||
|
||||
SELECT * FROM citus_mx_test_schema.nation_hash_composite_types WHERE test_col = '(a,a)'::citus_mx_test_schema.new_composite_type ORDER BY 1::int DESC;
|
||||
|
||||
--test with search_path is set
|
||||
SET search_path TO citus_mx_test_schema;
|
||||
SELECT * FROM nation_hash_composite_types WHERE test_col = '(a,a)'::new_composite_type ORDER BY 1::int DESC;
|
||||
|
||||
|
||||
-- check when search_path is public,
|
||||
-- join of two tables which are in different schemas,
|
||||
-- join on partition column
|
||||
SET search_path TO public;
|
||||
SELECT
|
||||
count (*)
|
||||
FROM
|
||||
citus_mx_test_schema_join_1.nation_hash n1, citus_mx_test_schema_join_2.nation_hash n2
|
||||
WHERE
|
||||
n1.n_nationkey = n2.n_nationkey;
|
||||
|
||||
-- check when search_path is different than public,
|
||||
-- join of two tables which are in different schemas,
|
||||
-- join on partition column
|
||||
SET search_path TO citus_mx_test_schema_join_1;
|
||||
SELECT
|
||||
count (*)
|
||||
FROM
|
||||
nation_hash n1, citus_mx_test_schema_join_2.nation_hash n2
|
||||
WHERE
|
||||
n1.n_nationkey = n2.n_nationkey;
|
||||
|
||||
-- check when search_path is public,
|
||||
-- join of two tables which are in same schemas,
|
||||
-- join on partition column
|
||||
SET search_path TO public;
|
||||
SELECT
|
||||
count (*)
|
||||
FROM
|
||||
citus_mx_test_schema_join_1.nation_hash n1, citus_mx_test_schema_join_1.nation_hash_2 n2
|
||||
WHERE
|
||||
n1.n_nationkey = n2.n_nationkey;
|
||||
|
||||
-- check when search_path is different than public,
|
||||
-- join of two tables which are in same schemas,
|
||||
-- join on partition column
|
||||
SET search_path TO citus_mx_test_schema_join_1;
|
||||
SELECT
|
||||
count (*)
|
||||
FROM
|
||||
nation_hash n1, nation_hash_2 n2
|
||||
WHERE
|
||||
n1.n_nationkey = n2.n_nationkey;
|
||||
|
||||
-- single repartition joins
|
||||
SET citus.task_executor_type TO "task-tracker";
|
||||
|
||||
-- check when search_path is public,
|
||||
-- join of two tables which are in different schemas,
|
||||
-- join on partition column and non-partition column
|
||||
--SET search_path TO public;
|
||||
SELECT
|
||||
count (*)
|
||||
FROM
|
||||
citus_mx_test_schema_join_1.nation_hash n1, citus_mx_test_schema_join_2.nation_hash n2
|
||||
WHERE
|
||||
n1.n_nationkey = n2.n_regionkey;
|
||||
|
||||
-- check when search_path is different than public,
|
||||
-- join of two tables which are in different schemas,
|
||||
-- join on partition column and non-partition column
|
||||
SET search_path TO citus_mx_test_schema_join_1;
|
||||
SELECT
|
||||
count (*)
|
||||
FROM
|
||||
nation_hash n1, citus_mx_test_schema_join_2.nation_hash n2
|
||||
WHERE
|
||||
n1.n_nationkey = n2.n_regionkey;
|
||||
|
||||
-- check when search_path is different than public,
|
||||
-- join of two tables which are in same schemas,
|
||||
-- join on partition column and non-partition column
|
||||
SET search_path TO citus_mx_test_schema_join_1;
|
||||
SELECT
|
||||
count (*)
|
||||
FROM
|
||||
nation_hash n1, nation_hash_2 n2
|
||||
WHERE
|
||||
n1.n_nationkey = n2.n_regionkey;
|
||||
|
||||
-- hash repartition joins
|
||||
|
||||
-- check when search_path is public,
|
||||
-- join of two tables which are in different schemas,
|
||||
-- join on non-partition column
|
||||
SET search_path TO public;
|
||||
SELECT
|
||||
count (*)
|
||||
FROM
|
||||
citus_mx_test_schema_join_1.nation_hash n1, citus_mx_test_schema_join_2.nation_hash n2
|
||||
WHERE
|
||||
n1.n_regionkey = n2.n_regionkey;
|
||||
|
||||
-- check when search_path is different than public,
|
||||
-- join of two tables which are in different schemas,
|
||||
-- join on non-partition column
|
||||
SET search_path TO citus_mx_test_schema_join_1;
|
||||
SELECT
|
||||
count (*)
|
||||
FROM
|
||||
nation_hash n1, citus_mx_test_schema_join_2.nation_hash n2
|
||||
WHERE
|
||||
n1.n_regionkey = n2.n_regionkey;
|
||||
|
||||
-- check when search_path is different than public,
|
||||
-- join of two tables which are in same schemas,
|
||||
-- join on non-partition column
|
||||
SET search_path TO citus_mx_test_schema_join_1;
|
||||
SELECT
|
||||
count (*)
|
||||
FROM
|
||||
nation_hash n1, nation_hash_2 n2
|
||||
WHERE
|
||||
n1.n_regionkey = n2.n_regionkey;
|
||||
|
||||
-- set task_executor back to real-time
|
||||
SET citus.task_executor_type TO "real-time";
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
--
|
||||
-- MULTI_MX_TPCH_QUERY1
|
||||
--
|
||||
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1310000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1310000;
|
||||
|
||||
-- connect to the schema node
|
||||
\c - - - :master_port
|
||||
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
|
||||
-- Query #1 from the TPC-H decision support benchmark
|
||||
|
||||
SELECT
|
||||
l_returnflag,
|
||||
l_linestatus,
|
||||
sum(l_quantity) as sum_qty,
|
||||
sum(l_extendedprice) as sum_base_price,
|
||||
sum(l_extendedprice * (1 - l_discount)) as sum_disc_price,
|
||||
sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge,
|
||||
avg(l_quantity) as avg_qty,
|
||||
avg(l_extendedprice) as avg_price,
|
||||
avg(l_discount) as avg_disc,
|
||||
count(*) as count_order
|
||||
FROM
|
||||
lineitem_mx
|
||||
WHERE
|
||||
l_shipdate <= date '1998-12-01' - interval '90 days'
|
||||
GROUP BY
|
||||
l_returnflag,
|
||||
l_linestatus
|
||||
ORDER BY
|
||||
l_returnflag,
|
||||
l_linestatus;
|
||||
|
||||
-- connect one of the workers
|
||||
\c - - - :worker_1_port
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1310000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1310000;
|
||||
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
|
||||
-- Query #1 from the TPC-H decision support benchmark
|
||||
|
||||
SELECT
|
||||
l_returnflag,
|
||||
l_linestatus,
|
||||
sum(l_quantity) as sum_qty,
|
||||
sum(l_extendedprice) as sum_base_price,
|
||||
sum(l_extendedprice * (1 - l_discount)) as sum_disc_price,
|
||||
sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge,
|
||||
avg(l_quantity) as avg_qty,
|
||||
avg(l_extendedprice) as avg_price,
|
||||
avg(l_discount) as avg_disc,
|
||||
count(*) as count_order
|
||||
FROM
|
||||
lineitem_mx
|
||||
WHERE
|
||||
l_shipdate <= date '1998-12-01' - interval '90 days'
|
||||
GROUP BY
|
||||
l_returnflag,
|
||||
l_linestatus
|
||||
ORDER BY
|
||||
l_returnflag,
|
||||
l_linestatus;
|
||||
|
||||
-- connect to the other node
|
||||
\c - - - :worker_2_port
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1310000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1310000;
|
||||
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
|
||||
-- Query #1 from the TPC-H decision support benchmark
|
||||
|
||||
SELECT
|
||||
l_returnflag,
|
||||
l_linestatus,
|
||||
sum(l_quantity) as sum_qty,
|
||||
sum(l_extendedprice) as sum_base_price,
|
||||
sum(l_extendedprice * (1 - l_discount)) as sum_disc_price,
|
||||
sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge,
|
||||
avg(l_quantity) as avg_qty,
|
||||
avg(l_extendedprice) as avg_price,
|
||||
avg(l_discount) as avg_disc,
|
||||
count(*) as count_order
|
||||
FROM
|
||||
lineitem_mx
|
||||
WHERE
|
||||
l_shipdate <= date '1998-12-01' - interval '90 days'
|
||||
GROUP BY
|
||||
l_returnflag,
|
||||
l_linestatus
|
||||
ORDER BY
|
||||
l_returnflag,
|
||||
l_linestatus;
|
|
@ -0,0 +1,126 @@
|
|||
--
|
||||
-- MULTI_MX_TPCH_QUERY10
|
||||
--
|
||||
|
||||
-- Query #10 from the TPC-H decision support benchmark. Unlike other TPC-H tests,
|
||||
-- we don't set citus.large_table_shard_count here, and instead use the default value
|
||||
-- coming from postgresql.conf or multi_task_tracker_executor.conf.
|
||||
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1300000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1300000;
|
||||
|
||||
-- connect to master
|
||||
\c - - - :master_port
|
||||
|
||||
SELECT
|
||||
c_custkey,
|
||||
c_name,
|
||||
sum(l_extendedprice * (1 - l_discount)) as revenue,
|
||||
c_acctbal,
|
||||
n_name,
|
||||
c_address,
|
||||
c_phone,
|
||||
c_comment
|
||||
FROM
|
||||
customer_mx,
|
||||
orders_mx,
|
||||
lineitem_mx,
|
||||
nation_mx
|
||||
WHERE
|
||||
c_custkey = o_custkey
|
||||
AND l_orderkey = o_orderkey
|
||||
AND o_orderdate >= date '1993-10-01'
|
||||
AND o_orderdate < date '1993-10-01' + interval '3' month
|
||||
AND l_returnflag = 'R'
|
||||
AND c_nationkey = n_nationkey
|
||||
GROUP BY
|
||||
c_custkey,
|
||||
c_name,
|
||||
c_acctbal,
|
||||
c_phone,
|
||||
n_name,
|
||||
c_address,
|
||||
c_comment
|
||||
ORDER BY
|
||||
revenue DESC
|
||||
LIMIT 20;
|
||||
|
||||
|
||||
-- connect one of the workers
|
||||
\c - - - :worker_1_port
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1300000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1300000;
|
||||
|
||||
SELECT
|
||||
c_custkey,
|
||||
c_name,
|
||||
sum(l_extendedprice * (1 - l_discount)) as revenue,
|
||||
c_acctbal,
|
||||
n_name,
|
||||
c_address,
|
||||
c_phone,
|
||||
c_comment
|
||||
FROM
|
||||
customer_mx,
|
||||
orders_mx,
|
||||
lineitem_mx,
|
||||
nation_mx
|
||||
WHERE
|
||||
c_custkey = o_custkey
|
||||
AND l_orderkey = o_orderkey
|
||||
AND o_orderdate >= date '1993-10-01'
|
||||
AND o_orderdate < date '1993-10-01' + interval '3' month
|
||||
AND l_returnflag = 'R'
|
||||
AND c_nationkey = n_nationkey
|
||||
GROUP BY
|
||||
c_custkey,
|
||||
c_name,
|
||||
c_acctbal,
|
||||
c_phone,
|
||||
n_name,
|
||||
c_address,
|
||||
c_comment
|
||||
ORDER BY
|
||||
revenue DESC
|
||||
LIMIT 20;
|
||||
|
||||
-- connect to the other worker
|
||||
\c - - - :worker_2_port
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1300000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1300000;
|
||||
|
||||
SELECT
|
||||
c_custkey,
|
||||
c_name,
|
||||
sum(l_extendedprice * (1 - l_discount)) as revenue,
|
||||
c_acctbal,
|
||||
n_name,
|
||||
c_address,
|
||||
c_phone,
|
||||
c_comment
|
||||
FROM
|
||||
customer_mx,
|
||||
orders_mx,
|
||||
lineitem_mx,
|
||||
nation_mx
|
||||
WHERE
|
||||
c_custkey = o_custkey
|
||||
AND l_orderkey = o_orderkey
|
||||
AND o_orderdate >= date '1993-10-01'
|
||||
AND o_orderdate < date '1993-10-01' + interval '3' month
|
||||
AND l_returnflag = 'R'
|
||||
AND c_nationkey = n_nationkey
|
||||
GROUP BY
|
||||
c_custkey,
|
||||
c_name,
|
||||
c_acctbal,
|
||||
c_phone,
|
||||
n_name,
|
||||
c_address,
|
||||
c_comment
|
||||
ORDER BY
|
||||
revenue DESC
|
||||
LIMIT 20;
|
|
@ -0,0 +1,127 @@
|
|||
--
|
||||
-- MULTI_MX_TPCH_QUERY12
|
||||
--
|
||||
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1290000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1290000;
|
||||
|
||||
-- connect to the schema node
|
||||
\c - - - :master_port
|
||||
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
|
||||
-- Query #12 from the TPC-H decision support benchmark
|
||||
|
||||
SELECT
|
||||
l_shipmode,
|
||||
sum(case
|
||||
when o_orderpriority = '1-URGENT'
|
||||
OR o_orderpriority = '2-HIGH'
|
||||
then 1
|
||||
else 0
|
||||
end) as high_line_count,
|
||||
sum(case
|
||||
when o_orderpriority <> '1-URGENT'
|
||||
AND o_orderpriority <> '2-HIGH'
|
||||
then 1
|
||||
else 0
|
||||
end) AS low_line_count
|
||||
FROM
|
||||
orders_mx,
|
||||
lineitem_mx
|
||||
WHERE
|
||||
o_orderkey = l_orderkey
|
||||
AND l_shipmode in ('MAIL', 'SHIP')
|
||||
AND l_commitdate < l_receiptdate
|
||||
AND l_shipdate < l_commitdate
|
||||
AND l_receiptdate >= date '1994-01-01'
|
||||
AND l_receiptdate < date '1994-01-01' + interval '1' year
|
||||
GROUP BY
|
||||
l_shipmode
|
||||
ORDER BY
|
||||
l_shipmode;
|
||||
|
||||
-- connect one of the workers
|
||||
\c - - - :worker_1_port
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1290000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1290000;
|
||||
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
|
||||
-- Query #12 from the TPC-H decision support benchmark
|
||||
|
||||
SELECT
|
||||
l_shipmode,
|
||||
sum(case
|
||||
when o_orderpriority = '1-URGENT'
|
||||
OR o_orderpriority = '2-HIGH'
|
||||
then 1
|
||||
else 0
|
||||
end) as high_line_count,
|
||||
sum(case
|
||||
when o_orderpriority <> '1-URGENT'
|
||||
AND o_orderpriority <> '2-HIGH'
|
||||
then 1
|
||||
else 0
|
||||
end) AS low_line_count
|
||||
FROM
|
||||
orders_mx,
|
||||
lineitem_mx
|
||||
WHERE
|
||||
o_orderkey = l_orderkey
|
||||
AND l_shipmode in ('MAIL', 'SHIP')
|
||||
AND l_commitdate < l_receiptdate
|
||||
AND l_shipdate < l_commitdate
|
||||
AND l_receiptdate >= date '1994-01-01'
|
||||
AND l_receiptdate < date '1994-01-01' + interval '1' year
|
||||
GROUP BY
|
||||
l_shipmode
|
||||
ORDER BY
|
||||
l_shipmode;
|
||||
|
||||
-- connect to the other worker node
|
||||
\c - - - :worker_2_port
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1290000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1290000;
|
||||
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
|
||||
-- Query #12 from the TPC-H decision support benchmark
|
||||
|
||||
SELECT
|
||||
l_shipmode,
|
||||
sum(case
|
||||
when o_orderpriority = '1-URGENT'
|
||||
OR o_orderpriority = '2-HIGH'
|
||||
then 1
|
||||
else 0
|
||||
end) as high_line_count,
|
||||
sum(case
|
||||
when o_orderpriority <> '1-URGENT'
|
||||
AND o_orderpriority <> '2-HIGH'
|
||||
then 1
|
||||
else 0
|
||||
end) AS low_line_count
|
||||
FROM
|
||||
orders_mx,
|
||||
lineitem_mx
|
||||
WHERE
|
||||
o_orderkey = l_orderkey
|
||||
AND l_shipmode in ('MAIL', 'SHIP')
|
||||
AND l_commitdate < l_receiptdate
|
||||
AND l_shipdate < l_commitdate
|
||||
AND l_receiptdate >= date '1994-01-01'
|
||||
AND l_receiptdate < date '1994-01-01' + interval '1' year
|
||||
GROUP BY
|
||||
l_shipmode
|
||||
ORDER BY
|
||||
l_shipmode;
|
|
@ -0,0 +1,82 @@
|
|||
--
|
||||
-- MULTI_MX_TPCH_QUERY14
|
||||
--
|
||||
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1280000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1280000;
|
||||
|
||||
-- connect to the schema node
|
||||
\c - - - :master_port
|
||||
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
|
||||
-- Query #14 from the TPC-H decision support benchmark
|
||||
|
||||
SELECT
|
||||
100.00 * sum(case
|
||||
when p_type like 'PROMO%'
|
||||
then l_extendedprice * (1 - l_discount)
|
||||
else 0
|
||||
end) / sum(l_extendedprice * (1 - l_discount)) as promo_revenue
|
||||
FROM
|
||||
lineitem_mx,
|
||||
part_mx
|
||||
WHERE
|
||||
l_partkey = p_partkey
|
||||
AND l_shipdate >= date '1995-09-01'
|
||||
AND l_shipdate < date '1995-09-01' + interval '1' year;
|
||||
|
||||
-- connect one of the workers
|
||||
\c - - - :worker_1_port
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1280000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1280000;
|
||||
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
|
||||
-- Query #14 from the TPC-H decision support benchmark
|
||||
|
||||
SELECT
|
||||
100.00 * sum(case
|
||||
when p_type like 'PROMO%'
|
||||
then l_extendedprice * (1 - l_discount)
|
||||
else 0
|
||||
end) / sum(l_extendedprice * (1 - l_discount)) as promo_revenue
|
||||
FROM
|
||||
lineitem_mx,
|
||||
part_mx
|
||||
WHERE
|
||||
l_partkey = p_partkey
|
||||
AND l_shipdate >= date '1995-09-01'
|
||||
AND l_shipdate < date '1995-09-01' + interval '1' year;
|
||||
|
||||
-- connect to the other node
|
||||
\c - - - :worker_2_port
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1280000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1280000;
|
||||
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
|
||||
-- Query #14 from the TPC-H decision support benchmark
|
||||
|
||||
SELECT
|
||||
100.00 * sum(case
|
||||
when p_type like 'PROMO%'
|
||||
then l_extendedprice * (1 - l_discount)
|
||||
else 0
|
||||
end) / sum(l_extendedprice * (1 - l_discount)) as promo_revenue
|
||||
FROM
|
||||
lineitem_mx,
|
||||
part_mx
|
||||
WHERE
|
||||
l_partkey = p_partkey
|
||||
AND l_shipdate >= date '1995-09-01'
|
||||
AND l_shipdate < date '1995-09-01' + interval '1' year;
|
|
@ -0,0 +1,133 @@
|
|||
--
|
||||
-- MULTI_MX_TPCH_QUERY19
|
||||
--
|
||||
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1270000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1270000;
|
||||
|
||||
-- connect to the schema node
|
||||
\c - - - :master_port
|
||||
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
|
||||
-- Query #19 from the TPC-H decision support benchmark. Note that we modified
|
||||
-- the query from its original to make it work on smaller data sets.
|
||||
|
||||
SELECT
|
||||
sum(l_extendedprice* (1 - l_discount)) as revenue
|
||||
FROM
|
||||
lineitem_mx,
|
||||
part_mx
|
||||
WHERE
|
||||
(
|
||||
p_partkey = l_partkey
|
||||
AND (p_brand = 'Brand#12' OR p_brand= 'Brand#14' OR p_brand='Brand#15')
|
||||
AND l_quantity >= 10
|
||||
AND l_shipmode in ('AIR', 'AIR REG', 'TRUCK')
|
||||
AND l_shipinstruct = 'DELIVER IN PERSON'
|
||||
)
|
||||
OR
|
||||
(
|
||||
p_partkey = l_partkey
|
||||
AND (p_brand = 'Brand#23' OR p_brand='Brand#24')
|
||||
AND l_quantity >= 20
|
||||
AND l_shipmode in ('AIR', 'AIR REG', 'TRUCK')
|
||||
AND l_shipinstruct = 'DELIVER IN PERSON'
|
||||
)
|
||||
OR
|
||||
(
|
||||
p_partkey = l_partkey
|
||||
AND (p_brand = 'Brand#33' OR p_brand = 'Brand#34' OR p_brand = 'Brand#35')
|
||||
AND l_quantity >= 1
|
||||
AND l_shipmode in ('AIR', 'AIR REG', 'TRUCK')
|
||||
AND l_shipinstruct = 'DELIVER IN PERSON'
|
||||
);
|
||||
|
||||
-- connect one of the workers
|
||||
\c - - - :worker_1_port
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1270000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1270000;
|
||||
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
|
||||
-- Query #19 from the TPC-H decision support benchmark. Note that we modified
|
||||
-- the query from its original to make it work on smaller data sets.
|
||||
|
||||
SELECT
|
||||
sum(l_extendedprice* (1 - l_discount)) as revenue
|
||||
FROM
|
||||
lineitem_mx,
|
||||
part_mx
|
||||
WHERE
|
||||
(
|
||||
p_partkey = l_partkey
|
||||
AND (p_brand = 'Brand#12' OR p_brand= 'Brand#14' OR p_brand='Brand#15')
|
||||
AND l_quantity >= 10
|
||||
AND l_shipmode in ('AIR', 'AIR REG', 'TRUCK')
|
||||
AND l_shipinstruct = 'DELIVER IN PERSON'
|
||||
)
|
||||
OR
|
||||
(
|
||||
p_partkey = l_partkey
|
||||
AND (p_brand = 'Brand#23' OR p_brand='Brand#24')
|
||||
AND l_quantity >= 20
|
||||
AND l_shipmode in ('AIR', 'AIR REG', 'TRUCK')
|
||||
AND l_shipinstruct = 'DELIVER IN PERSON'
|
||||
)
|
||||
OR
|
||||
(
|
||||
p_partkey = l_partkey
|
||||
AND (p_brand = 'Brand#33' OR p_brand = 'Brand#34' OR p_brand = 'Brand#35')
|
||||
AND l_quantity >= 1
|
||||
AND l_shipmode in ('AIR', 'AIR REG', 'TRUCK')
|
||||
AND l_shipinstruct = 'DELIVER IN PERSON'
|
||||
);
|
||||
|
||||
-- connect to the other node
|
||||
\c - - - :worker_2_port
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1270000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1270000;
|
||||
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
|
||||
-- Query #19 from the TPC-H decision support benchmark. Note that we modified
|
||||
-- the query from its original to make it work on smaller data sets.
|
||||
|
||||
SELECT
|
||||
sum(l_extendedprice* (1 - l_discount)) as revenue
|
||||
FROM
|
||||
lineitem_mx,
|
||||
part_mx
|
||||
WHERE
|
||||
(
|
||||
p_partkey = l_partkey
|
||||
AND (p_brand = 'Brand#12' OR p_brand= 'Brand#14' OR p_brand='Brand#15')
|
||||
AND l_quantity >= 10
|
||||
AND l_shipmode in ('AIR', 'AIR REG', 'TRUCK')
|
||||
AND l_shipinstruct = 'DELIVER IN PERSON'
|
||||
)
|
||||
OR
|
||||
(
|
||||
p_partkey = l_partkey
|
||||
AND (p_brand = 'Brand#23' OR p_brand='Brand#24')
|
||||
AND l_quantity >= 20
|
||||
AND l_shipmode in ('AIR', 'AIR REG', 'TRUCK')
|
||||
AND l_shipinstruct = 'DELIVER IN PERSON'
|
||||
)
|
||||
OR
|
||||
(
|
||||
p_partkey = l_partkey
|
||||
AND (p_brand = 'Brand#33' OR p_brand = 'Brand#34' OR p_brand = 'Brand#35')
|
||||
AND l_quantity >= 1
|
||||
AND l_shipmode in ('AIR', 'AIR REG', 'TRUCK')
|
||||
AND l_shipinstruct = 'DELIVER IN PERSON'
|
||||
);
|
|
@ -0,0 +1,95 @@
|
|||
--
|
||||
-- MULTI_MX_TPCH_QUERY3
|
||||
--
|
||||
|
||||
-- Query #3 from the TPC-H decision support benchmark. Unlike other TPC-H tests,
|
||||
-- we don't set citus.large_table_shard_count here, and instead use the default value
|
||||
-- coming from postgresql.conf or multi_task_tracker_executor.conf.
|
||||
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1260000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1260000;
|
||||
|
||||
-- connect to the schema node
|
||||
\c - - - :master_port
|
||||
|
||||
SELECT
|
||||
l_orderkey,
|
||||
sum(l_extendedprice * (1 - l_discount)) as revenue,
|
||||
o_orderdate,
|
||||
o_shippriority
|
||||
FROM
|
||||
customer_mx,
|
||||
orders_mx,
|
||||
lineitem_mx
|
||||
WHERE
|
||||
c_mktsegment = 'BUILDING'
|
||||
AND c_custkey = o_custkey
|
||||
AND l_orderkey = o_orderkey
|
||||
AND o_orderdate < date '1995-03-15'
|
||||
AND l_shipdate > date '1995-03-15'
|
||||
GROUP BY
|
||||
l_orderkey,
|
||||
o_orderdate,
|
||||
o_shippriority
|
||||
ORDER BY
|
||||
revenue DESC,
|
||||
o_orderdate;
|
||||
|
||||
-- connect one of the workers
|
||||
\c - - - :worker_1_port
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1260000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1260000;
|
||||
|
||||
SELECT
|
||||
l_orderkey,
|
||||
sum(l_extendedprice * (1 - l_discount)) as revenue,
|
||||
o_orderdate,
|
||||
o_shippriority
|
||||
FROM
|
||||
customer_mx,
|
||||
orders_mx,
|
||||
lineitem_mx
|
||||
WHERE
|
||||
c_mktsegment = 'BUILDING'
|
||||
AND c_custkey = o_custkey
|
||||
AND l_orderkey = o_orderkey
|
||||
AND o_orderdate < date '1995-03-15'
|
||||
AND l_shipdate > date '1995-03-15'
|
||||
GROUP BY
|
||||
l_orderkey,
|
||||
o_orderdate,
|
||||
o_shippriority
|
||||
ORDER BY
|
||||
revenue DESC,
|
||||
o_orderdate;
|
||||
|
||||
-- connect to the other node
|
||||
\c - - - :worker_2_port
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1260000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1260000;
|
||||
|
||||
SELECT
|
||||
l_orderkey,
|
||||
sum(l_extendedprice * (1 - l_discount)) as revenue,
|
||||
o_orderdate,
|
||||
o_shippriority
|
||||
FROM
|
||||
customer_mx,
|
||||
orders_mx,
|
||||
lineitem_mx
|
||||
WHERE
|
||||
c_mktsegment = 'BUILDING'
|
||||
AND c_custkey = o_custkey
|
||||
AND l_orderkey = o_orderkey
|
||||
AND o_orderdate < date '1995-03-15'
|
||||
AND l_shipdate > date '1995-03-15'
|
||||
GROUP BY
|
||||
l_orderkey,
|
||||
o_orderdate,
|
||||
o_shippriority
|
||||
ORDER BY
|
||||
revenue DESC,
|
||||
o_orderdate;
|
|
@ -0,0 +1,70 @@
|
|||
--
|
||||
-- MULTI_MX_TPCH_QUERY6
|
||||
--
|
||||
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1250000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1250000;
|
||||
|
||||
-- connect to the schema node
|
||||
\c - - - :master_port
|
||||
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
|
||||
-- Query #6 from the TPC-H decision support benchmark
|
||||
|
||||
SELECT
|
||||
sum(l_extendedprice * l_discount) as revenue
|
||||
FROM
|
||||
lineitem_mx
|
||||
WHERE
|
||||
l_shipdate >= date '1994-01-01'
|
||||
and l_shipdate < date '1994-01-01' + interval '1 year'
|
||||
and l_discount between 0.06 - 0.01 and 0.06 + 0.01
|
||||
and l_quantity < 24;
|
||||
|
||||
-- connect to one of the worker nodes
|
||||
\c - - - :worker_1_port
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1250000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1250000;
|
||||
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
|
||||
-- Query #6 from the TPC-H decision support benchmark
|
||||
|
||||
SELECT
|
||||
sum(l_extendedprice * l_discount) as revenue
|
||||
FROM
|
||||
lineitem_mx
|
||||
WHERE
|
||||
l_shipdate >= date '1994-01-01'
|
||||
and l_shipdate < date '1994-01-01' + interval '1 year'
|
||||
and l_discount between 0.06 - 0.01 and 0.06 + 0.01
|
||||
and l_quantity < 24;
|
||||
|
||||
-- connect to the other worker node
|
||||
\c - - - :worker_2_port
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1250000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1250000;
|
||||
|
||||
-- Change configuration to treat lineitem and orders tables as large
|
||||
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
|
||||
-- Query #6 from the TPC-H decision support benchmark
|
||||
|
||||
SELECT
|
||||
sum(l_extendedprice * l_discount) as revenue
|
||||
FROM
|
||||
lineitem_mx
|
||||
WHERE
|
||||
l_shipdate >= date '1994-01-01'
|
||||
and l_shipdate < date '1994-01-01' + interval '1 year'
|
||||
and l_discount between 0.06 - 0.01 and 0.06 + 0.01
|
||||
and l_quantity < 24;
|
|
@ -0,0 +1,160 @@
|
|||
--
|
||||
-- MULTI_MX_TPCH_QUERY7
|
||||
--
|
||||
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1230000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1230000;
|
||||
|
||||
-- connect to the schema node
|
||||
\c - - - :master_port
|
||||
|
||||
-- Change configuration to treat lineitem AND orders tables as large
|
||||
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
|
||||
-- Query #7 from the TPC-H decision support benchmark
|
||||
|
||||
SELECT
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year,
|
||||
sum(volume) as revenue
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
n1.n_name as supp_nation,
|
||||
n2.n_name as cust_nation,
|
||||
extract(year FROM l_shipdate) as l_year,
|
||||
l_extendedprice * (1 - l_discount) as volume
|
||||
FROM
|
||||
supplier_mx,
|
||||
lineitem_mx,
|
||||
orders_mx,
|
||||
customer_mx,
|
||||
nation_mx n1,
|
||||
nation_mx n2
|
||||
WHERE
|
||||
s_suppkey = l_suppkey
|
||||
AND o_orderkey = l_orderkey
|
||||
AND c_custkey = o_custkey
|
||||
AND s_nationkey = n1.n_nationkey
|
||||
AND c_nationkey = n2.n_nationkey
|
||||
AND (
|
||||
(n1.n_name = 'FRANCE' AND n2.n_name = 'GERMANY')
|
||||
OR (n1.n_name = 'GERMANY' AND n2.n_name = 'FRANCE')
|
||||
)
|
||||
AND l_shipdate between date '1995-01-01' AND date '1996-12-31'
|
||||
) as shipping
|
||||
GROUP BY
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year
|
||||
ORDER BY
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year;
|
||||
|
||||
-- connect one of the workers
|
||||
\c - - - :worker_1_port
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1230000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1230000;
|
||||
|
||||
-- Change configuration to treat lineitem AND orders tables as large
|
||||
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
|
||||
-- Query #7 from the TPC-H decision support benchmark
|
||||
|
||||
SELECT
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year,
|
||||
sum(volume) as revenue
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
n1.n_name as supp_nation,
|
||||
n2.n_name as cust_nation,
|
||||
extract(year FROM l_shipdate) as l_year,
|
||||
l_extendedprice * (1 - l_discount) as volume
|
||||
FROM
|
||||
supplier_mx,
|
||||
lineitem_mx,
|
||||
orders_mx,
|
||||
customer_mx,
|
||||
nation_mx n1,
|
||||
nation_mx n2
|
||||
WHERE
|
||||
s_suppkey = l_suppkey
|
||||
AND o_orderkey = l_orderkey
|
||||
AND c_custkey = o_custkey
|
||||
AND s_nationkey = n1.n_nationkey
|
||||
AND c_nationkey = n2.n_nationkey
|
||||
AND (
|
||||
(n1.n_name = 'FRANCE' AND n2.n_name = 'GERMANY')
|
||||
OR (n1.n_name = 'GERMANY' AND n2.n_name = 'FRANCE')
|
||||
)
|
||||
AND l_shipdate between date '1995-01-01' AND date '1996-12-31'
|
||||
) as shipping
|
||||
GROUP BY
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year
|
||||
ORDER BY
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year;
|
||||
|
||||
-- connect to the other worker node
|
||||
\c - - - :worker_2_port
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1230000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1230000;
|
||||
|
||||
-- Change configuration to treat lineitem AND orders tables as large
|
||||
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
|
||||
-- Query #7 from the TPC-H decision support benchmark
|
||||
|
||||
SELECT
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year,
|
||||
sum(volume) as revenue
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
n1.n_name as supp_nation,
|
||||
n2.n_name as cust_nation,
|
||||
extract(year FROM l_shipdate) as l_year,
|
||||
l_extendedprice * (1 - l_discount) as volume
|
||||
FROM
|
||||
supplier_mx,
|
||||
lineitem_mx,
|
||||
orders_mx,
|
||||
customer_mx,
|
||||
nation_mx n1,
|
||||
nation_mx n2
|
||||
WHERE
|
||||
s_suppkey = l_suppkey
|
||||
AND o_orderkey = l_orderkey
|
||||
AND c_custkey = o_custkey
|
||||
AND s_nationkey = n1.n_nationkey
|
||||
AND c_nationkey = n2.n_nationkey
|
||||
AND (
|
||||
(n1.n_name = 'FRANCE' AND n2.n_name = 'GERMANY')
|
||||
OR (n1.n_name = 'GERMANY' AND n2.n_name = 'FRANCE')
|
||||
)
|
||||
AND l_shipdate between date '1995-01-01' AND date '1996-12-31'
|
||||
) as shipping
|
||||
GROUP BY
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year
|
||||
ORDER BY
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year;
|
|
@ -0,0 +1,187 @@
|
|||
--
|
||||
-- MULTI_MX_TPCH_QUERY7_NESTED
|
||||
--
|
||||
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1240000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1240000;
|
||||
|
||||
-- connect to the schema node
|
||||
\c - - - :master_port
|
||||
|
||||
-- Change configuration to treat lineitem AND orders tables AS large
|
||||
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
|
||||
-- Query #7 from the TPC-H benchmark; modified to include sub-selects
|
||||
|
||||
SELECT
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year,
|
||||
sum(volume) AS revenue
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
extract(year FROM l_shipdate) AS l_year,
|
||||
l_extendedprice * (1 - l_discount) AS volume
|
||||
FROM
|
||||
supplier_mx,
|
||||
lineitem_mx,
|
||||
orders_mx,
|
||||
customer_mx,
|
||||
(
|
||||
SELECT
|
||||
n1.n_nationkey AS supp_nation_key,
|
||||
n2.n_nationkey AS cust_nation_key,
|
||||
n1.n_name AS supp_nation,
|
||||
n2.n_name AS cust_nation
|
||||
FROM
|
||||
nation_mx n1,
|
||||
nation_mx n2
|
||||
WHERE
|
||||
(
|
||||
(n1.n_name = 'FRANCE' AND n2.n_name = 'GERMANY')
|
||||
OR (n1.n_name = 'GERMANY' AND n2.n_name = 'FRANCE')
|
||||
)
|
||||
) AS temp
|
||||
WHERE
|
||||
s_suppkey = l_suppkey
|
||||
AND o_orderkey = l_orderkey
|
||||
AND c_custkey = o_custkey
|
||||
AND s_nationkey = supp_nation_key
|
||||
AND c_nationkey = cust_nation_key
|
||||
AND l_shipdate between date '1995-01-01' AND date '1996-12-31'
|
||||
) AS shipping
|
||||
GROUP BY
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year
|
||||
ORDER BY
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year;
|
||||
|
||||
-- connect to one of the workers
|
||||
\c - - - :worker_1_port
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1240000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1240000;
|
||||
|
||||
-- Change configuration to treat lineitem AND orders tables AS large
|
||||
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
|
||||
-- Query #7 from the TPC-H benchmark; modified to include sub-selects
|
||||
|
||||
SELECT
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year,
|
||||
sum(volume) AS revenue
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
extract(year FROM l_shipdate) AS l_year,
|
||||
l_extendedprice * (1 - l_discount) AS volume
|
||||
FROM
|
||||
supplier_mx,
|
||||
lineitem_mx,
|
||||
orders_mx,
|
||||
customer_mx,
|
||||
(
|
||||
SELECT
|
||||
n1.n_nationkey AS supp_nation_key,
|
||||
n2.n_nationkey AS cust_nation_key,
|
||||
n1.n_name AS supp_nation,
|
||||
n2.n_name AS cust_nation
|
||||
FROM
|
||||
nation_mx n1,
|
||||
nation_mx n2
|
||||
WHERE
|
||||
(
|
||||
(n1.n_name = 'FRANCE' AND n2.n_name = 'GERMANY')
|
||||
OR (n1.n_name = 'GERMANY' AND n2.n_name = 'FRANCE')
|
||||
)
|
||||
) AS temp
|
||||
WHERE
|
||||
s_suppkey = l_suppkey
|
||||
AND o_orderkey = l_orderkey
|
||||
AND c_custkey = o_custkey
|
||||
AND s_nationkey = supp_nation_key
|
||||
AND c_nationkey = cust_nation_key
|
||||
AND l_shipdate between date '1995-01-01' AND date '1996-12-31'
|
||||
) AS shipping
|
||||
GROUP BY
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year
|
||||
ORDER BY
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year;
|
||||
|
||||
-- connect to the schema node
|
||||
\c - - - :worker_2_port
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1240000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1240000;
|
||||
|
||||
-- Change configuration to treat lineitem AND orders tables AS large
|
||||
|
||||
SET citus.large_table_shard_count TO 2;
|
||||
|
||||
-- Query #7 from the TPC-H benchmark; modified to include sub-selects
|
||||
|
||||
SELECT
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year,
|
||||
sum(volume) AS revenue
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
extract(year FROM l_shipdate) AS l_year,
|
||||
l_extendedprice * (1 - l_discount) AS volume
|
||||
FROM
|
||||
supplier_mx,
|
||||
lineitem_mx,
|
||||
orders_mx,
|
||||
customer_mx,
|
||||
(
|
||||
SELECT
|
||||
n1.n_nationkey AS supp_nation_key,
|
||||
n2.n_nationkey AS cust_nation_key,
|
||||
n1.n_name AS supp_nation,
|
||||
n2.n_name AS cust_nation
|
||||
FROM
|
||||
nation_mx n1,
|
||||
nation_mx n2
|
||||
WHERE
|
||||
(
|
||||
(n1.n_name = 'FRANCE' AND n2.n_name = 'GERMANY')
|
||||
OR (n1.n_name = 'GERMANY' AND n2.n_name = 'FRANCE')
|
||||
)
|
||||
) AS temp
|
||||
WHERE
|
||||
s_suppkey = l_suppkey
|
||||
AND o_orderkey = l_orderkey
|
||||
AND c_custkey = o_custkey
|
||||
AND s_nationkey = supp_nation_key
|
||||
AND c_nationkey = cust_nation_key
|
||||
AND l_shipdate between date '1995-01-01' AND date '1996-12-31'
|
||||
) AS shipping
|
||||
GROUP BY
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year
|
||||
ORDER BY
|
||||
supp_nation,
|
||||
cust_nation,
|
||||
l_year;
|
Loading…
Reference in New Issue