diff --git a/src/common/backend/parser/parse_expr.cpp b/src/common/backend/parser/parse_expr.cpp index df6c523c7..b85da6f35 100644 --- a/src/common/backend/parser/parse_expr.cpp +++ b/src/common/backend/parser/parse_expr.cpp @@ -110,7 +110,7 @@ static Node *transformStartWithWhereClauseColumnRef(ParseState *pstate, ColumnRe static Node* tryTransformFunc(ParseState* pstate, List* fields, int location); static void SubCheckOutParam(List* exprtargs, Oid funcid); static Node* transformPrefixKey(ParseState* pstate, PrefixKey* pkey); -static Node* transformCursorExpression(ParseState* pstate, CursorExpression* cursor_expression); +static Node* transformCursorExpression(ParseState* pstate, CursorExpression* cursor_expression, bool smp = false); static Node* transformStringCast(ParseState* pstate, char *str, int location, TypeName *typname); static Node* transformBinaryDoubleInf(ParseState* pstate, ColumnRef *cref, char *colname); static Node* transformBinaryDoubleNan(ParseState* pstate, ColumnRef *cref, char *colname); @@ -1893,20 +1893,19 @@ static Node* transformFuncCall(ParseState* pstate, FuncCall* fn) result = ParseFuncOrColumn(pstate, fn->funcname, targs, last_srf, fn, fn->location, fn->call_func); if (IsA(result, FuncExpr)) { - /* if function is not SRF or pipelined, close smp for all CursorExpressions */ - int2 seq = (!((FuncExpr*)result)->funcretset && - !PROC_IS_PIPELINED(get_func_prokind(((FuncExpr*)result)->funcid))) ? - -1 : GetParallelCursorSeq(((FuncExpr*)result)->funcid); + /* + * If function is not function table, close smp for all CursorExpressions. + * If function is not SRF or pipelined, close smp too. + * */ + int2 seq = (pstate->p_expr_kind != EXPR_KIND_FROM_FUNCTION || (!((FuncExpr*)result)->funcretset && + !PROC_IS_PIPELINED(get_func_prokind(((FuncExpr*)result)->funcid)))) ? + -1 : GetParallelCursorSeq(((FuncExpr*)result)->funcid); int2 i = 0; - AutoDopControl dopControl; foreach (args, ((FuncExpr*)result)->args) { Node* arg = (Node*)lfirst(args); if (IsA(arg, CursorExpression)) { - if (i != seq) { - dopControl.CloseSmp(); - } - lfirst(args) = transformExprRecurse(pstate, arg); - dopControl.ResetSmp(); + pstate->p_expr_transform_level++; + lfirst(args) = transformCursorExpression(pstate, (CursorExpression*)arg, i == seq); } i++; } @@ -3890,7 +3889,7 @@ static Node* transformCursorOuterVarAsParam(ParseState* pstate, ColumnRef* cref, } -static Node* transformCursorExpression(ParseState* pstate, CursorExpression* cursor_expression) +static Node* transformCursorExpression(ParseState* pstate, CursorExpression* cursor_expression, bool smp) { CursorExpression* newm = makeNode(CursorExpression); char* queryString; @@ -3900,6 +3899,11 @@ static Node* transformCursorExpression(ParseState* pstate, CursorExpression* cur List* stmt_list = NIL; ParseState* parse_state_temp = NULL; int level = ++u_sess->parser_cxt.cursor_expr_level; + AutoDopControl dopControl; + + if (!smp) { + dopControl.CloseSmp(); + } ParseState* parse_state_parent = pstate; @@ -3961,6 +3965,9 @@ static Node* transformCursorExpression(ParseState* pstate, CursorExpression* cur parse_state_parent->is_outer_parse_state = false; parse_state_temp = parse_state_temp->parentParseState; } + + /* restore smp */ + dopControl.ResetSmp(); return (Node*)newm; } diff --git a/src/test/regress/expected/parallel_enable_function.out b/src/test/regress/expected/parallel_enable_function.out index 36f755b03..e192b9c95 100644 --- a/src/test/regress/expected/parallel_enable_function.out +++ b/src/test/regress/expected/parallel_enable_function.out @@ -383,6 +383,30 @@ select hash_srf(cursor (select * from employees)) limit 10; (10,60,abc,def,123,123) (10 rows) +explain (costs off) select hash_srf(cursor (select * from employees)) from employees limit 10; + QUERY PLAN +---------------------------------------------- + Limit + -> Streaming(type: LOCAL GATHER dop: 1/2) + -> Limit + -> Seq Scan on employees +(4 rows) + +select hash_srf(cursor (select * from employees)) from employees limit 10; + hash_srf +------------------------- + (1,60,abc,def,123,123) + (2,60,abc,def,123,123) + (3,60,abc,def,123,123) + (4,60,abc,def,123,123) + (5,60,abc,def,123,123) + (6,60,abc,def,123,123) + (7,60,abc,def,123,123) + (8,60,abc,def,123,123) + (9,60,abc,def,123,123) + (10,60,abc,def,123,123) +(10 rows) + -- subquery cannot smp explain (costs off) select 1, (select count(*) from hash_srf(cursor (select * from employees))); QUERY PLAN diff --git a/src/test/regress/expected/smp_cursor.out b/src/test/regress/expected/smp_cursor.out index 96b492e4c..451be46f8 100644 --- a/src/test/regress/expected/smp_cursor.out +++ b/src/test/regress/expected/smp_cursor.out @@ -519,5 +519,31 @@ NOTICE: --?duration.* end; +-- cursor expr in targetlist do not smp +set enable_auto_explain = off; +explain (costs off) select a, cursor(select * from t1) from t1 limit 10; + QUERY PLAN +---------------------------------------------- + Limit + -> Streaming(type: LOCAL GATHER dop: 1/2) + -> Limit + -> Seq Scan on t1 +(4 rows) + +select a, cursor(select * from t1) from t1 limit 10; + a | ?column? +----+------------------ +--?.* +--?.* +--?.* +--?.* +--?.* +--?.* +--?.* +--?.* +--?.* +--?.* +(10 rows) + drop schema smp_cursor cascade; NOTICE: drop cascades to table t1 diff --git a/src/test/regress/sql/parallel_enable_function.sql b/src/test/regress/sql/parallel_enable_function.sql index 21ceed582..64967b624 100644 --- a/src/test/regress/sql/parallel_enable_function.sql +++ b/src/test/regress/sql/parallel_enable_function.sql @@ -156,6 +156,9 @@ select * from hash_srf(cursor (select * from employees)) a, hash_srf(cursor (sel explain (costs off) select hash_srf(cursor (select * from employees)) limit 10; select hash_srf(cursor (select * from employees)) limit 10; +explain (costs off) select hash_srf(cursor (select * from employees)) from employees limit 10; +select hash_srf(cursor (select * from employees)) from employees limit 10; + -- subquery cannot smp explain (costs off) select 1, (select count(*) from hash_srf(cursor (select * from employees))); select 1, (select count(*) from hash_srf(cursor (select * from employees))); diff --git a/src/test/regress/sql/smp_cursor.sql b/src/test/regress/sql/smp_cursor.sql index 8334505c5..f53242f8a 100644 --- a/src/test/regress/sql/smp_cursor.sql +++ b/src/test/regress/sql/smp_cursor.sql @@ -79,4 +79,9 @@ fetch all xc; move xc; end; +-- cursor expr in targetlist do not smp +set enable_auto_explain = off; +explain (costs off) select a, cursor(select * from t1) from t1 limit 10; +select a, cursor(select * from t1) from t1 limit 10; + drop schema smp_cursor cascade; \ No newline at end of file