Commiting functions and plan-pushdown and modulo distribution columns - limitations...
authorPallavi Sontakke <[email protected]>
Tue, 18 Aug 2015 11:01:24 +0000 (16:31 +0530)
committerPallavi Sontakke <[email protected]>
Tue, 18 Aug 2015 11:01:24 +0000 (16:31 +0530)
src/test/regress/expected/xl_distribution_column_types_modulo.out [new file with mode: 0755]
src/test/regress/expected/xl_functions.out [new file with mode: 0644]
src/test/regress/expected/xl_plan_pushdown.out [new file with mode: 0755]
src/test/regress/serial_schedule
src/test/regress/sql/xl_distribution_column_types_modulo.sql [new file with mode: 0755]
src/test/regress/sql/xl_functions.sql [new file with mode: 0755]
src/test/regress/sql/xl_plan_pushdown.sql [new file with mode: 0755]

diff --git a/src/test/regress/expected/xl_distribution_column_types_modulo.out b/src/test/regress/expected/xl_distribution_column_types_modulo.out
new file mode 100755 (executable)
index 0000000..8e5534f
--- /dev/null
@@ -0,0 +1,263 @@
+-- Current Supported types for MODULO distribution column types - INT2, integer, INT4, BOOL, ABSTIME, RELTIME,DATE  
+-- However INT8 type should also be supported.So letting the test fail for now. 
+--INT8, 
+CREATE TABLE xl_dcm (
+    product_no integer,
+    product_id INT8 PRIMARY KEY,
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (product_id);
+
+--integer
+CREATE TABLE xl_dcm (
+    product_no integer,
+    product_id integer PRIMARY KEY,
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (product_id);
+--INT2, 
+CREATE TABLE xl_dcm1 (
+    product_no integer,
+    product_id INT2 PRIMARY KEY,
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (product_id);
+--OID, 
+CREATE TABLE xl_dcm2 (
+    product_no integer,
+    product_id OID PRIMARY KEY,
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (product_id);
+ERROR:  Column product_id is not modulo distributable data type
+--INT4, 
+CREATE TABLE xl_dcm3 (
+    product_no integer,
+    product_id INT4 PRIMARY KEY,
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (product_id);
+--BOOL, 
+CREATE TABLE xl_dcm4 (
+    product_no integer,
+    is_available BOOL PRIMARY KEY,
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (is_available);
+--INT2VECTOR, 
+CREATE TABLE xl_dcm5 (
+    product_no integer,
+    product_id integer,
+    sub_product_ids INT2VECTOR PRIMARY KEY, 
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (sub_product_ids);
+ERROR:  Column sub_product_ids is not modulo distributable data type
+--OIDVECTOR, 
+CREATE TABLE xl_dcm6 (
+    product_no integer,
+    product_id integer,
+    sub_product_ids OIDVECTOR PRIMARY KEY, 
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (sub_product_ids);
+ERROR:  Column sub_product_ids is not modulo distributable data type
+--CHAR, 
+CREATE TABLE xl_dcm7 (
+    product_no integer,
+    product_group CHAR PRIMARY KEY,
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (product_group);
+ERROR:  Column product_group is not modulo distributable data type
+--NAME, 
+CREATE TABLE xl_dcm8 (
+    product_no integer,
+    product_name NAME PRIMARY KEY,
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (product_name);
+ERROR:  Column product_name is not modulo distributable data type
+--TEXT, 
+CREATE TABLE xl_dcm9 (
+    product_no integer,
+    product_name TEXT PRIMARY KEY,
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (product_name);
+ERROR:  Column product_name is not modulo distributable data type
+--BPCHAR - blank padded char, 
+CREATE TABLE xl_dcm10 (
+    product_no integer,
+    product_group BPCHAR PRIMARY KEY,
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (product_group);
+ERROR:  Column product_group is not modulo distributable data type
+--BYTEA - variable length binary string, 
+CREATE TABLE xl_dcm11 (
+    product_no integer,
+    product_group BYTEA PRIMARY KEY,
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (product_group);
+ERROR:  Column product_group is not modulo distributable data type
+--VARCHAR, 
+CREATE TABLE xl_dcm12 (
+    product_no integer,
+    product_group VARCHAR PRIMARY KEY,
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (product_group);
+ERROR:  Column product_group is not modulo distributable data type
+--NUMERIC, 
+CREATE TABLE xl_dcm15 (
+    product_no integer,
+    product_id NUMERIC PRIMARY KEY,
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (product_id);
+ERROR:  Column product_id is not modulo distributable data type
+--MONEY - String datatype, 
+CREATE TABLE xl_dcm16 (
+    product_no integer,
+    product_id NUMERIC ,
+    name MONEY PRIMARY KEY,
+    price numeric
+) DISTRIBUTE BY MODULO (name);
+ERROR:  Column name is not modulo distributable data type
+--ABSTIME, 
+CREATE TABLE xl_dcm17 (
+    product_no integer,
+    product_id NUMERIC ,
+    purchase_date ABSTIME PRIMARY KEY,
+    price numeric
+) DISTRIBUTE BY MODULO (purchase_date);
+--RELTIME, 
+CREATE TABLE xl_dcm18 (
+    product_no integer,
+    product_id NUMERIC ,
+    name MONEY,
+    purchase_date RELTIME PRIMARY KEY,
+    price numeric
+) DISTRIBUTE BY MODULO (purchase_date);
+--DATE, 
+CREATE TABLE xl_dcm19 (
+    product_no integer,
+    product_id NUMERIC ,
+    name MONEY,
+    purchase_date DATE PRIMARY KEY,
+    price numeric
+) DISTRIBUTE BY MODULO (purchase_date);
+--TIME, 
+CREATE TABLE xl_dcm20 (
+    product_no integer,
+    product_id NUMERIC ,
+    name MONEY,
+    purchase_date TIME PRIMARY KEY,
+    price numeric
+) DISTRIBUTE BY MODULO (purchase_date);
+ERROR:  Column purchase_date is not modulo distributable data type
+--TIMESTAMP,
+CREATE TABLE xl_dcm21 (
+    product_no integer,
+    product_id NUMERIC ,
+    name MONEY,
+    purchase_date TIMESTAMP PRIMARY KEY,
+    price numeric
+) DISTRIBUTE BY MODULO (purchase_date); 
+ERROR:  Column purchase_date is not modulo distributable data type
+--TIMESTAMPTZ, 
+CREATE TABLE xl_dcm22 (
+    product_no integer,
+    product_id NUMERIC ,
+    name MONEY,
+    purchase_date TIMESTAMPTZ PRIMARY KEY,
+    price numeric
+) DISTRIBUTE BY MODULO (purchase_date); 
+ERROR:  Column purchase_date is not modulo distributable data type
+--INTERVAL, 
+CREATE TABLE xl_dcm23 (
+    product_no integer,
+    product_id NUMERIC ,
+    name MONEY,
+    purchase_date INTERVAL PRIMARY KEY,
+    price numeric
+) DISTRIBUTE BY MODULO (purchase_date); 
+ERROR:  Column purchase_date is not modulo distributable data type
+--and TIMETZ - time along with time zone
+CREATE TABLE xl_dcm24 (
+    product_no integer,
+    product_id NUMERIC ,
+    name MONEY,
+    purchase_date TIMETZ PRIMARY KEY,
+    price numeric
+) DISTRIBUTE BY MODULO (purchase_date); 
+ERROR:  Column purchase_date is not modulo distributable data type
+--Distribution strategy can specify on a single column
+CREATE TABLE xl_dcm25 (
+    product_no integer,
+    product_id NUMERIC ,
+    name MONEY,
+    purchase_date TIMETZ,
+    price numeric,
+    primary key(product_no, product_id)
+) DISTRIBUTE BY MODULO (product_no, product_id); --fail
+ERROR:  syntax error at or near ","
+LINE 8: ) DISTRIBUTE BY MODULO (product_no, product_id);
+                                          ^
+-- Distribution column value cannot be updated
+-- default distributed on HASH by primary key column, i.e. city
+CREATE TABLE xl_dcm_weather (
+    city_no         INT2 PRIMARY KEY,
+    temp_lo         int,           -- low temperature
+    temp_hi         int,           -- high temperature
+    prcp            real,          -- precipitation
+    date            date
+) DISTRIBUTE BY MODULO (city_no);
+INSERT INTO xl_dcm_weather VALUES (55, 46, 50, 0.25, '1994-11-27');
+UPDATE xl_dcm_weather SET city_no = 56 where temp_lo=46 and temp_hi=50; -- fail
+ERROR:  could not plan this distributed update
+DETAIL:  correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
+DROP TABLE xl_dcm;
+DROP TABLE xl_dcm1;
+DROP TABLE xl_dcm2;
+ERROR:  table "xl_dcm2" does not exist
+DROP TABLE xl_dcm3;
+DROP TABLE xl_dcm4;
+DROP TABLE xl_dcm5;
+ERROR:  table "xl_dcm5" does not exist
+DROP TABLE xl_dcm6;
+ERROR:  table "xl_dcm6" does not exist
+DROP TABLE xl_dcm7;
+ERROR:  table "xl_dcm7" does not exist
+DROP TABLE xl_dcm8;
+ERROR:  table "xl_dcm8" does not exist
+DROP TABLE xl_dcm9;
+ERROR:  table "xl_dcm9" does not exist
+DROP TABLE xl_dcm10;
+ERROR:  table "xl_dcm10" does not exist
+DROP TABLE xl_dcm11;
+ERROR:  table "xl_dcm11" does not exist
+DROP TABLE xl_dcm12;
+ERROR:  table "xl_dcm12" does not exist
+DROP TABLE xl_dcm15;
+ERROR:  table "xl_dcm15" does not exist
+DROP TABLE xl_dcm16;
+ERROR:  table "xl_dcm16" does not exist
+DROP TABLE xl_dcm17;
+DROP TABLE xl_dcm18;
+DROP TABLE xl_dcm19;
+DROP TABLE xl_dcm20;
+ERROR:  table "xl_dcm20" does not exist
+DROP TABLE xl_dcm21;
+ERROR:  table "xl_dcm21" does not exist
+DROP TABLE xl_dcm22;
+ERROR:  table "xl_dcm22" does not exist
+DROP TABLE xl_dcm23;
+ERROR:  table "xl_dcm23" does not exist
+DROP TABLE xl_dcm24;
+ERROR:  table "xl_dcm24" does not exist
+DROP TABLE xl_dcm25;
+ERROR:  table "xl_dcm25" does not exist
+DROP TABLE xl_dcm_weather;
diff --git a/src/test/regress/expected/xl_functions.out b/src/test/regress/expected/xl_functions.out
new file mode 100644 (file)
index 0000000..ce9c690
--- /dev/null
@@ -0,0 +1,118 @@
+--Immutable, stable, volatile functions and nextval are allowed in DEFAULT clause
+-- IMMUTABLE function is allowed
+CREATE FUNCTION xl_add(integer, integer) RETURNS integer
+    AS 'select $1 + $2;'
+    LANGUAGE SQL
+    IMMUTABLE
+    RETURNS NULL ON NULL INPUT;
+CREATE TABLE xl_funct2(
+       a integer,
+       b integer,
+       c integer DEFAULT xl_add(10,12 )
+) DISTRIBUTE BY HASH(a);
+INSERT INTO xl_funct2(a,b) VALUES (1,2);--c should be 22
+INSERT INTO xl_funct2(a,b,c) VALUES (3,4,5);-- c should be 5
+SELECT * from xl_funct2;
+ a | b | c  
+---+---+----
+ 1 | 2 | 22
+ 3 | 4 |  5
+(2 rows)
+
+--STABLE functions
+-- checking STABLE function in DEFAULT of non-distribution column
+create table xl_users (userid text, seq int, name text);
+insert into xl_users values ('id',1,'pallavi');
+insert into xl_users values ('id2',2,'xyz');
+create or replace function xl_get_first_user() returns text as
+$$ SELECT name FROM xl_users ORDER BY userid LIMIT 1; $$
+language sql stable;
+CREATE TABLE xl_funct3(
+       a integer,
+       b integer,
+       c text DEFAULT xl_get_first_user()
+) DISTRIBUTE BY HASH(a);
+INSERT INTO xl_funct3(a,b) VALUES (1,2);--c should be pallavi
+INSERT INTO xl_funct3(a,b,c) VALUES (3,4,'qwerty');-- c should be qwerty
+SELECT * from xl_funct3;
+ a | b |    c    
+---+---+---------
+ 1 | 2 | pallavi
+ 3 | 4 | qwerty
+(2 rows)
+
+-- checking STABLE function in DEFAULT of distribution column
+CREATE TABLE xl_funct4(
+       a integer,
+       b integer,
+       c text DEFAULT xl_get_first_user()
+) DISTRIBUTE BY HASH(c);
+INSERT INTO xl_funct4(a,b) VALUES (1,2);--c should be pallavi
+INSERT INTO xl_funct4(a,b,c) VALUES (3,4,'qwerty');-- c should be qwerty
+SELECT * from xl_funct4;
+ a | b |    c    
+---+---+---------
+ 1 | 2 | pallavi
+ 3 | 4 | qwerty
+(2 rows)
+
+--VOLATILE functions
+create or replace function xl_get_curr_decade() returns double precision as
+$$ SELECT EXTRACT(DECADE FROM NOW()); $$
+language sql volatile;
+CREATE TABLE xl_funct5(
+       a integer,
+       b integer,
+       c double precision DEFAULT xl_get_curr_decade()
+) DISTRIBUTE BY HASH(a);
+INSERT INTO xl_funct5(a,b) VALUES (1,2);--c should be e.g. 201 for 2015
+INSERT INTO xl_funct5(a,b,c) VALUES (3,4,20);-- c should be 20
+SELECT * from xl_funct5;
+ a | b |  c  
+---+---+-----
+ 1 | 2 | 201
+ 3 | 4 |  20
+(2 rows)
+
+--nextval check
+CREATE SEQUENCE xl_INSERT_SEQ;
+CREATE TABLE xl_funct (
+       a integer,
+       b INT DEFAULT nextval('xl_insert_seq')
+) DISTRIBUTE BY HASH (a);
+INSERT INTO xl_funct (a) VALUES (1);
+INSERT INTO xl_funct (a) VALUES (2);
+INSERT INTO xl_funct (a) VALUES (3);
+SELECT * FROM xl_funct;
+ a | b 
+---+---
+ 1 | 1
+ 2 | 2
+ 3 | 3
+(3 rows)
+
+CREATE TABLE xl_funct1 (
+       a integer DEFAULT nextval('xl_insert_seq'),
+       b INT 
+) DISTRIBUTE BY HASH (a);
+INSERT INTO xl_funct1 (b) VALUES (1);
+INSERT INTO xl_funct1 (b) VALUES (2);
+INSERT INTO xl_funct1 (b) VALUES (3);
+SELECT * FROM xl_funct1;
+ a | b 
+---+---
+ 5 | 2
+ 6 | 3
+ 4 | 1
+(3 rows)
+
+DROP TABLE xl_funct;
+DROP TABLE xl_funct1;
+DROP SEQUENCE xl_INSERT_SEQ;
+DROP TABLE xl_funct2;
+DROP TABLE xl_funct3;
+DROP TABLE xl_funct4;
+DROP TABLE xl_users;
+DROP FUNCTION xl_get_first_user();
+DROP TABLE xl_funct5;
+DROP FUNCTION xl_get_curr_decade();
diff --git a/src/test/regress/expected/xl_plan_pushdown.out b/src/test/regress/expected/xl_plan_pushdown.out
new file mode 100755 (executable)
index 0000000..51580b7
--- /dev/null
@@ -0,0 +1,229 @@
+--ensure that the plans are being pushed to the right subset of nodes
+--Sometimes plans get pushed down to more nodes than they really need to.
+CREATE TABLE xl_pp (a bigint, b int) DISTRIBUTE BY HASH(a);
+INSERT INTO xl_pp SELECT generate_series(1,100), 20;
+EXPLAIN VERBOSE SELECT * FROM xl_pp WHERE a = 100;
+                                       QUERY PLAN                                       
+----------------------------------------------------------------------------------------
+ Remote Subquery Scan on all (datanode2)  (cost=0.00..35.50 rows=10 width=12)
+   Output: a, b
+   ->  Seq Scan on public.xl_pp  (cost=0.00..35.50 rows=10 width=12)
+         Output: a, b
+         Filter: (xl_pp.a = 100)
+(5 rows)
+
+--This goes to all nodes (incorrect behavior)
+EXPLAIN VERBOSE SELECT * FROM xl_pp WHERE a = 100::bigint;
+                                  QUERY PLAN                                  
+------------------------------------------------------------------------------
+ Remote Subquery Scan on all (datanode2)  (cost=0.00..35.50 rows=10 width=12)
+   Output: a, b
+   ->  Seq Scan on public.xl_pp  (cost=0.00..35.50 rows=10 width=12)
+         Output: a, b
+         Filter: (xl_pp.a = '100'::bigint)
+(5 rows)
+
+--goes to just one node where 100 is mapped to
+--Looks like we test for datatypes for distribution column and constant literals and want them to be of the same type for pushdown to work
+--Doesn't look like a necessary restriction.
+--100 by default gets typecast-ed to INT
+-- Same behavior for SELECT, DELETE and UPDATE right now - (bug) - hence test is failing. 
+EXPLAIN VERBOSE INSERT INTO xl_pp (a, b) VALUES (200, 1) ;
+                                    QUERY PLAN                                    
+----------------------------------------------------------------------------------
+ Remote Subquery Scan on all (datanode1)  (cost=0.00..0.01 rows=1 width=0)
+   ->  Insert on public.xl_pp  (cost=0.00..0.01 rows=1 width=0)
+         ->  Remote Subquery Scan on local node  (cost=0.00..0.01 rows=1 width=0)
+               Output: '200'::bigint, 1
+               Distribute results by H: '200'::bigint
+               ->  Result  (cost=0.00..0.01 rows=1 width=0)
+                     Output: '200'::bigint, 1
+(7 rows)
+
+EXPLAIN VERBOSE INSERT INTO xl_pp (a, b) VALUES (201::bigint, 1) ;
+                                    QUERY PLAN                                    
+----------------------------------------------------------------------------------
+ Remote Subquery Scan on all (datanode1)  (cost=0.00..0.01 rows=1 width=0)
+   ->  Insert on public.xl_pp  (cost=0.00..0.01 rows=1 width=0)
+         ->  Remote Subquery Scan on local node  (cost=0.00..0.01 rows=1 width=0)
+               Output: '201'::bigint, 1
+               Distribute results by H: '201'::bigint
+               ->  Result  (cost=0.00..0.01 rows=1 width=0)
+                     Output: '201'::bigint, 1
+(7 rows)
+
+EXPLAIN VERBOSE UPDATE xl_pp SET b=2 where a=200;
+                                       QUERY PLAN                                       
+----------------------------------------------------------------------------------------
+ Remote Subquery Scan on all (datanode1)  (cost=0.00..35.50 rows=10 width=18)
+   ->  Update on public.xl_pp  (cost=0.00..35.50 rows=10 width=18)
+         ->  Seq Scan on public.xl_pp  (cost=0.00..35.50 rows=10 width=18)
+               Output: a, 2, a, xc_node_id, ctid
+               Filter: (xl_pp.a = 200)
+(5 rows)
+
+EXPLAIN VERBOSE UPDATE xl_pp SET b=2 where a=200::bigint;
+                                  QUERY PLAN                                  
+------------------------------------------------------------------------------
+ Remote Subquery Scan on all (datanode1)  (cost=0.00..35.50 rows=10 width=18)
+   ->  Update on public.xl_pp  (cost=0.00..35.50 rows=10 width=18)
+         ->  Seq Scan on public.xl_pp  (cost=0.00..35.50 rows=10 width=18)
+               Output: a, 2, a, xc_node_id, ctid
+               Filter: (xl_pp.a = '200'::bigint)
+(5 rows)
+
+EXPLAIN VERBOSE DELETE FROM xl_pp where a=200;
+                                       QUERY PLAN                                       
+----------------------------------------------------------------------------------------
+ Remote Subquery Scan on all (datanode1)  (cost=0.00..35.50 rows=10 width=18)
+   ->  Delete on public.xl_pp  (cost=0.00..35.50 rows=10 width=18)
+         ->  Seq Scan on public.xl_pp  (cost=0.00..35.50 rows=10 width=18)
+               Output: a, xc_node_id, ctid, a
+               Filter: (xl_pp.a = 200)
+(5 rows)
+
+SELECT * from xl_pp where a=200;
+ a | b 
+---+---
+(0 rows)
+
+SELECT * from xl_pp where a=200::bigint;
+ a | b 
+---+---
+(0 rows)
+
+EXPLAIN VERBOSE DELETE FROM xl_pp where a=200;
+                                       QUERY PLAN                                       
+----------------------------------------------------------------------------------------
+ Remote Subquery Scan on all (datanode1)  (cost=0.00..35.50 rows=10 width=18)
+   ->  Delete on public.xl_pp  (cost=0.00..35.50 rows=10 width=18)
+         ->  Seq Scan on public.xl_pp  (cost=0.00..35.50 rows=10 width=18)
+               Output: a, xc_node_id, ctid, a
+               Filter: (xl_pp.a = 200)
+(5 rows)
+
+EXPLAIN VERBOSE DELETE FROM xl_pp where a=200::bigint;
+                                  QUERY PLAN                                  
+------------------------------------------------------------------------------
+ Remote Subquery Scan on all (datanode1)  (cost=0.00..35.50 rows=10 width=18)
+   ->  Delete on public.xl_pp  (cost=0.00..35.50 rows=10 width=18)
+         ->  Seq Scan on public.xl_pp  (cost=0.00..35.50 rows=10 width=18)
+               Output: a, xc_node_id, ctid, a
+               Filter: (xl_pp.a = '200'::bigint)
+(5 rows)
+
+--Testing with MODULO distribution
+CREATE TABLE xl_ppm (a INT2, b int) DISTRIBUTE BY MODULO(a);
+INSERT INTO xl_ppm SELECT generate_series(1,100), 20;
+EXPLAIN VERBOSE SELECT * FROM xl_ppm WHERE a = 100;
+                                      QUERY PLAN                                       
+---------------------------------------------------------------------------------------
+ Remote Subquery Scan on all (datanode1)  (cost=0.00..40.00 rows=12 width=6)
+   Output: a, b
+   ->  Seq Scan on public.xl_ppm  (cost=0.00..40.00 rows=12 width=6)
+         Output: a, b
+         Filter: (xl_ppm.a = 100)
+(5 rows)
+
+--This goes to all nodes (incorrect behavior)
+EXPLAIN VERBOSE SELECT * FROM xl_ppm WHERE a = 100::INT2;
+                                 QUERY PLAN                                  
+-----------------------------------------------------------------------------
+ Remote Subquery Scan on all (datanode1)  (cost=0.00..40.00 rows=12 width=6)
+   Output: a, b
+   ->  Seq Scan on public.xl_ppm  (cost=0.00..40.00 rows=12 width=6)
+         Output: a, b
+         Filter: (xl_ppm.a = '100'::smallint)
+(5 rows)
+
+--goes to just one node where 100 is mapped to
+--Looks like we test for datatypes for distribution column and constant literals and want them to be of the same type for pushdown to work
+--Doesn't look like a necessary restriction.
+--100 by default gets typecast-ed to INT
+-- Same behavior for SELECT, DELETE and UPDATE right now - (bug) - hence test is failing. 
+EXPLAIN VERBOSE INSERT INTO xl_ppm (a, b) VALUES (200, 1) ;
+                                    QUERY PLAN                                    
+----------------------------------------------------------------------------------
+ Remote Subquery Scan on all (datanode1)  (cost=0.00..0.01 rows=1 width=0)
+   ->  Insert on public.xl_ppm  (cost=0.00..0.01 rows=1 width=0)
+         ->  Remote Subquery Scan on local node  (cost=0.00..0.01 rows=1 width=0)
+               Output: '200'::smallint, 1
+               Distribute results by M: '200'::smallint
+               ->  Result  (cost=0.00..0.01 rows=1 width=0)
+                     Output: '200'::smallint, 1
+(7 rows)
+
+EXPLAIN VERBOSE INSERT INTO xl_ppm (a, b) VALUES (201::INT2, 1) ;
+                                    QUERY PLAN                                    
+----------------------------------------------------------------------------------
+ Remote Subquery Scan on all (datanode2)  (cost=0.00..0.01 rows=1 width=0)
+   ->  Insert on public.xl_ppm  (cost=0.00..0.01 rows=1 width=0)
+         ->  Remote Subquery Scan on local node  (cost=0.00..0.01 rows=1 width=0)
+               Output: '201'::smallint, 1
+               Distribute results by M: '201'::smallint
+               ->  Result  (cost=0.00..0.01 rows=1 width=0)
+                     Output: '201'::smallint, 1
+(7 rows)
+
+EXPLAIN VERBOSE UPDATE xl_ppm SET b=2 where a=200;
+                                       QUERY PLAN                                       
+----------------------------------------------------------------------------------------
+ Remote Subquery Scan on all (datanode1)  (cost=0.00..40.00 rows=12 width=12)
+   ->  Update on public.xl_ppm  (cost=0.00..40.00 rows=12 width=12)
+         ->  Seq Scan on public.xl_ppm  (cost=0.00..40.00 rows=12 width=12)
+               Output: a, 2, a, xc_node_id, ctid
+               Filter: (xl_ppm.a = 200)
+(5 rows)
+
+EXPLAIN VERBOSE UPDATE xl_ppm SET b=2 where a=200::INT2;
+                                  QUERY PLAN                                  
+------------------------------------------------------------------------------
+ Remote Subquery Scan on all (datanode1)  (cost=0.00..40.00 rows=12 width=12)
+   ->  Update on public.xl_ppm  (cost=0.00..40.00 rows=12 width=12)
+         ->  Seq Scan on public.xl_ppm  (cost=0.00..40.00 rows=12 width=12)
+               Output: a, 2, a, xc_node_id, ctid
+               Filter: (xl_ppm.a = '200'::smallint)
+(5 rows)
+
+EXPLAIN VERBOSE DELETE FROM xl_ppm where a=200;
+                                       QUERY PLAN                                       
+----------------------------------------------------------------------------------------
+ Remote Subquery Scan on all (datanode1)  (cost=0.00..40.00 rows=12 width=12)
+   ->  Delete on public.xl_ppm  (cost=0.00..40.00 rows=12 width=12)
+         ->  Seq Scan on public.xl_ppm  (cost=0.00..40.00 rows=12 width=12)
+               Output: a, xc_node_id, ctid, a
+               Filter: (xl_ppm.a = 200)
+(5 rows)
+
+SELECT * from xl_ppm where a=200;
+ a | b 
+---+---
+(0 rows)
+
+SELECT * from xl_ppm where a=200::INT2;
+ a | b 
+---+---
+(0 rows)
+
+EXPLAIN VERBOSE DELETE FROM xl_ppm where a=200;
+                                       QUERY PLAN                                       
+----------------------------------------------------------------------------------------
+ Remote Subquery Scan on all (datanode1)  (cost=0.00..40.00 rows=12 width=12)
+   ->  Delete on public.xl_ppm  (cost=0.00..40.00 rows=12 width=12)
+         ->  Seq Scan on public.xl_ppm  (cost=0.00..40.00 rows=12 width=12)
+               Output: a, xc_node_id, ctid, a
+               Filter: (xl_ppm.a = 200)
+(5 rows)
+
+EXPLAIN VERBOSE DELETE FROM xl_ppm where a=200::INT2;
+                                  QUERY PLAN                                  
+------------------------------------------------------------------------------
+ Remote Subquery Scan on all (datanode1)  (cost=0.00..40.00 rows=12 width=12)
+   ->  Delete on public.xl_ppm  (cost=0.00..40.00 rows=12 width=12)
+         ->  Seq Scan on public.xl_ppm  (cost=0.00..40.00 rows=12 width=12)
+               Output: a, xc_node_id, ctid, a
+               Filter: (xl_ppm.a = '200'::smallint)
+(5 rows)
+
+DROP TABLE xl_pp;
+DROP TABLE xl_ppm;
index 2edc25e237908a7d6318972ac897e70ecda661e0..33a6dddec9bd8c91de8f37bc284637c3df4b5a05 100644 (file)
@@ -180,3 +180,6 @@ test: xl_primary_key
 test: xl_foreign_key
 test: xl_distribution_column_types
 test: xl_alter_table
+test: xl_distribution_column_types_modulo
+test: xl_plan_pushdown
+test: xl_functions
diff --git a/src/test/regress/sql/xl_distribution_column_types_modulo.sql b/src/test/regress/sql/xl_distribution_column_types_modulo.sql
new file mode 100755 (executable)
index 0000000..f0a707f
--- /dev/null
@@ -0,0 +1,267 @@
+-- Current Supported types for MODULO distribution column types - INT2, integer, INT4, BOOL, ABSTIME, RELTIME,DATE  
+
+-- However INT8 type should also be supported.So letting the test fail for now. 
+
+--INT8, 
+
+CREATE TABLE xl_dcm (
+    product_no integer,
+    product_id INT8 PRIMARY KEY,
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (product_id);
+
+--integer
+CREATE TABLE xl_dcm (
+    product_no integer,
+    product_id integer PRIMARY KEY,
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (product_id);
+
+
+--INT2, 
+
+
+CREATE TABLE xl_dcm1 (
+    product_no integer,
+    product_id INT2 PRIMARY KEY,
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (product_id);
+
+--OID, 
+CREATE TABLE xl_dcm2 (
+    product_no integer,
+    product_id OID PRIMARY KEY,
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (product_id);
+
+--INT4, 
+CREATE TABLE xl_dcm3 (
+    product_no integer,
+    product_id INT4 PRIMARY KEY,
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (product_id);
+
+--BOOL, 
+
+CREATE TABLE xl_dcm4 (
+    product_no integer,
+    is_available BOOL PRIMARY KEY,
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (is_available);
+
+--INT2VECTOR, 
+CREATE TABLE xl_dcm5 (
+    product_no integer,
+    product_id integer,
+    sub_product_ids INT2VECTOR PRIMARY KEY, 
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (sub_product_ids);
+
+--OIDVECTOR, 
+CREATE TABLE xl_dcm6 (
+    product_no integer,
+    product_id integer,
+    sub_product_ids OIDVECTOR PRIMARY KEY, 
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (sub_product_ids);
+
+--CHAR, 
+CREATE TABLE xl_dcm7 (
+    product_no integer,
+    product_group CHAR PRIMARY KEY,
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (product_group);
+
+--NAME, 
+CREATE TABLE xl_dcm8 (
+    product_no integer,
+    product_name NAME PRIMARY KEY,
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (product_name);
+
+--TEXT, 
+CREATE TABLE xl_dcm9 (
+    product_no integer,
+    product_name TEXT PRIMARY KEY,
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (product_name);
+
+
+--BPCHAR - blank padded char, 
+CREATE TABLE xl_dcm10 (
+    product_no integer,
+    product_group BPCHAR PRIMARY KEY,
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (product_group);
+
+--BYTEA - variable length binary string, 
+CREATE TABLE xl_dcm11 (
+    product_no integer,
+    product_group BYTEA PRIMARY KEY,
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (product_group);
+
+--VARCHAR, 
+CREATE TABLE xl_dcm12 (
+    product_no integer,
+    product_group VARCHAR PRIMARY KEY,
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (product_group);
+
+--NUMERIC, 
+CREATE TABLE xl_dcm15 (
+    product_no integer,
+    product_id NUMERIC PRIMARY KEY,
+    name text,
+    price numeric
+) DISTRIBUTE BY MODULO (product_id);
+
+--MONEY - String datatype, 
+CREATE TABLE xl_dcm16 (
+    product_no integer,
+    product_id NUMERIC ,
+    name MONEY PRIMARY KEY,
+    price numeric
+) DISTRIBUTE BY MODULO (name);
+
+--ABSTIME, 
+CREATE TABLE xl_dcm17 (
+    product_no integer,
+    product_id NUMERIC ,
+    purchase_date ABSTIME PRIMARY KEY,
+    price numeric
+) DISTRIBUTE BY MODULO (purchase_date);
+
+--RELTIME, 
+CREATE TABLE xl_dcm18 (
+    product_no integer,
+    product_id NUMERIC ,
+    name MONEY,
+    purchase_date RELTIME PRIMARY KEY,
+    price numeric
+) DISTRIBUTE BY MODULO (purchase_date);
+
+
+--DATE, 
+CREATE TABLE xl_dcm19 (
+    product_no integer,
+    product_id NUMERIC ,
+    name MONEY,
+    purchase_date DATE PRIMARY KEY,
+    price numeric
+) DISTRIBUTE BY MODULO (purchase_date);
+
+--TIME, 
+CREATE TABLE xl_dcm20 (
+    product_no integer,
+    product_id NUMERIC ,
+    name MONEY,
+    purchase_date TIME PRIMARY KEY,
+    price numeric
+) DISTRIBUTE BY MODULO (purchase_date);
+
+--TIMESTAMP,
+
+CREATE TABLE xl_dcm21 (
+    product_no integer,
+    product_id NUMERIC ,
+    name MONEY,
+    purchase_date TIMESTAMP PRIMARY KEY,
+    price numeric
+) DISTRIBUTE BY MODULO (purchase_date); 
+
+--TIMESTAMPTZ, 
+
+CREATE TABLE xl_dcm22 (
+    product_no integer,
+    product_id NUMERIC ,
+    name MONEY,
+    purchase_date TIMESTAMPTZ PRIMARY KEY,
+    price numeric
+) DISTRIBUTE BY MODULO (purchase_date); 
+
+--INTERVAL, 
+CREATE TABLE xl_dcm23 (
+    product_no integer,
+    product_id NUMERIC ,
+    name MONEY,
+    purchase_date INTERVAL PRIMARY KEY,
+    price numeric
+) DISTRIBUTE BY MODULO (purchase_date); 
+
+--and TIMETZ - time along with time zone
+CREATE TABLE xl_dcm24 (
+    product_no integer,
+    product_id NUMERIC ,
+    name MONEY,
+    purchase_date TIMETZ PRIMARY KEY,
+    price numeric
+) DISTRIBUTE BY MODULO (purchase_date); 
+
+--Distribution strategy can specify on a single column
+CREATE TABLE xl_dcm25 (
+    product_no integer,
+    product_id NUMERIC ,
+    name MONEY,
+    purchase_date TIMETZ,
+    price numeric,
+    primary key(product_no, product_id)
+) DISTRIBUTE BY MODULO (product_no, product_id); --fail
+
+-- Distribution column value cannot be updated
+-- default distributed on HASH by primary key column, i.e. city
+CREATE TABLE xl_dcm_weather (
+    city_no         INT2 PRIMARY KEY,
+    temp_lo         int,           -- low temperature
+    temp_hi         int,           -- high temperature
+    prcp            real,          -- precipitation
+    date            date
+) DISTRIBUTE BY MODULO (city_no);
+
+INSERT INTO xl_dcm_weather VALUES (55, 46, 50, 0.25, '1994-11-27');
+
+UPDATE xl_dcm_weather SET city_no = 56 where temp_lo=46 and temp_hi=50; -- fail
+
+DROP TABLE xl_dcm;
+DROP TABLE xl_dcm1;
+DROP TABLE xl_dcm2;
+DROP TABLE xl_dcm3;
+DROP TABLE xl_dcm4;
+DROP TABLE xl_dcm5;
+DROP TABLE xl_dcm6;
+DROP TABLE xl_dcm7;
+DROP TABLE xl_dcm8;
+DROP TABLE xl_dcm9;
+DROP TABLE xl_dcm10;
+DROP TABLE xl_dcm11;
+DROP TABLE xl_dcm12;
+DROP TABLE xl_dcm15;
+DROP TABLE xl_dcm16;
+DROP TABLE xl_dcm17;
+DROP TABLE xl_dcm18;
+DROP TABLE xl_dcm19;
+DROP TABLE xl_dcm20;
+DROP TABLE xl_dcm21;
+DROP TABLE xl_dcm22;
+DROP TABLE xl_dcm23;
+DROP TABLE xl_dcm24;
+DROP TABLE xl_dcm25;
+DROP TABLE xl_dcm_weather;
+
+
+
+
diff --git a/src/test/regress/sql/xl_functions.sql b/src/test/regress/sql/xl_functions.sql
new file mode 100755 (executable)
index 0000000..4263c1a
--- /dev/null
@@ -0,0 +1,106 @@
+--Immutable, stable, volatile functions and nextval are allowed in DEFAULT clause
+
+-- IMMUTABLE function is allowed
+CREATE FUNCTION xl_add(integer, integer) RETURNS integer
+    AS 'select $1 + $2;'
+    LANGUAGE SQL
+    IMMUTABLE
+    RETURNS NULL ON NULL INPUT;
+
+CREATE TABLE xl_funct2(
+       a integer,
+       b integer,
+       c integer DEFAULT xl_add(10,12 )
+) DISTRIBUTE BY HASH(a);
+
+INSERT INTO xl_funct2(a,b) VALUES (1,2);--c should be 22
+INSERT INTO xl_funct2(a,b,c) VALUES (3,4,5);-- c should be 5
+
+SELECT * from xl_funct2;
+
+--STABLE functions
+-- checking STABLE function in DEFAULT of non-distribution column
+create table xl_users (userid text, seq int, name text);
+insert into xl_users values ('id',1,'pallavi');
+insert into xl_users values ('id2',2,'xyz');
+
+create or replace function xl_get_first_user() returns text as
+$$ SELECT name FROM xl_users ORDER BY userid LIMIT 1; $$
+language sql stable;
+
+CREATE TABLE xl_funct3(
+       a integer,
+       b integer,
+       c text DEFAULT xl_get_first_user()
+) DISTRIBUTE BY HASH(a);
+
+INSERT INTO xl_funct3(a,b) VALUES (1,2);--c should be pallavi
+INSERT INTO xl_funct3(a,b,c) VALUES (3,4,'qwerty');-- c should be qwerty
+
+SELECT * from xl_funct3;
+
+-- checking STABLE function in DEFAULT of distribution column
+CREATE TABLE xl_funct4(
+       a integer,
+       b integer,
+       c text DEFAULT xl_get_first_user()
+) DISTRIBUTE BY HASH(c);
+
+INSERT INTO xl_funct4(a,b) VALUES (1,2);--c should be pallavi
+INSERT INTO xl_funct4(a,b,c) VALUES (3,4,'qwerty');-- c should be qwerty
+
+SELECT * from xl_funct4;
+
+--VOLATILE functions
+
+create or replace function xl_get_curr_decade() returns double precision as
+$$ SELECT EXTRACT(DECADE FROM NOW()); $$
+language sql volatile;
+
+CREATE TABLE xl_funct5(
+       a integer,
+       b integer,
+       c double precision DEFAULT xl_get_curr_decade()
+) DISTRIBUTE BY HASH(a);
+
+INSERT INTO xl_funct5(a,b) VALUES (1,2);--c should be e.g. 201 for 2015
+INSERT INTO xl_funct5(a,b,c) VALUES (3,4,20);-- c should be 20
+
+SELECT * from xl_funct5;
+
+--nextval check
+CREATE SEQUENCE xl_INSERT_SEQ;
+
+CREATE TABLE xl_funct (
+       a integer,
+       b INT DEFAULT nextval('xl_insert_seq')
+) DISTRIBUTE BY HASH (a);
+
+INSERT INTO xl_funct (a) VALUES (1);
+INSERT INTO xl_funct (a) VALUES (2);
+INSERT INTO xl_funct (a) VALUES (3);
+
+SELECT * FROM xl_funct;
+
+CREATE TABLE xl_funct1 (
+       a integer DEFAULT nextval('xl_insert_seq'),
+       b INT 
+) DISTRIBUTE BY HASH (a);
+
+INSERT INTO xl_funct1 (b) VALUES (1);
+INSERT INTO xl_funct1 (b) VALUES (2);
+INSERT INTO xl_funct1 (b) VALUES (3);
+
+SELECT * FROM xl_funct1;
+
+
+DROP TABLE xl_funct;
+DROP TABLE xl_funct1;
+DROP SEQUENCE xl_INSERT_SEQ;
+DROP TABLE xl_funct2;
+DROP TABLE xl_funct3;
+DROP TABLE xl_funct4;
+DROP TABLE xl_users;
+DROP FUNCTION xl_get_first_user();
+DROP TABLE xl_funct5;
+DROP FUNCTION xl_get_curr_decade();
diff --git a/src/test/regress/sql/xl_plan_pushdown.sql b/src/test/regress/sql/xl_plan_pushdown.sql
new file mode 100755 (executable)
index 0000000..24b4699
--- /dev/null
@@ -0,0 +1,74 @@
+--ensure that the plans are being pushed to the right subset of nodes
+--Sometimes plans get pushed down to more nodes than they really need to.
+
+
+CREATE TABLE xl_pp (a bigint, b int) DISTRIBUTE BY HASH(a);
+
+INSERT INTO xl_pp SELECT generate_series(1,100), 20;
+
+EXPLAIN VERBOSE SELECT * FROM xl_pp WHERE a = 100;
+--This goes to all nodes (incorrect behavior)
+
+EXPLAIN VERBOSE SELECT * FROM xl_pp WHERE a = 100::bigint;
+--goes to just one node where 100 is mapped to
+
+--Looks like we test for datatypes for distribution column and constant literals and want them to be of the same type for pushdown to work
+--Doesn't look like a necessary restriction.
+--100 by default gets typecast-ed to INT
+-- Same behavior for SELECT, DELETE and UPDATE right now - (bug) - hence test is failing. 
+
+EXPLAIN VERBOSE INSERT INTO xl_pp (a, b) VALUES (200, 1) ;
+
+EXPLAIN VERBOSE INSERT INTO xl_pp (a, b) VALUES (201::bigint, 1) ;
+
+EXPLAIN VERBOSE UPDATE xl_pp SET b=2 where a=200;
+
+EXPLAIN VERBOSE UPDATE xl_pp SET b=2 where a=200::bigint;
+
+EXPLAIN VERBOSE DELETE FROM xl_pp where a=200;
+
+SELECT * from xl_pp where a=200;
+
+SELECT * from xl_pp where a=200::bigint;
+
+EXPLAIN VERBOSE DELETE FROM xl_pp where a=200;
+
+EXPLAIN VERBOSE DELETE FROM xl_pp where a=200::bigint;
+
+--Testing with MODULO distribution
+
+CREATE TABLE xl_ppm (a INT2, b int) DISTRIBUTE BY MODULO(a);
+
+INSERT INTO xl_ppm SELECT generate_series(1,100), 20;
+
+EXPLAIN VERBOSE SELECT * FROM xl_ppm WHERE a = 100;
+--This goes to all nodes (incorrect behavior)
+
+EXPLAIN VERBOSE SELECT * FROM xl_ppm WHERE a = 100::INT2;
+--goes to just one node where 100 is mapped to
+
+--Looks like we test for datatypes for distribution column and constant literals and want them to be of the same type for pushdown to work
+--Doesn't look like a necessary restriction.
+--100 by default gets typecast-ed to INT
+-- Same behavior for SELECT, DELETE and UPDATE right now - (bug) - hence test is failing. 
+
+EXPLAIN VERBOSE INSERT INTO xl_ppm (a, b) VALUES (200, 1) ;
+
+EXPLAIN VERBOSE INSERT INTO xl_ppm (a, b) VALUES (201::INT2, 1) ;
+
+EXPLAIN VERBOSE UPDATE xl_ppm SET b=2 where a=200;
+
+EXPLAIN VERBOSE UPDATE xl_ppm SET b=2 where a=200::INT2;
+
+EXPLAIN VERBOSE DELETE FROM xl_ppm where a=200;
+
+SELECT * from xl_ppm where a=200;
+
+SELECT * from xl_ppm where a=200::INT2;
+
+EXPLAIN VERBOSE DELETE FROM xl_ppm where a=200;
+
+EXPLAIN VERBOSE DELETE FROM xl_ppm where a=200::INT2;
+
+DROP TABLE xl_pp;
+DROP TABLE xl_ppm;