--
-- MULTI_SHARD_MODIFY
--
SET citus.next_shard_id TO 350000;
-- Create a new hash partitioned multi_shard_modify_test table and load data into it.
CREATE TABLE multi_shard_modify_test (
        t_key integer not null,
        t_name varchar(25) not null,
        t_value integer not null);
SELECT create_distributed_table('multi_shard_modify_test', 't_key', 'hash');
 create_distributed_table
---------------------------------------------------------------------

(1 row)

COPY multi_shard_modify_test (t_key, t_name, t_value) FROM STDIN WITH (FORMAT 'csv');
-- Testing master_modify_multiple_shards
-- Verify that master_modify_multiple_shards can be rolled back
BEGIN;
SELECT master_modify_multiple_shards('DELETE FROM multi_shard_modify_test WHERE t_key > 10 AND t_key <= 13');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
 master_modify_multiple_shards
---------------------------------------------------------------------
                             0
(1 row)

SELECT master_modify_multiple_shards('DELETE FROM multi_shard_modify_test WHERE t_key = 202');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
 master_modify_multiple_shards
---------------------------------------------------------------------
                             0
(1 row)

ROLLBACK;
SELECT count(*) FROM multi_shard_modify_test;
 count
---------------------------------------------------------------------
    27
(1 row)

-- commands with volatile functions in their quals
SELECT master_modify_multiple_shards('DELETE FROM multi_shard_modify_test WHERE t_key = (random() * 1000)');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
ERROR:  functions used in the WHERE clause of modification queries on distributed tables must not be VOLATILE
SELECT master_modify_multiple_shards('DELETE FROM multi_shard_modify_test WHERE t_value = (random() * 1000)');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
ERROR:  functions used in the WHERE clause of modification queries on distributed tables must not be VOLATILE
-- commands with immutable functions in their quals
SELECT master_modify_multiple_shards('DELETE FROM multi_shard_modify_test WHERE t_key = abs(-3)');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
 master_modify_multiple_shards
---------------------------------------------------------------------
                             0
(1 row)

-- DELETE with expression in WHERE clause
SELECT master_modify_multiple_shards('DELETE FROM multi_shard_modify_test WHERE t_key = (3*18-40)');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
 master_modify_multiple_shards
---------------------------------------------------------------------
                             0
(1 row)

-- commands with a USING a non distributed table error out
CREATE TABLE temp_nations(name text, key integer);
SELECT master_modify_multiple_shards('DELETE FROM multi_shard_modify_test USING temp_nations WHERE multi_shard_modify_test.t_value = temp_nations.key AND temp_nations.name = ''foobar'' ');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
ERROR:  relation temp_nations is not distributed
-- commands with a USING clause are unsupported
SELECT create_distributed_table('temp_nations', 'name', 'hash');
 create_distributed_table
---------------------------------------------------------------------

(1 row)

SELECT master_modify_multiple_shards('DELETE FROM multi_shard_modify_test USING temp_nations WHERE multi_shard_modify_test.t_value = temp_nations.key AND temp_nations.name = ''foobar'' ');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
ERROR:  complex joins are only supported when all distributed tables are co-located and joined on their distribution columns
-- commands with a RETURNING clause are unsupported
SELECT master_modify_multiple_shards('DELETE FROM multi_shard_modify_test WHERE t_key = 3 RETURNING *');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
 master_modify_multiple_shards
---------------------------------------------------------------------
                             0
(1 row)

-- commands containing a CTE are unsupported
SELECT master_modify_multiple_shards('WITH deleted_stuff AS (INSERT INTO multi_shard_modify_test DEFAULT VALUES RETURNING *) DELETE FROM multi_shard_modify_test');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
ERROR:  cannot perform an INSERT without a partition column value
-- Check that we can successfully delete from multiple shards with 1PC
SET citus.multi_shard_commit_protocol TO '1pc';
SELECT count(*) FROM multi_shard_modify_test;
 count
---------------------------------------------------------------------
    25
