修复游标表达式做targetlist的coredump问题
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)));
|
||||
|
||||
@ -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;
|
||||
Reference in New Issue
Block a user