Merge pull request #2569 from citusdata/fix_having_with_joins

Fix having clause bug for complex joins
pull/2578/head
Murat Tuncer 2019-01-04 13:32:28 +03:00 committed by GitHub
commit cb77fcce85
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 52 additions and 29 deletions

View File

@ -106,6 +106,8 @@ static RangeTblEntry * DerivedRangeTableEntry(MultiNode *multiNode, List *column
List *tableIdList); List *tableIdList);
static List * DerivedColumnNameList(uint32 columnCount, uint64 generatingJobId); static List * DerivedColumnNameList(uint32 columnCount, uint64 generatingJobId);
static Query * BuildSubqueryJobQuery(MultiNode *multiNode); static Query * BuildSubqueryJobQuery(MultiNode *multiNode);
static void UpdateAllColumnAttributes(Node *columnContainer, List *rangeTableList,
List *dependedJobList);
static void UpdateColumnAttributes(Var *column, List *rangeTableList, static void UpdateColumnAttributes(Var *column, List *rangeTableList,
List *dependedJobList); List *dependedJobList);
static Index NewTableId(Index originalTableId, List *rangeTableList); static Index NewTableId(Index originalTableId, List *rangeTableList);
@ -579,10 +581,8 @@ BuildJobQuery(MultiNode *multiNode, List *dependedJobList)
List *sortClauseList = NIL; List *sortClauseList = NIL;
List *groupClauseList = NIL; List *groupClauseList = NIL;
List *selectClauseList = NIL; List *selectClauseList = NIL;
List *columnList = NIL;
Node *limitCount = NULL; Node *limitCount = NULL;
Node *limitOffset = NULL; Node *limitOffset = NULL;
ListCell *columnCell = NULL;
FromExpr *joinTree = NULL; FromExpr *joinTree = NULL;
Node *joinRoot = NULL; Node *joinRoot = NULL;
Node *havingQual = NULL; Node *havingQual = NULL;
@ -650,13 +650,7 @@ BuildJobQuery(MultiNode *multiNode, List *dependedJobList)
/* update the column attributes for target entries */ /* update the column attributes for target entries */
if (updateColumnAttributes) if (updateColumnAttributes)
{ {
ListCell *columnCell = NULL; UpdateAllColumnAttributes((Node *) targetList, rangeTableList, dependedJobList);
List *columnList = pull_var_clause_default((Node *) targetList);
foreach(columnCell, columnList)
{
Var *column = (Var *) lfirst(columnCell);
UpdateColumnAttributes(column, rangeTableList, dependedJobList);
}
} }
/* extract limit count/offset and sort clauses */ /* extract limit count/offset and sort clauses */
@ -676,16 +670,12 @@ BuildJobQuery(MultiNode *multiNode, List *dependedJobList)
/* build the where clause list using select predicates */ /* build the where clause list using select predicates */
selectClauseList = QuerySelectClauseList(multiNode); selectClauseList = QuerySelectClauseList(multiNode);
/* set correct column attributes for select columns */ /* set correct column attributes for select and having clauses */
if (updateColumnAttributes) if (updateColumnAttributes)
{ {
columnCell = NULL; UpdateAllColumnAttributes((Node *) selectClauseList, rangeTableList,
columnList = pull_var_clause_default((Node *) selectClauseList); dependedJobList);
foreach(columnCell, columnList) UpdateAllColumnAttributes(havingQual, rangeTableList, dependedJobList);
{
Var *column = (Var *) lfirst(columnCell);
UpdateColumnAttributes(column, rangeTableList, dependedJobList);
}
} }
/* /*
@ -1526,6 +1516,25 @@ BuildSubqueryJobQuery(MultiNode *multiNode)
} }
/*
* UpdateAllColumnAttributes extracts column references from provided columnContainer
* and calls UpdateColumnAttributes to updates the column's range table reference (varno) and
* column attribute number for the range table (varattno).
*/
static void
UpdateAllColumnAttributes(Node *columnContainer, List *rangeTableList,
List *dependedJobList)
{
ListCell *columnCell = NULL;
List *columnList = pull_var_clause_default(columnContainer);
foreach(columnCell, columnList)
{
Var *column = (Var *) lfirst(columnCell);
UpdateColumnAttributes(column, rangeTableList, dependedJobList);
}
}
/* /*
* UpdateColumnAttributes updates the column's range table reference (varno) and * UpdateColumnAttributes updates the column's range table reference (varno) and
* column attribute number for the range table (varattno). The function uses the * column attribute number for the range table (varattno). The function uses the

View File

@ -428,8 +428,8 @@ ORDER BY 2 DESC, 1;
5 | 14 5 | 14
(3 rows) (3 rows)
-- non-partition key joins are not supported inside subquery -- non-partition key joins are supported inside subquery
-- since the join with a table -- via pull-push execution
SELECT * FROM SELECT * FROM
(SELECT ru.user_id, count(*) (SELECT ru.user_id, count(*)
FROM recent_users ru FROM recent_users ru
@ -438,7 +438,13 @@ SELECT * FROM
GROUP BY ru.user_id GROUP BY ru.user_id
ORDER BY 2 DESC, 1) s1 ORDER BY 2 DESC, 1) s1
ORDER BY 2 DESC, 1; ORDER BY 2 DESC, 1;
ERROR: bogus varno: 3 user_id | count
---------+-------
1 | 24
3 | 23
5 | 7
(3 rows)
-- join between views -- join between views
-- recent users who has an event in recent events -- recent users who has an event in recent events
SELECT ru.user_id FROM recent_users ru JOIN recent_events re USING(user_id) GROUP BY ru.user_id ORDER BY ru.user_id; SELECT ru.user_id FROM recent_users ru JOIN recent_events re USING(user_id) GROUP BY ru.user_id ORDER BY ru.user_id;
@ -533,7 +539,8 @@ SELECT * FROM
ON(ru.user_id = et.event_type) ON(ru.user_id = et.event_type)
) s1 ) s1
ORDER BY 2 DESC, 1; ORDER BY 2 DESC, 1;
ERROR: bogus varno: 3 ERROR: cannot pushdown the subquery
DETAIL: Complex subqueries and CTEs cannot be in the outer part of the outer join
-- create a select only view -- create a select only view
CREATE VIEW selected_users AS SELECT * FROM users_table WHERE value_1 >= 1 and value_1 <3; CREATE VIEW selected_users AS SELECT * FROM users_table WHERE value_1 >= 1 and value_1 <3;
CREATE VIEW recent_selected_users AS SELECT su.* FROM selected_users su JOIN recent_users ru USING(user_id); CREATE VIEW recent_selected_users AS SELECT su.* FROM selected_users su JOIN recent_users ru USING(user_id);
@ -863,7 +870,7 @@ EXPLAIN (COSTS FALSE) SELECT et.* FROM recent_10_users JOIN events_table et USIN
-> Sort -> Sort
Sort Key: remote_scan."time" DESC Sort Key: remote_scan."time" DESC
-> Custom Scan (Citus Real-Time) -> Custom Scan (Citus Real-Time)
-> Distributed Subplan 95_1 -> Distributed Subplan 96_1
-> Limit -> Limit
-> Sort -> Sort
Sort Key: max((max(remote_scan.lastseen))) DESC Sort Key: max((max(remote_scan.lastseen))) DESC

View File

@ -428,8 +428,8 @@ ORDER BY 2 DESC, 1;
5 | 14 5 | 14
(3 rows) (3 rows)
-- non-partition key joins are not supported inside subquery -- non-partition key joins are supported inside subquery
-- since the join with a table -- via pull-push execution
SELECT * FROM SELECT * FROM
(SELECT ru.user_id, count(*) (SELECT ru.user_id, count(*)
FROM recent_users ru FROM recent_users ru
@ -438,7 +438,13 @@ SELECT * FROM
GROUP BY ru.user_id GROUP BY ru.user_id
ORDER BY 2 DESC, 1) s1 ORDER BY 2 DESC, 1) s1
ORDER BY 2 DESC, 1; ORDER BY 2 DESC, 1;
ERROR: bogus varno: 3 user_id | count
---------+-------
1 | 24
3 | 23
5 | 7
(3 rows)
-- join between views -- join between views
-- recent users who has an event in recent events -- recent users who has an event in recent events
SELECT ru.user_id FROM recent_users ru JOIN recent_events re USING(user_id) GROUP BY ru.user_id ORDER BY ru.user_id; SELECT ru.user_id FROM recent_users ru JOIN recent_events re USING(user_id) GROUP BY ru.user_id ORDER BY ru.user_id;
@ -533,7 +539,8 @@ SELECT * FROM
ON(ru.user_id = et.event_type) ON(ru.user_id = et.event_type)
) s1 ) s1
ORDER BY 2 DESC, 1; ORDER BY 2 DESC, 1;
ERROR: bogus varno: 3 ERROR: cannot pushdown the subquery
DETAIL: Complex subqueries and CTEs cannot be in the outer part of the outer join
-- create a select only view -- create a select only view
CREATE VIEW selected_users AS SELECT * FROM users_table WHERE value_1 >= 1 and value_1 <3; CREATE VIEW selected_users AS SELECT * FROM users_table WHERE value_1 >= 1 and value_1 <3;
CREATE VIEW recent_selected_users AS SELECT su.* FROM selected_users su JOIN recent_users ru USING(user_id); CREATE VIEW recent_selected_users AS SELECT su.* FROM selected_users su JOIN recent_users ru USING(user_id);
@ -865,7 +872,7 @@ EXPLAIN (COSTS FALSE) SELECT et.* FROM recent_10_users JOIN events_table et USIN
-> Sort -> Sort
Sort Key: remote_scan."time" DESC Sort Key: remote_scan."time" DESC
-> Custom Scan (Citus Real-Time) -> Custom Scan (Citus Real-Time)
-> Distributed Subplan 95_1 -> Distributed Subplan 96_1
-> Limit -> Limit
-> Sort -> Sort
Sort Key: max((max(remote_scan.lastseen))) DESC Sort Key: max((max(remote_scan.lastseen))) DESC

View File

@ -220,8 +220,8 @@ SELECT * FROM
ORDER BY 2 DESC, 1) s1 ORDER BY 2 DESC, 1) s1
ORDER BY 2 DESC, 1; ORDER BY 2 DESC, 1;
-- non-partition key joins are not supported inside subquery -- non-partition key joins are supported inside subquery
-- since the join with a table -- via pull-push execution
SELECT * FROM SELECT * FROM
(SELECT ru.user_id, count(*) (SELECT ru.user_id, count(*)
FROM recent_users ru FROM recent_users ru