(1 row)

SELECT master_modify_multiple_shards('DELETE FROM multi_shard_modify_test WHERE t_key > 200');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
 master_modify_multiple_shards
---------------------------------------------------------------------
                             0
(1 row)

SELECT count(*) FROM multi_shard_modify_test;
 count
---------------------------------------------------------------------
    23
(1 row)

-- Check that we can successfully delete from multiple shards with 2PC
SET citus.multi_shard_commit_protocol TO '2pc';
SELECT master_modify_multiple_shards('DELETE FROM multi_shard_modify_test WHERE t_key > 100');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
 master_modify_multiple_shards
---------------------------------------------------------------------
                             0
(1 row)

SELECT count(*) FROM multi_shard_modify_test;
 count
---------------------------------------------------------------------
    21
(1 row)

-- Check that shard pruning works
SET client_min_messages TO DEBUG2;
SELECT master_modify_multiple_shards('DELETE FROM multi_shard_modify_test WHERE t_key = 15');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
DEBUG:  Distributed planning for a fast-path router query
DEBUG:  Creating router plan
DEBUG:  Plan is router executable
DETAIL:  distribution column value: 15
 master_modify_multiple_shards
---------------------------------------------------------------------
                             0
(1 row)

SET client_min_messages TO NOTICE;
-- Check that master_modify_multiple_shards works without partition keys
SELECT master_modify_multiple_shards('DELETE FROM multi_shard_modify_test WHERE t_name LIKE ''barce%'' ');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
 master_modify_multiple_shards
---------------------------------------------------------------------
                             0
(1 row)

-- Simple, Single Shard Update
SELECT master_modify_multiple_shards('UPDATE multi_shard_modify_test SET t_name=''warsaw'' WHERE t_key=17');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
 master_modify_multiple_shards
---------------------------------------------------------------------
                             0
(1 row)

SELECT t_name FROM multi_shard_modify_test WHERE t_key=17;
 t_name
---------------------------------------------------------------------
 warsaw
(1 row)

-- Simple, Multi Shard Update
SELECT master_modify_multiple_shards('UPDATE multi_shard_modify_test SET t_name=''???'' WHERE t_key>30 AND t_key<35');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
 master_modify_multiple_shards
---------------------------------------------------------------------
                             0
(1 row)

SELECT t_name FROM multi_shard_modify_test WHERE t_key>30 AND t_key<35;
 t_name
---------------------------------------------------------------------
 ???
 ???
 ???
 ???
(4 rows)

-- expression UPDATE
SELECT master_modify_multiple_shards('UPDATE multi_shard_modify_test SET t_value=8*37 WHERE t_key>30 AND t_key<35');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
 master_modify_multiple_shards
---------------------------------------------------------------------
                             0
(1 row)

SELECT t_value FROM multi_shard_modify_test WHERE t_key>30 AND t_key<35;
 t_value
---------------------------------------------------------------------
     296
     296
     296
     296
(4 rows)

-- multi-column UPDATE
SELECT master_modify_multiple_shards('UPDATE multi_shard_modify_test SET t_name=''somename'', t_value=333 WHERE t_key>30 AND t_key<35');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
 master_modify_multiple_shards
---------------------------------------------------------------------
                             0
(1 row)

SELECT t_name, t_value FROM multi_shard_modify_test WHERE t_key>30 AND t_key<35;
  t_name  | t_value
---------------------------------------------------------------------
 somename |     333
 somename |     333
 somename |     333
 somename |     333
(4 rows)

-- commands with no constraints on the partition key are supported
SELECT master_modify_multiple_shards('UPDATE multi_shard_modify_test SET t_name=''nice city'' WHERE t_value < 0');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
 master_modify_multiple_shards
---------------------------------------------------------------------
                             0
(1 row)

SELECT t_name FROM multi_shard_modify_test WHERE t_value < 0;
  t_name
---------------------------------------------------------------------
 nice city
 nice city
(2 rows)

