mirror of https://github.com/citusdata/citus.git
Merge pull request #2569 from citusdata/fix_having_with_joins
Fix having clause bug for complex joinspull/2578/head
commit
cb77fcce85
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue