--
-- multi behavioral analytics
-- this file is intended to create the table requires for the tests
--
SET citus.next_shard_id TO 1400000;
SET citus.shard_replication_factor = 1;
SET citus.shard_count = 32;
CREATE SCHEMA with_basics;
SET search_path TO 'with_basics';
CREATE TABLE users_table (user_id int, time timestamp, value_1 int, value_2 int, value_3 float, value_4 bigint);
SELECT create_distributed_table('users_table', 'user_id');
 create_distributed_table 
--------------------------
 
(1 row)

CREATE TABLE events_table (user_id int, time timestamp, event_type int, value_2 int, value_3 float, value_4 bigint);
SELECT create_distributed_table('events_table', 'user_id');
 create_distributed_table 
--------------------------
 
(1 row)

COPY users_table FROM '@abs_srcdir@/data/users_table.data' WITH CSV;
COPY events_table FROM '@abs_srcdir@/data/events_table.data' WITH CSV;
SET citus.shard_count = 96;
CREATE SCHEMA subquery_and_ctes;
SET search_path TO subquery_and_ctes;
CREATE TABLE users_table (user_id int, time timestamp, value_1 int, value_2 int, value_3 float, value_4 bigint);
SELECT create_distributed_table('users_table', 'user_id');
 create_distributed_table 
--------------------------
 
(1 row)

CREATE TABLE events_table (user_id int, time timestamp, event_type int, value_2 int, value_3 float, value_4 bigint);
SELECT create_distributed_table('events_table', 'user_id');
 create_distributed_table 
--------------------------
 
(1 row)

COPY users_table FROM '@abs_srcdir@/data/users_table.data' WITH CSV;
COPY events_table FROM '@abs_srcdir@/data/events_table.data' WITH CSV;
SET citus.shard_count TO DEFAULT;
SET search_path TO DEFAULT;
CREATE TABLE users_table (user_id int, time timestamp, value_1 int, value_2 int, value_3 float, value_4 bigint);
SELECT create_distributed_table('users_table', 'user_id');
 create_distributed_table 
--------------------------
 
(1 row)

CREATE TABLE events_table (user_id int, time timestamp, event_type int, value_2 int, value_3 float, value_4 bigint);
SELECT create_distributed_table('events_table', 'user_id');
 create_distributed_table 
--------------------------
 
(1 row)

CREATE TABLE agg_results (user_id int, value_1_agg int, value_2_agg int, value_3_agg float, value_4_agg bigint, agg_time timestamp);
SELECT create_distributed_table('agg_results', 'user_id');
 create_distributed_table 
--------------------------
 
(1 row)

-- we need this to improve the concurrency on the regression tests
CREATE TABLE agg_results_second (user_id int, value_1_agg int, value_2_agg int, value_3_agg float, value_4_agg bigint, agg_time timestamp);
SELECT create_distributed_table('agg_results_second', 'user_id');
 create_distributed_table 
--------------------------
 
(1 row)

-- same as agg_results_second
CREATE TABLE agg_results_third (user_id int, value_1_agg int, value_2_agg int, value_3_agg float, value_4_agg bigint, agg_time timestamp);
SELECT create_distributed_table('agg_results_third', 'user_id');
 create_distributed_table 
--------------------------
 
(1 row)

-- same as agg_results_second
CREATE TABLE agg_results_fourth (user_id int, value_1_agg int, value_2_agg int, value_3_agg float, value_4_agg bigint, agg_time timestamp);
SELECT create_distributed_table('agg_results_fourth', 'user_id');
 create_distributed_table 
--------------------------
 
(1 row)

-- same as agg_results_second
CREATE TABLE agg_results_window (user_id int, value_1_agg int, value_2_agg int, value_3_agg float, value_4_agg bigint, agg_time timestamp);
SELECT create_distributed_table('agg_results_window', 'user_id');
 create_distributed_table 
--------------------------
 
(1 row)

CREATE TABLE users_ref_test_table(id int, it_name varchar(25), k_no int);
SELECT create_reference_table('users_ref_test_table');
 create_reference_table 
------------------------
 
(1 row)

