mirror of https://github.com/citusdata/citus.git
Disallow field indirection in INSERT/UPDATE queries (#4241)
parent
8efca3b60a
commit
1a28858c47
|
@ -130,6 +130,7 @@ static bool IsTidColumn(Node *node);
|
|||
static DeferredErrorMessage * ModifyPartialQuerySupported(Query *queryTree, bool
|
||||
multiShardQuery,
|
||||
Oid *distributedTableId);
|
||||
static bool NodeIsFieldStore(Node *node);
|
||||
static DeferredErrorMessage * DeferErrorIfUnsupportedModifyQueryWithLocalTable(
|
||||
Query *query);
|
||||
static DeferredErrorMessage * DeferErrorIfUnsupportedModifyQueryWithCitusLocalTable(
|
||||
|
@ -674,6 +675,18 @@ ModifyPartialQuerySupported(Query *queryTree, bool multiShardQuery,
|
|||
{
|
||||
Assert(hasVarArgument || hasBadCoalesce);
|
||||
}
|
||||
|
||||
if (FindNodeMatchingCheckFunction((Node *) targetEntry->expr,
|
||||
NodeIsFieldStore))
|
||||
{
|
||||
/* DELETE cannot do field indirection already */
|
||||
Assert(commandType == CMD_UPDATE || commandType == CMD_INSERT);
|
||||
return DeferredError(ERRCODE_FEATURE_NOT_SUPPORTED,
|
||||
"inserting or modifying composite type fields is not "
|
||||
"supported", NULL,
|
||||
"Use the column name to insert or update the composite "
|
||||
"type as a single value");
|
||||
}
|
||||
}
|
||||
|
||||
if (joinTree != NULL)
|
||||
|
@ -740,6 +753,16 @@ ModifyPartialQuerySupported(Query *queryTree, bool multiShardQuery,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* NodeIsFieldStore returns true if given Node is a FieldStore object.
|
||||
*/
|
||||
static bool
|
||||
NodeIsFieldStore(Node *node)
|
||||
{
|
||||
return node && IsA(node, FieldStore);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* DeferErrorIfUnsupportedModifyQueryWithLocalTable returns DeferredErrorMessage
|
||||
* for unsupported modify queries that cannot be planned by router planner due to
|
||||
|
|
|
@ -380,6 +380,79 @@ SELECT run_command_on_workers($$SELECT count(*) FROM pg_type where typname IN ('
|
|||
(2 rows)
|
||||
|
||||
RESET citus.enable_create_type_propagation;
|
||||
CREATE TYPE ct1 as (int_1 int, int_2 int);
|
||||
CREATE TABLE field_indirection_test_1 (int_col int, ct1_col ct1);
|
||||
SELECT create_distributed_table('field_indirection_test_1', 'int_col');
|
||||
create_distributed_table
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- not supported (field indirection in single row insert)
|
||||
INSERT INTO field_indirection_test_1 (int_col, ct1_col.int_1, ct1_col.int_2) VALUES (0, 1, 2);
|
||||
ERROR: inserting or modifying composite type fields is not supported
|
||||
HINT: Use the column name to insert or update the composite type as a single value
|
||||
INSERT INTO field_indirection_test_1 (int_col, ct1_col.int_1) VALUES (0, 1);
|
||||
ERROR: inserting or modifying composite type fields is not supported
|
||||
HINT: Use the column name to insert or update the composite type as a single value
|
||||
CREATE TYPE ct2 as (int_2 int, text_1 text, int_1 int);
|
||||
CREATE TABLE field_indirection_test_2 (int_col int, ct2_col ct2, ct1_col ct1);
|
||||
SELECT create_distributed_table('field_indirection_test_2', 'int_col');
|
||||
create_distributed_table
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- not supported (field indirection in multi row insert)
|
||||
INSERT INTO field_indirection_test_2 (ct2_col.int_1, int_col, ct2_col.text_1, ct1_col.int_2)
|
||||
VALUES (0, 1, 'text1', 2), (3, 4, 'text1', 5);
|
||||
ERROR: inserting or modifying composite type fields is not supported
|
||||
HINT: Use the column name to insert or update the composite type as a single value
|
||||
-- not supported (field indirection in update)
|
||||
UPDATE field_indirection_test_2 SET (ct2_col.text_1, ct1_col.int_2) = ('text2', 10) WHERE int_col=4;
|
||||
ERROR: inserting or modifying composite type fields is not supported
|
||||
HINT: Use the column name to insert or update the composite type as a single value
|
||||
CREATE TYPE two_ints as (if1 int, if2 int);
|
||||
CREATE DOMAIN domain AS two_ints CHECK ((VALUE).if1 > 0);
|
||||
-- citus does not propagate domain objects
|
||||
SELECT run_command_on_workers(
|
||||
$$
|
||||
CREATE DOMAIN type_tests.domain AS type_tests.two_ints CHECK ((VALUE).if1 > 0);
|
||||
$$);
|
||||
run_command_on_workers
|
||||
---------------------------------------------------------------------
|
||||
(localhost,57637,t,"CREATE DOMAIN")
|
||||
(localhost,57638,t,"CREATE DOMAIN")
|
||||
(2 rows)
|
||||
|
||||
CREATE TABLE domain_indirection_test (f1 int, f3 domain, domain_array domain[]);
|
||||
SELECT create_distributed_table('domain_indirection_test', 'f1');
|
||||
create_distributed_table
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- not supported (field indirection to underlying composite type)
|
||||
INSERT INTO domain_indirection_test (f1,f3.if1, f3.if2) VALUES (0, 1, 2);
|
||||
ERROR: inserting or modifying composite type fields is not supported
|
||||
HINT: Use the column name to insert or update the composite type as a single value
|
||||
INSERT INTO domain_indirection_test (f1,f3.if1) VALUES (0, 1);
|
||||
ERROR: inserting or modifying composite type fields is not supported
|
||||
HINT: Use the column name to insert or update the composite type as a single value
|
||||
UPDATE domain_indirection_test SET domain_array[0].if2 = 5;
|
||||
ERROR: inserting or modifying composite type fields is not supported
|
||||
HINT: Use the column name to insert or update the composite type as a single value
|
||||
-- below are supported as we don't do any field indirection
|
||||
INSERT INTO field_indirection_test_2 (ct2_col, int_col, ct1_col)
|
||||
VALUES ('(1, "text1", 2)', 3, '(4, 5)'), ('(6, "text2", 7)', 8, '(9, 10)');
|
||||
UPDATE field_indirection_test_2 SET (ct2_col, ct1_col) = ('(10, "text10", 20)', '(40, 50)') WHERE int_col=8;
|
||||
SELECT * FROM field_indirection_test_2 ORDER BY 1,2,3;
|
||||
int_col | ct2_col | ct1_col
|
||||
---------------------------------------------------------------------
|
||||
3 | (1," text1",2) | (4,5)
|
||||
8 | (10," text10",20) | (40,50)
|
||||
(2 rows)
|
||||
|
||||
-- clear objects
|
||||
SET client_min_messages TO error; -- suppress cascading objects dropping
|
||||
DROP SCHEMA type_tests CASCADE;
|
||||
|
|
|
@ -240,6 +240,47 @@ SELECT run_command_on_workers($$SELECT count(*) FROM pg_type where typname IN ('
|
|||
|
||||
RESET citus.enable_create_type_propagation;
|
||||
|
||||
CREATE TYPE ct1 as (int_1 int, int_2 int);
|
||||
CREATE TABLE field_indirection_test_1 (int_col int, ct1_col ct1);
|
||||
SELECT create_distributed_table('field_indirection_test_1', 'int_col');
|
||||
|
||||
-- not supported (field indirection in single row insert)
|
||||
INSERT INTO field_indirection_test_1 (int_col, ct1_col.int_1, ct1_col.int_2) VALUES (0, 1, 2);
|
||||
INSERT INTO field_indirection_test_1 (int_col, ct1_col.int_1) VALUES (0, 1);
|
||||
|
||||
CREATE TYPE ct2 as (int_2 int, text_1 text, int_1 int);
|
||||
CREATE TABLE field_indirection_test_2 (int_col int, ct2_col ct2, ct1_col ct1);
|
||||
SELECT create_distributed_table('field_indirection_test_2', 'int_col');
|
||||
|
||||
-- not supported (field indirection in multi row insert)
|
||||
INSERT INTO field_indirection_test_2 (ct2_col.int_1, int_col, ct2_col.text_1, ct1_col.int_2)
|
||||
VALUES (0, 1, 'text1', 2), (3, 4, 'text1', 5);
|
||||
|
||||
-- not supported (field indirection in update)
|
||||
UPDATE field_indirection_test_2 SET (ct2_col.text_1, ct1_col.int_2) = ('text2', 10) WHERE int_col=4;
|
||||
|
||||
CREATE TYPE two_ints as (if1 int, if2 int);
|
||||
CREATE DOMAIN domain AS two_ints CHECK ((VALUE).if1 > 0);
|
||||
-- citus does not propagate domain objects
|
||||
SELECT run_command_on_workers(
|
||||
$$
|
||||
CREATE DOMAIN type_tests.domain AS type_tests.two_ints CHECK ((VALUE).if1 > 0);
|
||||
$$);
|
||||
CREATE TABLE domain_indirection_test (f1 int, f3 domain, domain_array domain[]);
|
||||
SELECT create_distributed_table('domain_indirection_test', 'f1');
|
||||
|
||||
-- not supported (field indirection to underlying composite type)
|
||||
INSERT INTO domain_indirection_test (f1,f3.if1, f3.if2) VALUES (0, 1, 2);
|
||||
INSERT INTO domain_indirection_test (f1,f3.if1) VALUES (0, 1);
|
||||
UPDATE domain_indirection_test SET domain_array[0].if2 = 5;
|
||||
|
||||
-- below are supported as we don't do any field indirection
|
||||
INSERT INTO field_indirection_test_2 (ct2_col, int_col, ct1_col)
|
||||
VALUES ('(1, "text1", 2)', 3, '(4, 5)'), ('(6, "text2", 7)', 8, '(9, 10)');
|
||||
UPDATE field_indirection_test_2 SET (ct2_col, ct1_col) = ('(10, "text10", 20)', '(40, 50)') WHERE int_col=8;
|
||||
|
||||
SELECT * FROM field_indirection_test_2 ORDER BY 1,2,3;
|
||||
|
||||
-- clear objects
|
||||
SET client_min_messages TO error; -- suppress cascading objects dropping
|
||||
DROP SCHEMA type_tests CASCADE;
|
||||
|
|
Loading…
Reference in New Issue