mirror of https://github.com/citusdata/citus.git
parent
2a6b9ffd39
commit
dcdaaaa88d
|
@ -1715,3 +1715,73 @@ RoleSpecString(RoleSpec *spec, bool withQuoteIdentifier)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* list_sort comparator to sort target list by paramid (in MULTIEXPR)
|
||||
* Intended for indirection management: UPDATE SET () = (SELECT )
|
||||
*/
|
||||
int
|
||||
target_list_cmp(const ListCell *a, const ListCell *b)
|
||||
{
|
||||
TargetEntry *tleA = lfirst(a);
|
||||
TargetEntry *tleB = lfirst(b);
|
||||
|
||||
if (IsA(tleA->expr, Param) && IsA(tleB->expr, Param))
|
||||
{
|
||||
int la = ((Param *) tleA->expr)->paramid;
|
||||
int lb = ((Param *) tleB->expr)->paramid;
|
||||
return (la > lb) - (la < lb);
|
||||
}
|
||||
else if ((IsA(tleA->expr, Param) && IsA(tleB->expr, SubLink)) ||
|
||||
(IsA(tleA->expr, SubLink) && IsA(tleB->expr, Param)) ||
|
||||
(IsA(tleA->expr, SubLink) && IsA(tleB->expr, SubLink)))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
elog(ERROR, "unexpected nodes");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Recursively search an expression for a Param and return its paramid
|
||||
* Intended for indirection management: UPDATE SET () = (SELECT )
|
||||
* Does not cover all options but those supported by Citus.
|
||||
*/
|
||||
int
|
||||
GetParamId(Node *expr)
|
||||
{
|
||||
int paramid = 0;
|
||||
|
||||
if (expr == NULL)
|
||||
{
|
||||
return paramid;
|
||||
}
|
||||
|
||||
/* If it's a Param, return its attnum */
|
||||
if (IsA(expr, Param))
|
||||
{
|
||||
Param *param = (Param *) expr;
|
||||
paramid = param->paramid;
|
||||
}
|
||||
/* If it's a FuncExpr, search in arguments */
|
||||
else if (IsA(expr, FuncExpr))
|
||||
{
|
||||
FuncExpr *func = (FuncExpr *) expr;
|
||||
ListCell *lc;
|
||||
|
||||
foreach(lc, func->args)
|
||||
{
|
||||
paramid = GetParamId((Node *) lfirst(lc));
|
||||
if (paramid != 0)
|
||||
{
|
||||
break; /* Stop at the first valid paramid */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return paramid;
|
||||
}
|
||||
|
|
|
@ -3525,9 +3525,6 @@ get_update_query_targetlist_def(Query *query, List *targetList,
|
|||
SubLink *cur_ma_sublink;
|
||||
List *ma_sublinks;
|
||||
|
||||
AttrNumber previous_attnum = InvalidAttrNumber;
|
||||
int paramid_increment = 0;
|
||||
|
||||
/*
|
||||
* Prepare to deal with MULTIEXPR assignments: collect the source SubLinks
|
||||
* into a list. We expect them to appear, in ID order, in resjunk tlist
|
||||
|
@ -3536,13 +3533,21 @@ get_update_query_targetlist_def(Query *query, List *targetList,
|
|||
ma_sublinks = NIL;
|
||||
if (query->hasSubLinks) /* else there can't be any */
|
||||
{
|
||||
bool saw_junk = false;
|
||||
bool need_to_sort_target_list = false;
|
||||
int previous_paramid = 0;
|
||||
|
||||
foreach(l, targetList)
|
||||
{
|
||||
TargetEntry *tle = (TargetEntry *) lfirst(l);
|
||||
|
||||
// elog(WARNING, "TOP node to string: %s", nodeToString(tle->expr));
|
||||
// elog(WARNING, "TOP node type: %d", (int) nodeTag(tle->expr));
|
||||
|
||||
if (tle->resjunk && IsA(tle->expr, SubLink))
|
||||
{
|
||||
SubLink *sl = (SubLink *) tle->expr;
|
||||
saw_junk = true;
|
||||
|
||||
if (sl->subLinkType == MULTIEXPR_SUBLINK)
|
||||
{
|
||||
|
@ -3550,8 +3555,31 @@ get_update_query_targetlist_def(Query *query, List *targetList,
|
|||
Assert(sl->subLinkId == list_length(ma_sublinks));
|
||||
}
|
||||
}
|
||||
else if (!tle->resjunk)
|
||||
{
|
||||
int paramid = 0;
|
||||
if (saw_junk)
|
||||
elog(ERROR, "out of order target list");
|
||||
|
||||
paramid = GetParamId((Node *) tle->expr);
|
||||
if (paramid < previous_paramid)
|
||||
need_to_sort_target_list = true;
|
||||
|
||||
previous_paramid = paramid;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* reorder the target list on left side of the update:
|
||||
* SET () = (SELECT )
|
||||
* reordering the SELECT side only does not work, consider a case like:
|
||||
* SET (col_1, col3) = (SELECT 1, 3), (col_2) = (SELECT 2)
|
||||
* Then default order will lead to:
|
||||
* SET (col_1, col2) = (SELECT 1, 3), (col_3) = (SELECT 2)
|
||||
*/
|
||||
if (need_to_sort_target_list)
|
||||
list_sort(targetList, target_list_cmp);
|
||||
}
|
||||
next_ma_cell = list_head(ma_sublinks);
|
||||
cur_ma_sublink = NULL;
|
||||
remaining_ma_columns = 0;
|
||||
|
@ -3650,54 +3678,18 @@ get_update_query_targetlist_def(Query *query, List *targetList,
|
|||
*/
|
||||
if (cur_ma_sublink != NULL)
|
||||
{
|
||||
AttrNumber attnum = InvalidAttrNumber;
|
||||
if (IsA(expr, Param))
|
||||
{
|
||||
Param *param = (Param *) expr;
|
||||
attnum = param->paramid + paramid_increment;
|
||||
}
|
||||
else if (IsA(expr, FuncExpr))
|
||||
{
|
||||
FuncExpr *func = (FuncExpr *) expr;
|
||||
ListCell *lc;
|
||||
|
||||
/* Iterate through the arguments of the FuncExpr */
|
||||
foreach(lc, func->args)
|
||||
{
|
||||
Node *arg = (Node *) lfirst(lc);
|
||||
|
||||
/* Check if the argument is a PARAM node */
|
||||
if (IsA(arg, Param))
|
||||
{
|
||||
Param *param = (Param *) arg;
|
||||
attnum = param->paramid + paramid_increment;
|
||||
|
||||
break; /* Exit loop once we find the PARAM node */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (previous_attnum >= attnum)
|
||||
ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
||||
errmsg(
|
||||
"cannot plan distributed UPDATE SET (..) = (SELECT ...) query when not sorted by physical order"),
|
||||
errhint("Sort the columns on the left side by physical order.")));
|
||||
|
||||
previous_attnum = attnum;
|
||||
|
||||
if (--remaining_ma_columns > 0)
|
||||
continue; /* not the last column of multiassignment */
|
||||
|
||||
appendStringInfoChar(buf, ')');
|
||||
expr = (Node *) cur_ma_sublink;
|
||||
cur_ma_sublink = NULL;
|
||||
paramid_increment = previous_attnum;
|
||||
}
|
||||
|
||||
appendStringInfoString(buf, " = ");
|
||||
|
||||
get_rule_expr(expr, context, false);
|
||||
}
|
||||
elog(DEBUG4, "rewriten query: %s", buf->data);
|
||||
}
|
||||
|
||||
/* ----------
|
||||
|
|
|
@ -60,5 +60,8 @@ extern char * generate_operator_name(Oid operid, Oid arg1, Oid arg2);
|
|||
extern List * getOwnedSequences_internal(Oid relid, AttrNumber attnum, char deptype);
|
||||
extern void AppendOptionListToString(StringInfo stringData, List *options);
|
||||
|
||||
extern int GetParamId(Node *expr);
|
||||
extern int target_list_cmp(const ListCell *a, const ListCell *b);
|
||||
|
||||
|
||||
#endif /* CITUS_RULEUTILS_H */
|
||||
|
|
|
@ -126,210 +126,303 @@ RETURNING *;
|
|||
(4 rows)
|
||||
|
||||
UPDATE test_ref_indirection
|
||||
SET (col_bool, col_date) = (select true, '1970-01-01'::date)
|
||||
, (col_int, col_text) = (select 1, 'still ok')
|
||||
SET (col_bool, col_date) = (select false, '1971-01-01'::date)
|
||||
, (col_int, col_text) = (select 2, '2 ok')
|
||||
RETURNING *;
|
||||
id | col_bool | col_date | col_int | col_text
|
||||
---------------------------------------------------------------------
|
||||
1 | t | 01-01-1970 | 1 | still ok
|
||||
2 | t | 01-01-1970 | 1 | still ok
|
||||
3 | t | 01-01-1970 | 1 | still ok
|
||||
4 | t | 01-01-1970 | 1 | still ok
|
||||
1 | f | 01-01-1971 | 2 | 2 ok
|
||||
2 | f | 01-01-1971 | 2 | 2 ok
|
||||
3 | f | 01-01-1971 | 2 | 2 ok
|
||||
4 | f | 01-01-1971 | 2 | 2 ok
|
||||
(4 rows)
|
||||
|
||||
UPDATE test_dist_indirection
|
||||
SET (col_bool, col_date) = (select true, '1970-01-01'::date)
|
||||
, (col_int, col_text) = (select 1, 'still ok')
|
||||
SET (col_bool, col_date) = (select false, '1971-01-01'::date)
|
||||
, (col_int, col_text) = (select 2, '2 ok')
|
||||
RETURNING *;
|
||||
id | col_bool | col_date | col_int | col_text
|
||||
---------------------------------------------------------------------
|
||||
1 | t | 01-01-1970 | 1 | still ok
|
||||
2 | t | 01-01-1970 | 1 | still ok
|
||||
3 | t | 01-01-1970 | 1 | still ok
|
||||
4 | t | 01-01-1970 | 1 | still ok
|
||||
1 | f | 01-01-1971 | 2 | 2 ok
|
||||
2 | f | 01-01-1971 | 2 | 2 ok
|
||||
3 | f | 01-01-1971 | 2 | 2 ok
|
||||
4 | f | 01-01-1971 | 2 | 2 ok
|
||||
(4 rows)
|
||||
|
||||
UPDATE test_ref_indirection
|
||||
SET (col_bool, col_int) = (select true, 1)
|
||||
, (col_text) = (select 'ok')
|
||||
SET (col_bool, col_int) = (select true, 3)
|
||||
, (col_text) = (select '3 ok')
|
||||
RETURNING *;
|
||||
id | col_bool | col_date | col_int | col_text
|
||||
---------------------------------------------------------------------
|
||||
1 | t | 01-01-1970 | 1 | ok
|
||||
2 | t | 01-01-1970 | 1 | ok
|
||||
3 | t | 01-01-1970 | 1 | ok
|
||||
4 | t | 01-01-1970 | 1 | ok
|
||||
1 | t | 01-01-1971 | 3 | 3 ok
|
||||
2 | t | 01-01-1971 | 3 | 3 ok
|
||||
3 | t | 01-01-1971 | 3 | 3 ok
|
||||
4 | t | 01-01-1971 | 3 | 3 ok
|
||||
(4 rows)
|
||||
|
||||
SELECT * FROM test_ref_indirection ORDER BY id;
|
||||
UPDATE test_dist_indirection
|
||||
SET (col_bool, col_int) = (select true, 3)
|
||||
, (col_text) = (select '3 ok')
|
||||
RETURNING *;
|
||||
id | col_bool | col_date | col_int | col_text
|
||||
---------------------------------------------------------------------
|
||||
1 | t | 01-01-1970 | 1 | ok
|
||||
2 | t | 01-01-1970 | 1 | ok
|
||||
3 | t | 01-01-1970 | 1 | ok
|
||||
4 | t | 01-01-1970 | 1 | ok
|
||||
1 | t | 01-01-1971 | 3 | 3 ok
|
||||
2 | t | 01-01-1971 | 3 | 3 ok
|
||||
3 | t | 01-01-1971 | 3 | 3 ok
|
||||
4 | t | 01-01-1971 | 3 | 3 ok
|
||||
(4 rows)
|
||||
|
||||
SELECT * FROM test_dist_indirection ORDER BY id;
|
||||
id | col_bool | col_date | col_int | col_text
|
||||
---------------------------------------------------------------------
|
||||
1 | t | 01-01-1970 | 1 | still ok
|
||||
2 | t | 01-01-1970 | 1 | still ok
|
||||
3 | t | 01-01-1970 | 1 | still ok
|
||||
4 | t | 01-01-1970 | 1 | still ok
|
||||
(4 rows)
|
||||
|
||||
-- but those should not:
|
||||
-- but those should work since 13.X
|
||||
UPDATE test_ref_indirection
|
||||
SET (col_date, col_text, col_int, col_bool)
|
||||
= (SELECT '1970-06-06'::date, 'not ok', 2, false)
|
||||
= (SELECT '1972-01-01'::date, '4 ok', 4, false)
|
||||
RETURNING *;
|
||||
ERROR: cannot plan distributed UPDATE SET (..) = (SELECT ...) query when not sorted by physical order
|
||||
HINT: Sort the columns on the left side by physical order.
|
||||
id | col_bool | col_date | col_int | col_text
|
||||
---------------------------------------------------------------------
|
||||
1 | f | 01-01-1972 | 4 | 4 ok
|
||||
2 | f | 01-01-1972 | 4 | 4 ok
|
||||
3 | f | 01-01-1972 | 4 | 4 ok
|
||||
4 | f | 01-01-1972 | 4 | 4 ok
|
||||
(4 rows)
|
||||
|
||||
UPDATE test_dist_indirection
|
||||
SET (col_date, col_text, col_int, col_bool)
|
||||
= (SELECT '1970-06-06'::date, 'not ok', 2, false)
|
||||
= (SELECT '1972-01-01'::date, '4 ok', 4, false)
|
||||
RETURNING *;
|
||||
ERROR: cannot plan distributed UPDATE SET (..) = (SELECT ...) query when not sorted by physical order
|
||||
HINT: Sort the columns on the left side by physical order.
|
||||
id | col_bool | col_date | col_int | col_text
|
||||
---------------------------------------------------------------------
|
||||
1 | f | 01-01-1972 | 4 | 4 ok
|
||||
2 | f | 01-01-1972 | 4 | 4 ok
|
||||
3 | f | 01-01-1972 | 4 | 4 ok
|
||||
4 | f | 01-01-1972 | 4 | 4 ok
|
||||
(4 rows)
|
||||
|
||||
UPDATE test_ref_indirection
|
||||
SET (col_int, col_text) = (select 2, 'not ok')
|
||||
SET (col_int, col_text) = (select 5, '5 ok')
|
||||
, (col_bool) = (select true)
|
||||
RETURNING *;
|
||||
id | col_bool | col_date | col_int | col_text
|
||||
---------------------------------------------------------------------
|
||||
1 | t | 01-01-1972 | 5 | 5 ok
|
||||
2 | t | 01-01-1972 | 5 | 5 ok
|
||||
3 | t | 01-01-1972 | 5 | 5 ok
|
||||
4 | t | 01-01-1972 | 5 | 5 ok
|
||||
(4 rows)
|
||||
|
||||
UPDATE test_dist_indirection
|
||||
SET (col_int, col_text) = (select 5, '5 ok')
|
||||
, (col_bool) = (select true)
|
||||
RETURNING *;
|
||||
id | col_bool | col_date | col_int | col_text
|
||||
---------------------------------------------------------------------
|
||||
1 | t | 01-01-1972 | 5 | 5 ok
|
||||
2 | t | 01-01-1972 | 5 | 5 ok
|
||||
3 | t | 01-01-1972 | 5 | 5 ok
|
||||
4 | t | 01-01-1972 | 5 | 5 ok
|
||||
(4 rows)
|
||||
|
||||
UPDATE test_ref_indirection
|
||||
SET (col_int, col_date) = (select 6, '1973-01-01'::date)
|
||||
, (col_text, col_bool) = (select '6 ok', false)
|
||||
RETURNING *;
|
||||
id | col_bool | col_date | col_int | col_text
|
||||
---------------------------------------------------------------------
|
||||
1 | f | 01-01-1973 | 6 | 6 ok
|
||||
2 | f | 01-01-1973 | 6 | 6 ok
|
||||
3 | f | 01-01-1973 | 6 | 6 ok
|
||||
4 | f | 01-01-1973 | 6 | 6 ok
|
||||
(4 rows)
|
||||
|
||||
UPDATE test_dist_indirection
|
||||
SET (col_int, col_date) = (select 6, '1973-01-01'::date)
|
||||
, (col_text, col_bool) = (select '6 ok', false)
|
||||
RETURNING *;
|
||||
id | col_bool | col_date | col_int | col_text
|
||||
---------------------------------------------------------------------
|
||||
1 | f | 01-01-1973 | 6 | 6 ok
|
||||
2 | f | 01-01-1973 | 6 | 6 ok
|
||||
3 | f | 01-01-1973 | 6 | 6 ok
|
||||
4 | f | 01-01-1973 | 6 | 6 ok
|
||||
(4 rows)
|
||||
|
||||
UPDATE test_ref_indirection
|
||||
SET (col_int, col_date, col_text) = (select 7, '1974-01-01'::date, '7 ok')
|
||||
, (col_bool) = (select true)
|
||||
RETURNING *;
|
||||
id | col_bool | col_date | col_int | col_text
|
||||
---------------------------------------------------------------------
|
||||
1 | t | 01-01-1974 | 7 | 7 ok
|
||||
2 | t | 01-01-1974 | 7 | 7 ok
|
||||
3 | t | 01-01-1974 | 7 | 7 ok
|
||||
4 | t | 01-01-1974 | 7 | 7 ok
|
||||
(4 rows)
|
||||
|
||||
UPDATE test_dist_indirection
|
||||
SET (col_int, col_date, col_text) = (select 7, '1974-01-01'::date, '7 ok')
|
||||
, (col_bool) = (select true)
|
||||
RETURNING *;
|
||||
id | col_bool | col_date | col_int | col_text
|
||||
---------------------------------------------------------------------
|
||||
1 | t | 01-01-1974 | 7 | 7 ok
|
||||
2 | t | 01-01-1974 | 7 | 7 ok
|
||||
3 | t | 01-01-1974 | 7 | 7 ok
|
||||
4 | t | 01-01-1974 | 7 | 7 ok
|
||||
(4 rows)
|
||||
|
||||
UPDATE test_ref_indirection
|
||||
SET (col_date, col_text) = (select '1975-01-01'::date, '8 ok')
|
||||
, (col_int) = (select 8)
|
||||
, (col_bool) = (select false)
|
||||
RETURNING *;
|
||||
ERROR: cannot plan distributed UPDATE SET (..) = (SELECT ...) query when not sorted by physical order
|
||||
HINT: Sort the columns on the left side by physical order.
|
||||
UPDATE test_ref_indirection
|
||||
SET (col_int, col_date) = (select 2, '1970-06-06'::date)
|
||||
, (col_text, col_bool) = (select 'not ok', false)
|
||||
RETURNING *;
|
||||
ERROR: cannot plan distributed UPDATE SET (..) = (SELECT ...) query when not sorted by physical order
|
||||
HINT: Sort the columns on the left side by physical order.
|
||||
id | col_bool | col_date | col_int | col_text
|
||||
---------------------------------------------------------------------
|
||||
1 | f | 01-01-1975 | 8 | 8 ok
|
||||
2 | f | 01-01-1975 | 8 | 8 ok
|
||||
3 | f | 01-01-1975 | 8 | 8 ok
|
||||
4 | f | 01-01-1975 | 8 | 8 ok
|
||||
(4 rows)
|
||||
|
||||
UPDATE test_dist_indirection
|
||||
SET (col_int, col_date) = (select 2, '1970-06-06'::date)
|
||||
, (col_text, col_bool) = (select 'not ok', false)
|
||||
SET (col_date, col_text) = (select '1975-01-01'::date, '8 ok')
|
||||
, (col_int) = (select 8)
|
||||
, (col_bool) = (select false)
|
||||
RETURNING *;
|
||||
ERROR: cannot plan distributed UPDATE SET (..) = (SELECT ...) query when not sorted by physical order
|
||||
HINT: Sort the columns on the left side by physical order.
|
||||
id | col_bool | col_date | col_int | col_text
|
||||
---------------------------------------------------------------------
|
||||
1 | f | 01-01-1975 | 8 | 8 ok
|
||||
2 | f | 01-01-1975 | 8 | 8 ok
|
||||
3 | f | 01-01-1975 | 8 | 8 ok
|
||||
4 | f | 01-01-1975 | 8 | 8 ok
|
||||
(4 rows)
|
||||
|
||||
--
|
||||
-- more restrictive ones, just in case we miss a wrong value
|
||||
--
|
||||
-- those should work
|
||||
UPDATE test_ref_indirection
|
||||
SET (col_bool, col_text) = (SELECT true, 'ok')
|
||||
SET (col_bool, col_text) = (SELECT true, '9 ok')
|
||||
RETURNING *;
|
||||
id | col_bool | col_date | col_int | col_text
|
||||
---------------------------------------------------------------------
|
||||
1 | t | 01-01-1970 | 1 | ok
|
||||
2 | t | 01-01-1970 | 1 | ok
|
||||
3 | t | 01-01-1970 | 1 | ok
|
||||
4 | t | 01-01-1970 | 1 | ok
|
||||
1 | t | 01-01-1975 | 8 | 9 ok
|
||||
2 | t | 01-01-1975 | 8 | 9 ok
|
||||
3 | t | 01-01-1975 | 8 | 9 ok
|
||||
4 | t | 01-01-1975 | 8 | 9 ok
|
||||
(4 rows)
|
||||
|
||||
UPDATE test_dist_indirection
|
||||
SET (col_bool, col_text) = (SELECT true, 'ok')
|
||||
SET (col_bool, col_text) = (SELECT true, '9 ok')
|
||||
RETURNING *;
|
||||
id | col_bool | col_date | col_int | col_text
|
||||
---------------------------------------------------------------------
|
||||
1 | t | 01-01-1970 | 1 | ok
|
||||
2 | t | 01-01-1970 | 1 | ok
|
||||
3 | t | 01-01-1970 | 1 | ok
|
||||
4 | t | 01-01-1970 | 1 | ok
|
||||
1 | t | 01-01-1975 | 8 | 9 ok
|
||||
2 | t | 01-01-1975 | 8 | 9 ok
|
||||
3 | t | 01-01-1975 | 8 | 9 ok
|
||||
4 | t | 01-01-1975 | 8 | 9 ok
|
||||
(4 rows)
|
||||
|
||||
UPDATE test_ref_indirection
|
||||
SET (col_bool, col_text) = (SELECT true, 'ok')
|
||||
SET (col_bool, col_text) = (SELECT false, '10 ok')
|
||||
WHERE id = 1
|
||||
RETURNING *;
|
||||
id | col_bool | col_date | col_int | col_text
|
||||
---------------------------------------------------------------------
|
||||
1 | t | 01-01-1970 | 1 | ok
|
||||
1 | f | 01-01-1975 | 8 | 10 ok
|
||||
(1 row)
|
||||
|
||||
UPDATE test_dist_indirection
|
||||
SET (col_bool, col_text) = (SELECT true, 'ok')
|
||||
SET (col_bool, col_text) = (SELECT false, '10 ok')
|
||||
WHERE id = 1
|
||||
RETURNING *;
|
||||
id | col_bool | col_date | col_int | col_text
|
||||
---------------------------------------------------------------------
|
||||
1 | t | 01-01-1970 | 1 | ok
|
||||
1 | f | 01-01-1975 | 8 | 10 ok
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM test_ref_indirection ORDER BY id;
|
||||
UPDATE test_ref_indirection
|
||||
SET (col_text, col_bool) = (SELECT '11 ok', true)
|
||||
RETURNING *;
|
||||
id | col_bool | col_date | col_int | col_text
|
||||
---------------------------------------------------------------------
|
||||
1 | t | 01-01-1970 | 1 | ok
|
||||
2 | t | 01-01-1970 | 1 | ok
|
||||
3 | t | 01-01-1970 | 1 | ok
|
||||
4 | t | 01-01-1970 | 1 | ok
|
||||
1 | t | 01-01-1975 | 8 | 11 ok
|
||||
2 | t | 01-01-1975 | 8 | 11 ok
|
||||
3 | t | 01-01-1975 | 8 | 11 ok
|
||||
4 | t | 01-01-1975 | 8 | 11 ok
|
||||
(4 rows)
|
||||
|
||||
SELECT * FROM test_dist_indirection ORDER BY id;
|
||||
UPDATE test_dist_indirection
|
||||
SET (col_text, col_bool) = (SELECT '11 ok', true)
|
||||
RETURNING *;
|
||||
id | col_bool | col_date | col_int | col_text
|
||||
---------------------------------------------------------------------
|
||||
1 | t | 01-01-1970 | 1 | ok
|
||||
2 | t | 01-01-1970 | 1 | ok
|
||||
3 | t | 01-01-1970 | 1 | ok
|
||||
4 | t | 01-01-1970 | 1 | ok
|
||||
1 | t | 01-01-1975 | 8 | 11 ok
|
||||
2 | t | 01-01-1975 | 8 | 11 ok
|
||||
3 | t | 01-01-1975 | 8 | 11 ok
|
||||
4 | t | 01-01-1975 | 8 | 11 ok
|
||||
(4 rows)
|
||||
|
||||
-- those should not
|
||||
UPDATE test_ref_indirection
|
||||
SET (col_text, col_bool) = (SELECT 'not ok', false)
|
||||
RETURNING *;
|
||||
ERROR: cannot plan distributed UPDATE SET (..) = (SELECT ...) query when not sorted by physical order
|
||||
HINT: Sort the columns on the left side by physical order.
|
||||
UPDATE test_dist_indirection
|
||||
SET (col_text, col_bool) = (SELECT 'not ok', false)
|
||||
RETURNING *;
|
||||
ERROR: cannot plan distributed UPDATE SET (..) = (SELECT ...) query when not sorted by physical order
|
||||
HINT: Sort the columns on the left side by physical order.
|
||||
UPDATE test_ref_indirection
|
||||
SET (col_text, col_bool) = (SELECT 'not ok', false)
|
||||
SET (col_text, col_bool) = (SELECT '12 ok', false)
|
||||
WHERE id = 2
|
||||
RETURNING *;
|
||||
ERROR: cannot plan distributed UPDATE SET (..) = (SELECT ...) query when not sorted by physical order
|
||||
HINT: Sort the columns on the left side by physical order.
|
||||
id | col_bool | col_date | col_int | col_text
|
||||
---------------------------------------------------------------------
|
||||
2 | f | 01-01-1975 | 8 | 12 ok
|
||||
(1 row)
|
||||
|
||||
UPDATE test_dist_indirection
|
||||
SET (col_text, col_bool) = (SELECT 'not ok', false)
|
||||
SET (col_text, col_bool) = (SELECT '12 ok', false)
|
||||
WHERE id = 2
|
||||
RETURNING *;
|
||||
ERROR: cannot plan distributed UPDATE SET (..) = (SELECT ...) query when not sorted by physical order
|
||||
HINT: Sort the columns on the left side by physical order.
|
||||
id | col_bool | col_date | col_int | col_text
|
||||
---------------------------------------------------------------------
|
||||
2 | f | 01-01-1975 | 8 | 12 ok
|
||||
(1 row)
|
||||
|
||||
-- several updates in CTE shoult not work
|
||||
with qq3 as (
|
||||
update test_ref_indirection
|
||||
SET (col_text, col_bool)
|
||||
= (SELECT 'full', true)
|
||||
= (SELECT '13', true)
|
||||
where id = 3
|
||||
returning *
|
||||
),
|
||||
qq4 as (
|
||||
update test_ref_indirection
|
||||
SET (col_text, col_bool)
|
||||
= (SELECT 'fully', true)
|
||||
= (SELECT '14', false)
|
||||
where id = 4
|
||||
returning *
|
||||
)
|
||||
select * from qq3 union all select * from qq4;
|
||||
ERROR: cannot plan distributed UPDATE SET (..) = (SELECT ...) query when not sorted by physical order
|
||||
HINT: Sort the columns on the left side by physical order.
|
||||
id | col_bool | col_date | col_int | col_text
|
||||
---------------------------------------------------------------------
|
||||
3 | t | 01-01-1975 | 8 | 13
|
||||
4 | f | 01-01-1975 | 8 | 14
|
||||
(2 rows)
|
||||
|
||||
with qq3 as (
|
||||
update test_dist_indirection
|
||||
SET (col_text, col_bool)
|
||||
= (SELECT 'full', true)
|
||||
= (SELECT '13', true)
|
||||
where id = 3
|
||||
returning *
|
||||
),
|
||||
qq4 as (
|
||||
update test_dist_indirection
|
||||
SET (col_text, col_bool)
|
||||
= (SELECT 'fully', true)
|
||||
= (SELECT '14', false)
|
||||
where id = 4
|
||||
returning *
|
||||
)
|
||||
select * from qq3 union all select * from qq4;
|
||||
ERROR: cannot plan distributed UPDATE SET (..) = (SELECT ...) query when not sorted by physical order
|
||||
HINT: Sort the columns on the left side by physical order.
|
||||
id | col_bool | col_date | col_int | col_text
|
||||
---------------------------------------------------------------------
|
||||
3 | t | 01-01-1975 | 8 | 13
|
||||
4 | f | 01-01-1975 | 8 | 14
|
||||
(2 rows)
|
||||
|
||||
DROP TABLE test_dist_indirection;
|
||||
DROP TABLE test_dist_indirection_new;
|
||||
DROP TABLE test_ref_indirection;
|
||||
|
@ -349,10 +442,6 @@ SELECT create_reference_table('indirections.update_test');
|
|||
UPDATE update_test
|
||||
SET (b,a) = (select a,b from update_test where b = 41 and c = 'car')
|
||||
WHERE a = 100 AND b = 20;
|
||||
ERROR: cannot plan distributed UPDATE SET (..) = (SELECT ...) query when not sorted by physical order
|
||||
HINT: Sort the columns on the left side by physical order.
|
||||
-- https://github.com/citusdata/citus/pull/5692
|
||||
set client_min_messages to ERROR;
|
||||
DROP SCHEMA indirections CASCADE;
|
||||
NOTICE: drop cascades to 2 other objects
|
||||
DETAIL: drop cascades to table update_test
|
||||
drop cascades to table update_test_750006
|
||||
|
|
|
@ -73,43 +73,69 @@ UPDATE test_dist_indirection
|
|||
RETURNING *;
|
||||
|
||||
UPDATE test_ref_indirection
|
||||
SET (col_bool, col_date) = (select true, '1970-01-01'::date)
|
||||
, (col_int, col_text) = (select 1, 'still ok')
|
||||
SET (col_bool, col_date) = (select false, '1971-01-01'::date)
|
||||
, (col_int, col_text) = (select 2, '2 ok')
|
||||
RETURNING *;
|
||||
UPDATE test_dist_indirection
|
||||
SET (col_bool, col_date) = (select true, '1970-01-01'::date)
|
||||
, (col_int, col_text) = (select 1, 'still ok')
|
||||
SET (col_bool, col_date) = (select false, '1971-01-01'::date)
|
||||
, (col_int, col_text) = (select 2, '2 ok')
|
||||
RETURNING *;
|
||||
|
||||
UPDATE test_ref_indirection
|
||||
SET (col_bool, col_int) = (select true, 1)
|
||||
, (col_text) = (select 'ok')
|
||||
SET (col_bool, col_int) = (select true, 3)
|
||||
, (col_text) = (select '3 ok')
|
||||
RETURNING *;
|
||||
UPDATE test_dist_indirection
|
||||
SET (col_bool, col_int) = (select true, 3)
|
||||
, (col_text) = (select '3 ok')
|
||||
RETURNING *;
|
||||
|
||||
SELECT * FROM test_ref_indirection ORDER BY id;
|
||||
SELECT * FROM test_dist_indirection ORDER BY id;
|
||||
|
||||
-- but those should not:
|
||||
-- but those should work since 13.X
|
||||
UPDATE test_ref_indirection
|
||||
SET (col_date, col_text, col_int, col_bool)
|
||||
= (SELECT '1970-06-06'::date, 'not ok', 2, false)
|
||||
= (SELECT '1972-01-01'::date, '4 ok', 4, false)
|
||||
RETURNING *;
|
||||
UPDATE test_dist_indirection
|
||||
SET (col_date, col_text, col_int, col_bool)
|
||||
= (SELECT '1970-06-06'::date, 'not ok', 2, false)
|
||||
= (SELECT '1972-01-01'::date, '4 ok', 4, false)
|
||||
RETURNING *;
|
||||
|
||||
UPDATE test_ref_indirection
|
||||
SET (col_int, col_text) = (select 2, 'not ok')
|
||||
SET (col_int, col_text) = (select 5, '5 ok')
|
||||
, (col_bool) = (select true)
|
||||
RETURNING *;
|
||||
UPDATE test_dist_indirection
|
||||
SET (col_int, col_text) = (select 5, '5 ok')
|
||||
, (col_bool) = (select true)
|
||||
RETURNING *;
|
||||
|
||||
UPDATE test_ref_indirection
|
||||
SET (col_int, col_date) = (select 6, '1973-01-01'::date)
|
||||
, (col_text, col_bool) = (select '6 ok', false)
|
||||
RETURNING *;
|
||||
UPDATE test_dist_indirection
|
||||
SET (col_int, col_date) = (select 6, '1973-01-01'::date)
|
||||
, (col_text, col_bool) = (select '6 ok', false)
|
||||
RETURNING *;
|
||||
|
||||
UPDATE test_ref_indirection
|
||||
SET (col_int, col_date, col_text) = (select 7, '1974-01-01'::date, '7 ok')
|
||||
, (col_bool) = (select true)
|
||||
RETURNING *;
|
||||
UPDATE test_dist_indirection
|
||||
SET (col_int, col_date, col_text) = (select 7, '1974-01-01'::date, '7 ok')
|
||||
, (col_bool) = (select true)
|
||||
RETURNING *;
|
||||
|
||||
UPDATE test_ref_indirection
|
||||
SET (col_date, col_text) = (select '1975-01-01'::date, '8 ok')
|
||||
, (col_int) = (select 8)
|
||||
, (col_bool) = (select false)
|
||||
RETURNING *;
|
||||
UPDATE test_ref_indirection
|
||||
SET (col_int, col_date) = (select 2, '1970-06-06'::date)
|
||||
, (col_text, col_bool) = (select 'not ok', false)
|
||||
RETURNING *;
|
||||
UPDATE test_dist_indirection
|
||||
SET (col_int, col_date) = (select 2, '1970-06-06'::date)
|
||||
, (col_text, col_bool) = (select 'not ok', false)
|
||||
SET (col_date, col_text) = (select '1975-01-01'::date, '8 ok')
|
||||
, (col_int) = (select 8)
|
||||
, (col_bool) = (select false)
|
||||
RETURNING *;
|
||||
|
||||
--
|
||||
|
@ -117,38 +143,34 @@ RETURNING *;
|
|||
--
|
||||
-- those should work
|
||||
UPDATE test_ref_indirection
|
||||
SET (col_bool, col_text) = (SELECT true, 'ok')
|
||||
SET (col_bool, col_text) = (SELECT true, '9 ok')
|
||||
RETURNING *;
|
||||
UPDATE test_dist_indirection
|
||||
SET (col_bool, col_text) = (SELECT true, 'ok')
|
||||
SET (col_bool, col_text) = (SELECT true, '9 ok')
|
||||
RETURNING *;
|
||||
|
||||
UPDATE test_ref_indirection
|
||||
SET (col_bool, col_text) = (SELECT true, 'ok')
|
||||
SET (col_bool, col_text) = (SELECT false, '10 ok')
|
||||
WHERE id = 1
|
||||
RETURNING *;
|
||||
UPDATE test_dist_indirection
|
||||
SET (col_bool, col_text) = (SELECT true, 'ok')
|
||||
SET (col_bool, col_text) = (SELECT false, '10 ok')
|
||||
WHERE id = 1
|
||||
RETURNING *;
|
||||
|
||||
SELECT * FROM test_ref_indirection ORDER BY id;
|
||||
SELECT * FROM test_dist_indirection ORDER BY id;
|
||||
|
||||
-- those should not
|
||||
UPDATE test_ref_indirection
|
||||
SET (col_text, col_bool) = (SELECT 'not ok', false)
|
||||
SET (col_text, col_bool) = (SELECT '11 ok', true)
|
||||
RETURNING *;
|
||||
UPDATE test_dist_indirection
|
||||
SET (col_text, col_bool) = (SELECT 'not ok', false)
|
||||
SET (col_text, col_bool) = (SELECT '11 ok', true)
|
||||
RETURNING *;
|
||||
|
||||
UPDATE test_ref_indirection
|
||||
SET (col_text, col_bool) = (SELECT 'not ok', false)
|
||||
SET (col_text, col_bool) = (SELECT '12 ok', false)
|
||||
WHERE id = 2
|
||||
RETURNING *;
|
||||
UPDATE test_dist_indirection
|
||||
SET (col_text, col_bool) = (SELECT 'not ok', false)
|
||||
SET (col_text, col_bool) = (SELECT '12 ok', false)
|
||||
WHERE id = 2
|
||||
RETURNING *;
|
||||
|
||||
|
@ -156,14 +178,14 @@ RETURNING *;
|
|||
with qq3 as (
|
||||
update test_ref_indirection
|
||||
SET (col_text, col_bool)
|
||||
= (SELECT 'full', true)
|
||||
= (SELECT '13', true)
|
||||
where id = 3
|
||||
returning *
|
||||
),
|
||||
qq4 as (
|
||||
update test_ref_indirection
|
||||
SET (col_text, col_bool)
|
||||
= (SELECT 'fully', true)
|
||||
= (SELECT '14', false)
|
||||
where id = 4
|
||||
returning *
|
||||
)
|
||||
|
@ -171,14 +193,14 @@ select * from qq3 union all select * from qq4;
|
|||
with qq3 as (
|
||||
update test_dist_indirection
|
||||
SET (col_text, col_bool)
|
||||
= (SELECT 'full', true)
|
||||
= (SELECT '13', true)
|
||||
where id = 3
|
||||
returning *
|
||||
),
|
||||
qq4 as (
|
||||
update test_dist_indirection
|
||||
SET (col_text, col_bool)
|
||||
= (SELECT 'fully', true)
|
||||
= (SELECT '14', false)
|
||||
where id = 4
|
||||
returning *
|
||||
)
|
||||
|
@ -201,5 +223,6 @@ SET (b,a) = (select a,b from update_test where b = 41 and c = 'car')
|
|||
WHERE a = 100 AND b = 20;
|
||||
|
||||
-- https://github.com/citusdata/citus/pull/5692
|
||||
|
||||
set client_min_messages to ERROR;
|
||||
DROP SCHEMA indirections CASCADE;
|
||||
|
||||
|
|
Loading…
Reference in New Issue