INSERT INTO users_ref_test_table VALUES(1,'User_1',45);
INSERT INTO users_ref_test_table VALUES(2,'User_2',46);
INSERT INTO users_ref_test_table VALUES(3,'User_3',47);
INSERT INTO users_ref_test_table VALUES(4,'User_4',48);
INSERT INTO users_ref_test_table VALUES(5,'User_5',49);
INSERT INTO users_ref_test_table VALUES(6,'User_6',50);
COPY users_table FROM '@abs_srcdir@/data/users_table.data' WITH CSV;
COPY events_table FROM '@abs_srcdir@/data/events_table.data' WITH CSV;
-- create indexes for
CREATE INDEX is_index1 ON users_table(user_id);
CREATE INDEX is_index2 ON events_table(user_id);
CREATE INDEX is_index3 ON users_table(value_1);
CREATE INDEX is_index4 ON events_table(event_type);
CREATE INDEX is_index5 ON users_table(value_2);
CREATE INDEX is_index6 ON events_table(value_2);
-- Create composite type to use in subquery pushdown
CREATE TYPE user_composite_type AS
(
    tenant_id BIGINT,
    user_id BIGINT
);
SELECT run_command_on_master_and_workers($f$

	CREATE FUNCTION cmp_user_composite_type_function(user_composite_type, user_composite_type) RETURNS int
	LANGUAGE 'internal'
	AS 'btrecordcmp'
	IMMUTABLE
	RETURNS NULL ON NULL INPUT;
$f$);
 run_command_on_master_and_workers 
-----------------------------------
 
(1 row)

SELECT run_command_on_master_and_workers($f$

	CREATE FUNCTION gt_user_composite_type_function(user_composite_type, user_composite_type) RETURNS boolean
	LANGUAGE 'internal'
	AS 'record_gt'
	IMMUTABLE
	RETURNS NULL ON NULL INPUT;
$f$);
 run_command_on_master_and_workers 
-----------------------------------
 
(1 row)

SELECT run_command_on_master_and_workers($f$

	CREATE FUNCTION ge_user_composite_type_function(user_composite_type, user_composite_type) RETURNS boolean
	LANGUAGE 'internal'
	AS 'record_ge'
	IMMUTABLE
	RETURNS NULL ON NULL INPUT;
$f$);
 run_command_on_master_and_workers 
-----------------------------------
 
(1 row)

SELECT run_command_on_master_and_workers($f$

	CREATE FUNCTION equal_user_composite_type_function(user_composite_type, user_composite_type) RETURNS boolean
	LANGUAGE 'internal'
	AS 'record_eq'
	IMMUTABLE;
$f$);
 run_command_on_master_and_workers 
-----------------------------------
 
(1 row)

SELECT run_command_on_master_and_workers($f$

	CREATE FUNCTION lt_user_composite_type_function(user_composite_type, user_composite_type) RETURNS boolean
	LANGUAGE 'internal'
	AS 'record_lt'
	IMMUTABLE
	RETURNS NULL ON NULL INPUT;
$f$);
 run_command_on_master_and_workers 
-----------------------------------
 
(1 row)

SELECT run_command_on_master_and_workers($f$

	CREATE FUNCTION le_user_composite_type_function(user_composite_type, user_composite_type) RETURNS boolean
	LANGUAGE 'internal'
	AS 'record_lt'
	IMMUTABLE
	RETURNS NULL ON NULL INPUT;
$f$);
 run_command_on_master_and_workers 
-----------------------------------
 
(1 row)

SELECT run_command_on_master_and_workers($f$

	CREATE OPERATOR > (
	    LEFTARG = user_composite_type,
	    RIGHTARG = user_composite_type,
	    PROCEDURE = gt_user_composite_type_function
	);
$f$);
 run_command_on_master_and_workers 
-----------------------------------
 
(1 row)

SELECT run_command_on_master_and_workers($f$

	CREATE OPERATOR >= (
	    LEFTARG = user_composite_type,
	    RIGHTARG = user_composite_type,
	    PROCEDURE = ge_user_composite_type_function
	);
$f$);
 run_command_on_master_and_workers 
-----------------------------------
 
(1 row)

