From 3c56e30551067cc0e807eb79b6856be0bfa029d1 Mon Sep 17 00:00:00 2001 From: yupeng <308835789@qq.com> Date: Sun, 25 Apr 2021 16:32:42 +0800 Subject: [PATCH] fix (+) is null --- .../backend/parser/parse_compatibility.cpp | 6 ++--- .../expected/a_outerjoin_conversion.out | 27 ++++++++++++++++++- .../regress/sql/a_outerjoin_conversion.sql | 7 +++++ 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/common/backend/parser/parse_compatibility.cpp b/src/common/backend/parser/parse_compatibility.cpp index c5a7d1bc8..31f2f5bf9 100644 --- a/src/common/backend/parser/parse_compatibility.cpp +++ b/src/common/backend/parser/parse_compatibility.cpp @@ -143,7 +143,7 @@ static void insert_jointerm(OperatorPlusProcessContext* ctx, Expr* expr, RangeTb ListCell* lc = NULL; JoinTerm* jterm = NULL; - Assert(IsA(expr, A_Expr)); + Assert(IsA(expr, A_Expr) || IsA(expr, NullTest)); /* lrte is the RTE with operator "(+)", it couldn't be NULL */ Assert(lrte != NULL); @@ -567,8 +567,8 @@ bool plus_outerjoin_precheck(const OperatorPlusProcessContext* ctx, Node* expr, return false; } - /* Only support A_Expr with "(+)" for now */ - if (list_length(lhasplus) && !IsA(expr, A_Expr)) { + /* Only support A_Expr and NullTest with "(+)" for now */ + if (list_length(lhasplus) && !IsA(expr, A_Expr) && !IsA(expr, NullTest)) { ereport( ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("Operator \"(+)\" can only be used in common expression."))); } diff --git a/src/test/regress/expected/a_outerjoin_conversion.out b/src/test/regress/expected/a_outerjoin_conversion.out index 153956dfe..c0ac8c10c 100644 --- a/src/test/regress/expected/a_outerjoin_conversion.out +++ b/src/test/regress/expected/a_outerjoin_conversion.out @@ -4,11 +4,15 @@ create table t11(c1 int, c2 int, c3 int); create table t12(c1 int, c2 int, c3 int); create table t13(c1 int, c2 int, c3 int); create table t14(A4 int, B4 int, c4 int); +create table t_a (id int, name varchar(10), code int); +create table t_b (id int, name varchar(10), code int); -- insert base insert into t11 select v,v,v from generate_series(1,10) as v; insert into t12 select * from t11; insert into t13 select * from t11; insert into t14 select v,v,v from generate_series(1,30) as v; +insert into t_a values (1, 'tom', 3); +insert into t_b values (1, 'bat', 6); -- insert t11 t12, t13's not match values insert into t11 select v,v,v from generate_series(11,15) as v; insert into t12 select v,v,v from generate_series(16,20) as v; @@ -1463,9 +1467,28 @@ select t11.c1, t12.c2, t13.c2 from t11, t12, t13 where t11.c2 = t12.c3(+) and t1 -------used (+) with un common expression, like is null, is not null-------- select t11.c1, t12.c2, t13.c2 from t11, t12, t13 where t11.c2 = t12.c3(+) and t11.c3 = t13.c1(+) and t13.c2(+) is not null; -ERROR: Operator "(+)" can only be used in common expression. + c1 | c2 | c2 +----+----+---- + 1 | 1 | 1 + 2 | 2 | 2 + 3 | 3 | 3 + 4 | 4 | 4 + 5 | 5 | 5 + 6 | 6 | 6 + 7 | 7 | 7 + 8 | 8 | 8 + 9 | 9 | 9 + 10 | 10 | 10 +(10 rows) + select t11.c1, t12.c2, t13.c2 from t11, t12, t13 where t11.c2 = t12.c3(+) and t11.c3 = t13.c1(+) and (t13.c2(+) > t12.c1)::bool; ERROR: Operator "(+)" can only be used in common expression. +select * from t_a a,t_b b where b.id=a.id(+) and a.code(+) + 1 * 2 + a.code(+) IS NOT NULL ; + id | name | code | id | name | code +----+------+------+----+------+------ + 1 | tom | 3 | 1 | bat | 6 +(1 row) + drop view plus_v; drop function plus_join_test_1(); drop table t1; @@ -1475,4 +1498,6 @@ drop table t12; drop table t13; drop table t14; drop table t15; +drop table t_a; +drop table t_b; drop schema plus_outerjoin; diff --git a/src/test/regress/sql/a_outerjoin_conversion.sql b/src/test/regress/sql/a_outerjoin_conversion.sql index 4978354a0..67d041796 100644 --- a/src/test/regress/sql/a_outerjoin_conversion.sql +++ b/src/test/regress/sql/a_outerjoin_conversion.sql @@ -4,12 +4,16 @@ create table t11(c1 int, c2 int, c3 int); create table t12(c1 int, c2 int, c3 int); create table t13(c1 int, c2 int, c3 int); create table t14(A4 int, B4 int, c4 int); +create table t_a (id int, name varchar(10), code int); +create table t_b (id int, name varchar(10), code int); -- insert base insert into t11 select v,v,v from generate_series(1,10) as v; insert into t12 select * from t11; insert into t13 select * from t11; insert into t14 select v,v,v from generate_series(1,30) as v; +insert into t_a values (1, 'tom', 3); +insert into t_b values (1, 'bat', 6); -- insert t11 t12, t13's not match values insert into t11 select v,v,v from generate_series(11,15) as v; @@ -357,6 +361,7 @@ select t11.c1, t12.c2, t13.c2 from t11, t12, t13 where t11.c2 = t12.c3(+) and t1 -------used (+) with un common expression, like is null, is not null-------- select t11.c1, t12.c2, t13.c2 from t11, t12, t13 where t11.c2 = t12.c3(+) and t11.c3 = t13.c1(+) and t13.c2(+) is not null; select t11.c1, t12.c2, t13.c2 from t11, t12, t13 where t11.c2 = t12.c3(+) and t11.c3 = t13.c1(+) and (t13.c2(+) > t12.c1)::bool; +select * from t_a a,t_b b where b.id=a.id(+) and a.code(+) + 1 * 2 + a.code(+) IS NOT NULL ; drop view plus_v; drop function plus_join_test_1(); @@ -367,4 +372,6 @@ drop table t12; drop table t13; drop table t14; drop table t15; +drop table t_a; +drop table t_b; drop schema plus_outerjoin;