diff --git a/src/common/backend/parser/analyze.cpp b/src/common/backend/parser/analyze.cpp index 3781823d2..d47b3f604 100644 --- a/src/common/backend/parser/analyze.cpp +++ b/src/common/backend/parser/analyze.cpp @@ -1653,15 +1653,45 @@ static void SetUpsertAttrnoState(ParseState* pstate, List *targetList) } } +static bool isSubExprSupportRightRef(Node* node) +{ + if (!node) { + return true; + } + if (IsA(node, A_Expr)) { + A_Expr* expr = (A_Expr*)node; + return isSubExprSupportRightRef(expr->lexpr) && + isSubExprSupportRightRef(expr->rexpr); + } else if (IsA(node, SubLink)) { + SubLink* sl = (SubLink*)node; + if (sl->subselect) { + SelectStmt* subsel = (SelectStmt*)sl->subselect; + return (!subsel->whereClause || subsel->fromClause); + } + } + return true; +} + static RightRefState* MakeRightRefStateIfSupported(SelectStmt* selectStmt) { bool isSupported = DB_IS_CMPT(B_FORMAT) && selectStmt && selectStmt->valuesLists && !IsInitdb; - if (isSupported) { - RightRefState* refState = (RightRefState*)palloc0(sizeof(RightRefState)); - refState->isSupported = true; - return refState; + if (!isSupported) { + return nullptr; } - return nullptr; + ListCell* lc = NULL; + ListCell* lc2 = NULL; + foreach (lc, selectStmt->valuesLists) { + List* sublist = (List*)lfirst(lc); + foreach(lc2, sublist) { + Node* col = (Node*)lfirst(lc2); + if (!isSubExprSupportRightRef(col)) { + return nullptr; + } + } + } + RightRefState* refState = (RightRefState*)palloc0(sizeof(RightRefState)); + refState->isSupported = true; + return refState; } /* diff --git a/src/test/regress/expected/mysql_compatibility.out b/src/test/regress/expected/mysql_compatibility.out index 7f2a89cb5..503e2c462 100644 --- a/src/test/regress/expected/mysql_compatibility.out +++ b/src/test/regress/expected/mysql_compatibility.out @@ -1008,6 +1008,17 @@ select @num; 0 (1 row) +-- test insert right ref +drop table if exists ins_sel_t0; +NOTICE: table "ins_sel_t0" does not exist, skipping +CREATE TABLE ins_sel_t0 ( c3 INT , c10 INT ) ; +INSERT INTO ins_sel_t0 VALUES ( -66 , 54 ) , + ( EXISTS ( SELECT 76 AS c42 WHERE c3 = 12 IS NOT FALSE ) NOT IN ( 75 >= -80 ) , -99 ) ; -- should error +ERROR: column "c3" does not exist +LINE 2: ( EXISTS ( SELECT 76 AS c42 WHERE c3 = 12 IS NOT FALSE )... + ^ +HINT: There is a column named "c3" in table "ins_sel_t0", but it cannot be referenced from this part of the query. +drop table ins_sel_t0; --test as function parameter set @num := 1; select sin(@num := @num + 1) from t1; diff --git a/src/test/regress/sql/mysql_compatibility.sql b/src/test/regress/sql/mysql_compatibility.sql index f7e203a76..50434d80e 100644 --- a/src/test/regress/sql/mysql_compatibility.sql +++ b/src/test/regress/sql/mysql_compatibility.sql @@ -323,6 +323,13 @@ insert into t2 select @num + 10 from t1; select * from t2; select @num; +-- test insert right ref +drop table if exists ins_sel_t0; +CREATE TABLE ins_sel_t0 ( c3 INT , c10 INT ) ; +INSERT INTO ins_sel_t0 VALUES ( -66 , 54 ) , + ( EXISTS ( SELECT 76 AS c42 WHERE c3 = 12 IS NOT FALSE ) NOT IN ( 75 >= -80 ) , -99 ) ; -- should error +drop table ins_sel_t0; + --test as function parameter set @num := 1; select sin(@num := @num + 1) from t1;