-- ... use that function to create a custom equality operator...
SELECT run_command_on_master_and_workers($f$

	-- ... use that function to create a custom equality operator...
	CREATE OPERATOR = (
	    LEFTARG = user_composite_type,
	    RIGHTARG = user_composite_type,
	    PROCEDURE = equal_user_composite_type_function,
		commutator = =,
		RESTRICT = eqsel,
		JOIN = eqjoinsel,
		merges,
		hashes
	);
$f$);
 run_command_on_master_and_workers 
-----------------------------------
 
(1 row)

SELECT run_command_on_master_and_workers($f$

	CREATE OPERATOR <= (
	    LEFTARG = user_composite_type,
	    RIGHTARG = user_composite_type,
	    PROCEDURE = le_user_composite_type_function
	);
$f$);
 run_command_on_master_and_workers 
-----------------------------------
 
(1 row)

SELECT run_command_on_master_and_workers($f$

	CREATE OPERATOR < (
	    LEFTARG = user_composite_type,
	    RIGHTARG = user_composite_type,
	    PROCEDURE = lt_user_composite_type_function
	);
$f$);
 run_command_on_master_and_workers 
-----------------------------------
 
(1 row)

-- ... and create a custom operator family for hash indexes...
SELECT run_command_on_master_and_workers($f$

	CREATE OPERATOR FAMILY cats_2_op_fam USING hash;
$f$);
 run_command_on_master_and_workers 
-----------------------------------
 
(1 row)

-- ... create a test HASH function. Though it is a poor hash function,
-- it is acceptable for our tests
SELECT run_command_on_master_and_workers($f$

	CREATE FUNCTION test_composite_type_hash(user_composite_type) RETURNS int
	AS 'SELECT hashtext( ($1.tenant_id + $1.tenant_id)::text);'
	LANGUAGE SQL
	IMMUTABLE
	RETURNS NULL ON NULL INPUT;
$f$);
 run_command_on_master_and_workers 
-----------------------------------
 
(1 row)

-- We need to define two different operator classes for the composite types
-- One uses BTREE the other uses HASH
SELECT run_command_on_master_and_workers($f$

	CREATE OPERATOR CLASS cats_2_op_fam_clas3
	DEFAULT FOR TYPE user_composite_type USING BTREE AS
	OPERATOR 1 <=  (user_composite_type, user_composite_type),
	OPERATOR 2 <  (user_composite_type, user_composite_type),
	OPERATOR 3 = (user_composite_type, user_composite_type),
	OPERATOR 4 >= (user_composite_type, user_composite_type),
	OPERATOR 5 > (user_composite_type, user_composite_type),

	FUNCTION 1 cmp_user_composite_type_function(user_composite_type, user_composite_type);
$f$);
 run_command_on_master_and_workers 
-----------------------------------
 
(1 row)

SELECT run_command_on_master_and_workers($f$

	CREATE OPERATOR CLASS cats_2_op_fam_class
	DEFAULT FOR TYPE user_composite_type USING HASH AS
	OPERATOR 1 = (user_composite_type, user_composite_type),
	FUNCTION 1 test_composite_type_hash(user_composite_type);
$f$);
 run_command_on_master_and_workers 
-----------------------------------
 
(1 row)

CREATE TABLE events (
	composite_id user_composite_type,
	event_id bigint,
	event_type character varying(255),
	event_time bigint
);
SELECT master_create_distributed_table('events', 'composite_id', 'range');
 master_create_distributed_table 
---------------------------------
 
(1 row)

SELECT master_create_empty_shard('events') AS new_shard_id
\gset
UPDATE pg_dist_shard SET shardminvalue = '(1,1)', shardmaxvalue = '(1,2000000000)'
WHERE shardid = :new_shard_id;
SELECT master_create_empty_shard('events') AS new_shard_id
\gset
UPDATE pg_dist_shard SET shardminvalue = '(1,2000000001)', shardmaxvalue = '(1,4300000000)'
WHERE shardid = :new_shard_id;
SELECT master_create_empty_shard('events') AS new_shard_id
\gset
UPDATE pg_dist_shard SET shardminvalue = '(2,1)', shardmaxvalue = '(2,2000000000)'
WHERE shardid = :new_shard_id;
SELECT master_create_empty_shard('events') AS new_shard_id
\gset
UPDATE pg_dist_shard SET shardminvalue = '(2,2000000001)', shardmaxvalue = '(2,4300000000)'
WHERE shardid = :new_shard_id;
\COPY events FROM STDIN WITH CSV
CREATE TABLE users (
	composite_id user_composite_type,
	lastseen bigint
);
SELECT master_create_distributed_table('users', 'composite_id', 'range');
 master_create_distributed_table 