-- attempting to change the partition key is unsupported
SELECT master_modify_multiple_shards('UPDATE multi_shard_modify_test SET t_key=3000 WHERE t_key < 10 ');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
ERROR:  modifying the partition value of rows is not allowed
-- UPDATEs with a FROM clause are supported
SELECT master_modify_multiple_shards('UPDATE multi_shard_modify_test SET t_name = ''FAIL'' FROM temp_nations WHERE multi_shard_modify_test.t_key = 3 AND multi_shard_modify_test.t_value = temp_nations.key AND temp_nations.name = ''dummy'' ');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
 master_modify_multiple_shards
---------------------------------------------------------------------
                             0
(1 row)

-- commands with a RETURNING clause are unsupported
SELECT master_modify_multiple_shards('UPDATE multi_shard_modify_test SET t_name=''FAIL'' WHERE t_key=4 RETURNING *');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
 master_modify_multiple_shards
---------------------------------------------------------------------
                             0
(1 row)

-- commands containing a CTE are unsupported
SELECT master_modify_multiple_shards('WITH t AS (INSERT INTO multi_shard_modify_test DEFAULT VALUES RETURNING *) UPDATE multi_shard_modify_test SET t_name = ''FAIL'' ');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
ERROR:  cannot perform an INSERT without a partition column value
-- updates referencing just a var are supported
SELECT master_modify_multiple_shards('UPDATE multi_shard_modify_test SET t_value=t_key WHERE t_key = 10');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
 master_modify_multiple_shards
---------------------------------------------------------------------
                             0
(1 row)

SELECT t_value FROM multi_shard_modify_test WHERE t_key=10;
 t_value
---------------------------------------------------------------------
      10
(1 row)

-- updates referencing a column are supported
SELECT master_modify_multiple_shards('UPDATE multi_shard_modify_test SET t_value = t_value + 37 WHERE t_key = 10');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
 master_modify_multiple_shards
---------------------------------------------------------------------
                             0
(1 row)

SELECT t_value FROM multi_shard_modify_test WHERE t_key=10;
 t_value
---------------------------------------------------------------------
      47
(1 row)

CREATE FUNCTION temp_stable_func() RETURNS integer AS 'SELECT 10;' LANGUAGE SQL STABLE;
-- updates referencing non-IMMUTABLE functions are unsupported
SELECT master_modify_multiple_shards('UPDATE multi_shard_modify_test SET t_name = ''FAIL!'' WHERE t_key = temp_stable_func()');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
 master_modify_multiple_shards
---------------------------------------------------------------------
                             0
(1 row)

-- updates referencing IMMUTABLE functions in SET section are supported
SELECT master_modify_multiple_shards('UPDATE multi_shard_modify_test SET t_value = abs(-78) WHERE t_key = 10');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
 master_modify_multiple_shards
---------------------------------------------------------------------
                             0
(1 row)

SELECT t_value FROM multi_shard_modify_test WHERE t_key=10;
 t_value
---------------------------------------------------------------------
      78
(1 row)

-- updates referencing STABLE functions in SET section are supported
SELECT master_modify_multiple_shards('UPDATE multi_shard_modify_test SET t_value = temp_stable_func() * 2 WHERE t_key = 10');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
 master_modify_multiple_shards
---------------------------------------------------------------------
                             0
(1 row)

-- updates referencing VOLATILE functions in SET section are not supported
SELECT master_modify_multiple_shards('UPDATE multi_shard_modify_test SET t_value = random() WHERE t_key = 10');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
ERROR:  functions used in UPDATE queries on distributed tables must not be VOLATILE
-- commands with stable functions in their quals are allowed
SELECT master_modify_multiple_shards('DELETE FROM multi_shard_modify_test WHERE t_key = temp_stable_func()');
WARNING:  master_modify_multiple_shards is deprecated and will be removed in a future release.
HINT:  Run the command directly
 master_modify_multiple_shards
---------------------------------------------------------------------
                             0
(1 row)

SET citus.next_shard_id TO 102046;
