!2057 fix swcb qual push down join qual detection rule
Merge pull request !2057 from chenxiaobin/startwith
This commit is contained in:
@ -1290,6 +1290,21 @@ static void AddWithClauseToBranch(ParseState *pstate, SelectStmt *stmt, List *re
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool count_columnref_walker(Node *node, int *columnref_count)
|
||||||
|
{
|
||||||
|
if (node == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsA(node, ColumnRef)) {
|
||||||
|
return raw_expression_tree_walker(node, (bool (*)()) count_columnref_walker, (void*)columnref_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
*columnref_count = *columnref_count + 1;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static bool walker_to_exclude_non_join_quals(Node *node, Node *context_node)
|
static bool walker_to_exclude_non_join_quals(Node *node, Node *context_node)
|
||||||
{
|
{
|
||||||
if (node == NULL) {
|
if (node == NULL) {
|
||||||
@ -1301,17 +1316,22 @@ static bool walker_to_exclude_non_join_quals(Node *node, Node *context_node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
A_Expr* expr = (A_Expr*) node;
|
A_Expr* expr = (A_Expr*) node;
|
||||||
|
if (expr->kind != AEXPR_OP) {
|
||||||
|
return raw_expression_tree_walker(node, (bool (*)()) walker_to_exclude_non_join_quals, (void*)NULL);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* this is to achieve consistent result sets with those produced by the original
|
* this is to achieve consistent result sets with those produced by the original
|
||||||
* start with .. connect by syntax, which does not push filter quals down to connect quals.
|
* start with .. connect by syntax, which does not push filter quals down to connect quals.
|
||||||
* if non-column item appears on any side of an operator, we guess that it is
|
* if no more than one column item appears inside an AEXPR_OP, we guess that it is
|
||||||
* not a join qual so should not be filtered in sw op, and force it to be true.
|
* not a join qual so should not be filtered in sw op, and force it to be true.
|
||||||
* this rule is not always correct but should work fine most of the time.
|
* this rule is not always correct but should work fine most of the time.
|
||||||
* could be improved later on, e.g. find better ways to extract non-join quals
|
* could be improved later on, e.g. find better ways to extract non-join quals
|
||||||
* from the where clause.
|
* from the where clause.
|
||||||
*/
|
*/
|
||||||
if (expr->kind == AEXPR_OP &&
|
int columnref_count = 0;
|
||||||
(!IsA(expr->lexpr, ColumnRef) || !IsA(expr->rexpr, ColumnRef))) {
|
raw_expression_tree_walker(node, (bool (*)()) count_columnref_walker, (void*)&columnref_count);
|
||||||
|
|
||||||
|
if (columnref_count < 2) {
|
||||||
expr->lexpr = makeBoolAConst(true, -1);
|
expr->lexpr = makeBoolAConst(true, -1);
|
||||||
expr->rexpr = makeBoolAConst(true, -1);
|
expr->rexpr = makeBoolAConst(true, -1);
|
||||||
expr->kind = AEXPR_OR;
|
expr->kind = AEXPR_OR;
|
||||||
|
@ -1490,3 +1490,16 @@ select * from xt2,xt1 where xt1.id=xt2.idd and xt1.id=3 start with id=2 connect
|
|||||||
|
|
||||||
drop table if exists xt1;
|
drop table if exists xt1;
|
||||||
drop table if exists xt2;
|
drop table if exists xt2;
|
||||||
|
create table a(a1 int, a2 int);
|
||||||
|
create table b(b1 int, b2 int);
|
||||||
|
insert into a values(1,3),(2,4);
|
||||||
|
insert into b values(2,1),(3,1);
|
||||||
|
select * from a, b where a1+1=b1 and a1<10 start with a1=1 connect by a1=prior b1;
|
||||||
|
a1 | a2 | b1 | b2
|
||||||
|
----+----+----+----
|
||||||
|
1 | 3 | 2 | 1
|
||||||
|
2 | 4 | 3 | 1
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
drop table a;
|
||||||
|
drop table b;
|
||||||
|
@ -441,3 +441,11 @@ select * from xt2,xt1 where xt1.id=xt2.idd and xt1.id!=2 start with id=2 connect
|
|||||||
select * from xt2,xt1 where xt1.id=xt2.idd and xt1.id=3 start with id=2 connect by prior id=lid;
|
select * from xt2,xt1 where xt1.id=xt2.idd and xt1.id=3 start with id=2 connect by prior id=lid;
|
||||||
drop table if exists xt1;
|
drop table if exists xt1;
|
||||||
drop table if exists xt2;
|
drop table if exists xt2;
|
||||||
|
|
||||||
|
create table a(a1 int, a2 int);
|
||||||
|
create table b(b1 int, b2 int);
|
||||||
|
insert into a values(1,3),(2,4);
|
||||||
|
insert into b values(2,1),(3,1);
|
||||||
|
select * from a, b where a1+1=b1 and a1<10 start with a1=1 connect by a1=prior b1;
|
||||||
|
drop table a;
|
||||||
|
drop table b;
|
||||||
|
Reference in New Issue
Block a user