Add alias for target in multi-row INSERTs

This is necessary for multi-row INSERTs for the same reasons we use it
in e.g. UPSERTs: if the range table list has more than one entry, then
PostgreSQL's deparse logic requires that vars be prefixed by the name
of their corresponding range table entry. This of course doesn't affect
single-row INSERTs, but since multi-row INSERTs have a VALUE RTE, they
were affected.

The piece of ruleutils which builds range table names wasn't modified
to handle shard extension; instead UPSERT/INSERT INTO ... SELECT added
an alias to the RTE. When present, this alias is favored. Doing the
same in the multi-row INSERT case fixes RETURNING for such commands.
pull/1600/head
Jason Petersen 2017-08-18 17:08:46 -06:00 committed by Marco Slot
parent ad1fbbe186
commit 8cb69e3a14
5 changed files with 21 additions and 8 deletions

View File

@ -82,11 +82,15 @@ RebuildQueryStrings(Query *originalQuery, List *taskList)
UpdateRelationToShardNames((Node *) copiedSubquery, relationShardList);
}
else if (task->upsertQuery)
else if (task->upsertQuery || valuesRTE != NULL)
{
RangeTblEntry *rangeTableEntry = NULL;
/* setting an alias simplifies deparsing of UPSERTs */
/*
* Always an alias in UPSERTs and multi-row INSERTs to avoid
* deparsing issues (e.g. RETURNING might reference the original
* table name, which has been replaced by a shard name).
*/
rangeTableEntry = linitial(query->rtable);
if (rangeTableEntry->alias == NULL)
{

View File

@ -305,7 +305,7 @@ Custom Scan (Citus Router)
Tasks Shown: All
-> Task
Node: host=localhost port=57638 dbname=regression
-> Insert on lineitem_290000
-> Insert on lineitem_290000 citus_table_alias
-> Values Scan on "*VALUES*"
-- Test update
EXPLAIN (COSTS FALSE)

View File

@ -305,7 +305,7 @@ Custom Scan (Citus Router)
Tasks Shown: All
-> Task
Node: host=localhost port=57638 dbname=regression
-> Insert on lineitem_290000
-> Insert on lineitem_290000 citus_table_alias
-> Values Scan on "*VALUES*"
-- Test update
EXPLAIN (COSTS FALSE)

View File

@ -211,10 +211,18 @@ SELECT COUNT(*) FROM limit_orders WHERE id BETWEEN 12037 AND 12039;
3
(1 row)
-- even those with functions
-- even those with functions and returning
INSERT INTO limit_orders VALUES (22037, 'GOOG', 5634, now(), 'buy', 0.50),
(22038, 'GOOG', 5634, now(), 'buy', 2.50),
(22039, 'GOOG', 5634, now(), 'buy', 1.50);
(22039, 'GOOG', 5634, now(), 'buy', 1.50)
RETURNING id;
id
-------
22038
22039
22037
(3 rows)
SELECT COUNT(*) FROM limit_orders WHERE id BETWEEN 22037 AND 22039;
count
-------

View File

@ -153,10 +153,11 @@ INSERT INTO limit_orders VALUES (12037, 'GOOG', 5634, '2001-04-16 03:37:28', 'bu
SELECT COUNT(*) FROM limit_orders WHERE id BETWEEN 12037 AND 12039;
-- even those with functions
-- even those with functions and returning
INSERT INTO limit_orders VALUES (22037, 'GOOG', 5634, now(), 'buy', 0.50),
(22038, 'GOOG', 5634, now(), 'buy', 2.50),
(22039, 'GOOG', 5634, now(), 'buy', 1.50);
(22039, 'GOOG', 5634, now(), 'buy', 1.50)
RETURNING id;
SELECT COUNT(*) FROM limit_orders WHERE id BETWEEN 22037 AND 22039;