diff --git a/src/common/backend/parser/parse_startwith.cpp b/src/common/backend/parser/parse_startwith.cpp index 53cec1e63..bb983216b 100644 --- a/src/common/backend/parser/parse_startwith.cpp +++ b/src/common/backend/parser/parse_startwith.cpp @@ -1290,6 +1290,21 @@ static void AddWithClauseToBranch(ParseState *pstate, SelectStmt *stmt, List *re 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) { 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; + 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 * 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. * 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 * from the where clause. */ - if (expr->kind == AEXPR_OP && - (!IsA(expr->lexpr, ColumnRef) || !IsA(expr->rexpr, ColumnRef))) { + int columnref_count = 0; + raw_expression_tree_walker(node, (bool (*)()) count_columnref_walker, (void*)&columnref_count); + + if (columnref_count < 2) { expr->lexpr = makeBoolAConst(true, -1); expr->rexpr = makeBoolAConst(true, -1); expr->kind = AEXPR_OR; diff --git a/src/test/regress/expected/sw_bugfix-1.out b/src/test/regress/expected/sw_bugfix-1.out index 8d72667db..133605add 100644 --- a/src/test/regress/expected/sw_bugfix-1.out +++ b/src/test/regress/expected/sw_bugfix-1.out @@ -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 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; diff --git a/src/test/regress/sql/sw_bugfix-1.sql b/src/test/regress/sql/sw_bugfix-1.sql index cbf505b7a..e3f2f0f81 100644 --- a/src/test/regress/sql/sw_bugfix-1.sql +++ b/src/test/regress/sql/sw_bugfix-1.sql @@ -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; drop table if exists xt1; 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;