---------------------------------
 
(1 row)

SELECT master_create_empty_shard('users') AS new_shard_id
\gset
UPDATE pg_dist_shard SET shardminvalue = '(1,1)', shardmaxvalue = '(1,2000000000)'
WHERE shardid = :new_shard_id;
SELECT master_create_empty_shard('users') AS new_shard_id
\gset
UPDATE pg_dist_shard SET shardminvalue = '(1,2000000001)', shardmaxvalue = '(1,4300000000)'
WHERE shardid = :new_shard_id;
SELECT master_create_empty_shard('users') AS new_shard_id
\gset
UPDATE pg_dist_shard SET shardminvalue = '(2,1)', shardmaxvalue = '(2,2000000000)'
WHERE shardid = :new_shard_id;
SELECT master_create_empty_shard('users') AS new_shard_id
\gset
UPDATE pg_dist_shard SET shardminvalue = '(2,2000000001)', shardmaxvalue = '(2,4300000000)'
WHERE shardid = :new_shard_id;
\COPY users FROM STDIN WITH CSV
-- Create tables for subquery tests
CREATE TABLE lineitem_subquery (
	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) );
SELECT master_create_distributed_table('lineitem_subquery', 'l_orderkey', 'range');
 master_create_distributed_table 
---------------------------------
 
(1 row)

CREATE TABLE orders_subquery (
	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 master_create_distributed_table('orders_subquery', 'o_orderkey', 'range');
 master_create_distributed_table 
---------------------------------
 
(1 row)

SET citus.enable_router_execution TO 'false';
-- Check that we don't crash if there are not any shards.
SELECT
	avg(unit_price)
FROM
	(SELECT
		l_orderkey,
		avg(o_totalprice) AS unit_price
	FROM
		lineitem_subquery,
		orders_subquery
	WHERE
		l_orderkey = o_orderkey
	GROUP BY
		l_orderkey) AS unit_prices;
 avg 
-----
    
(1 row)

-- Load data into tables.
SELECT master_create_empty_shard('lineitem_subquery') AS new_shard_id
\gset
UPDATE pg_dist_shard SET shardminvalue = 1, shardmaxvalue = 5986
WHERE shardid = :new_shard_id;
SELECT master_create_empty_shard('lineitem_subquery') AS new_shard_id
\gset
UPDATE pg_dist_shard SET shardminvalue = 8997, shardmaxvalue = 14947
WHERE shardid = :new_shard_id;
SELECT master_create_empty_shard('orders_subquery') AS new_shard_id
\gset
UPDATE pg_dist_shard SET shardminvalue = 1, shardmaxvalue = 5986
WHERE shardid = :new_shard_id;
SELECT master_create_empty_shard('orders_subquery') AS new_shard_id
\gset
UPDATE pg_dist_shard SET shardminvalue = 8997, shardmaxvalue = 14947
WHERE shardid = :new_shard_id;
SET citus.shard_max_size TO "1MB";
\copy lineitem_subquery FROM '@abs_srcdir@/data/lineitem.1.data' with delimiter '|'
\copy lineitem_subquery FROM '@abs_srcdir@/data/lineitem.2.data' with delimiter '|'
\copy orders_subquery FROM '@abs_srcdir@/data/orders.1.data' with delimiter '|'
\copy orders_subquery FROM '@abs_srcdir@/data/orders.2.data' with delimiter '|'
CREATE TABLE events_reference_table (like events_table including all);
SELECT create_reference_table('events_reference_table');
 create_reference_table 
------------------------
 
(1 row)

CREATE INDEX events_ref_val2 on events_reference_table(value_2);
INSERT INTO events_reference_table SELECT * FROM events_table;
CREATE TABLE users_reference_table (like users_table including all);
SELECT create_reference_table('users_reference_table');
 create_reference_table 
------------------------
 
(1 row)

INSERT INTO users_reference_table SELECT * FROM users_table;
