!2057 fix swcb qual push down join qual detection rule

Merge pull request !2057 from chenxiaobin/startwith
This commit is contained in:
opengauss-bot
2022-08-22 12:28:31 +00:00
committed by Gitee
3 changed files with 44 additions and 3 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;