修复greatest作为表函数的core问题
This commit is contained in:
@ -4156,8 +4156,13 @@ static Node *transformStartWithWhereClauseColumnRef(ParseState *pstate, ColumnRe
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PlannedStmt* getCursorStreamFromFuncArg(FuncExpr* funcexpr, CursorExpression** ce)
|
||||
PlannedStmt* getCursorStreamFromFuncArg(Node* node, CursorExpression** ce)
|
||||
{
|
||||
if (!IsA(node, FuncExpr)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FuncExpr* funcexpr = (FuncExpr*)node;
|
||||
ListCell* lc = NULL;
|
||||
foreach (lc, funcexpr->args) {
|
||||
Node* arg = (Node*)lfirst(lc);
|
||||
|
||||
@ -1792,11 +1792,9 @@ RangeTblEntry* addRangeTableEntryForFunction(
|
||||
* create_functionscan_path need cursorDop to determine
|
||||
* wheather functionscan smp or not.
|
||||
*/
|
||||
if (IsA(funcexpr, FuncExpr)) {
|
||||
PlannedStmt* cursorPstmt = getCursorStreamFromFuncArg((FuncExpr*)funcexpr);
|
||||
if (cursorPstmt != NULL && IsA(cursorPstmt->planTree, Stream)) {
|
||||
rte->cursorDop = cursorPstmt->planTree->lefttree->dop;
|
||||
}
|
||||
PlannedStmt* cursorPstmt = getCursorStreamFromFuncArg(funcexpr);
|
||||
if (cursorPstmt != NULL && IsA(cursorPstmt->planTree, Stream)) {
|
||||
rte->cursorDop = cursorPstmt->planTree->lefttree->dop;
|
||||
}
|
||||
|
||||
eref = makeAlias(alias ? alias->aliasname : funcname, NIL);
|
||||
|
||||
@ -6246,7 +6246,7 @@ static FunctionScan* make_functionscan(List* qptlist, List* qpqual, Index scanre
|
||||
node->funccolcollations = funccolcollations;
|
||||
|
||||
CursorExpression* ce = NULL;
|
||||
PlannedStmt* cursorPstmt = getCursorStreamFromFuncArg((FuncExpr*)funcexpr, &ce);
|
||||
PlannedStmt* cursorPstmt = getCursorStreamFromFuncArg(funcexpr, &ce);
|
||||
if (cursorPstmt == NULL) {
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -1898,7 +1898,7 @@ void finalize_node_id(Plan* result_plan, int* plan_node_id, int* parent_node_id,
|
||||
}
|
||||
} break;
|
||||
case T_FunctionScan: {
|
||||
PlannedStmt* cursorPstmt = getCursorStreamFromFuncArg((FuncExpr*)((FunctionScan*)result_plan)->funcexpr);
|
||||
PlannedStmt* cursorPstmt = getCursorStreamFromFuncArg(((FunctionScan*)result_plan)->funcexpr);
|
||||
if (cursorPstmt != NULL) {
|
||||
cursorPstmt->planTree->cursor_owner_node_id = result_plan->plan_node_id;
|
||||
set_stream_plan_cursor_walker(cursorPstmt->planTree);
|
||||
|
||||
@ -971,7 +971,7 @@ static void InitStreamFlow(StreamFlowCtl* ctl)
|
||||
InitStreamFlow(ctl);
|
||||
} break;
|
||||
case T_FunctionScan: {
|
||||
PlannedStmt* cursorPstmt = getCursorStreamFromFuncArg((FuncExpr*)((FunctionScan*)oldPlan)->funcexpr);
|
||||
PlannedStmt* cursorPstmt = getCursorStreamFromFuncArg(((FunctionScan*)oldPlan)->funcexpr);
|
||||
if (cursorPstmt != NULL) {
|
||||
ctl->plan = cursorPstmt->planTree;
|
||||
|
||||
|
||||
@ -39,6 +39,6 @@ extern bool IsQuerySWCBRewrite(Query *query);
|
||||
extern bool IsSWCBRewriteRTE(RangeTblEntry *rte);
|
||||
extern Datum GetTypeZeroValue(Form_pg_attribute att_tup);
|
||||
typedef Datum (*getTypeZeroValueFunc)(Form_pg_attribute att_tup);
|
||||
extern PlannedStmt* getCursorStreamFromFuncArg(FuncExpr* funcexpr, CursorExpression** ce = NULL);
|
||||
extern PlannedStmt* getCursorStreamFromFuncArg(Node* node, CursorExpression** ce = NULL);
|
||||
|
||||
#endif /* PARSE_EXPR_H */
|
||||
|
||||
@ -808,6 +808,12 @@ select least(0.9, 1);
|
||||
.9
|
||||
(1 row)
|
||||
|
||||
select * from greatest(1, 1.1);
|
||||
greatest
|
||||
----------
|
||||
1.1
|
||||
(1 row)
|
||||
|
||||
create or replace function test_cast(a numeric)
|
||||
returns int as
|
||||
$$
|
||||
|
||||
@ -319,6 +319,8 @@ select greatest(1.1, 1);
|
||||
select least(1, 0.9);
|
||||
select least(0.9, 1);
|
||||
|
||||
select * from greatest(1, 1.1);
|
||||
|
||||
create or replace function test_cast(a numeric)
|
||||
returns int as
|
||||
$$
|
||||
|
||||
Reference in New Issue
Block a user