ALTER SEQUENCE pg_catalog.pg_dist_shardid_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 perform an INSERT without a partition column value -- 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 perform an INSERT with NULL in the 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); -- 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 coordinator 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: cannot run DELETE command which targets multiple shards HINT: Consider using an equality filter on partition column "id" to target a single shard. If you'd like to run a multi-shard operation, use master_modify_multiple_shards(). -- 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: cannot run DELETE command which targets multiple shards HINT: Consider using an equality filter on partition column "id" to target a single shard. If you'd like to run a multi-shard operation, use master_modify_multiple_shards(). 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: cannot run UPDATE command which targets multiple shards HINT: Consider using an equality filter on partition column "id" to target a single shard. If you'd like to run a multi-shard operation, use master_modify_multiple_shards(). -- 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 coordinator 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 coordinator 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: cannot run UPDATE command which targets multiple shards HINT: Consider using an equality filter on partition column "id" to target a single shard. If you'd like to run a multi-shard operation, use master_modify_multiple_shards(). -- 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 ------------------ 3940649673949185 (1 row) INSERT INTO app_analytics_events_mx (app_id, name) VALUES (102, 'Wayz') RETURNING id; id ------------------ 3940649673949186 (1 row) INSERT INTO app_analytics_events_mx (app_id, name) VALUES (103, 'Mynt') RETURNING *; id | app_id | name ------------------+--------+------ 3940649673949187 | 103 | Mynt (1 row)