funcscan_plan_optimizer_v2.patch
text/x-patch
Filename: funcscan_plan_optimizer_v2.patch
Type: text/x-patch
Part: 0
Patch
Format: unified
Series: patch v2
| File | + | − |
|---|---|---|
| src/backend/optimizer/util/clauses.c | 53 | 0 |
| src/test/regress/expected/join.out | 29 | 29 |
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 505ae0af85..2c9983004a 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -3655,6 +3655,59 @@ eval_const_expressions_mutator(Node *node,
context);
}
break;
+ case T_Var:
+ if (context->root && context->root->parse->rtable)
+ {
+ Var *var;
+ Query *query;
+ RangeTblEntry *pointedNode;
+
+ var = (Var *)node;
+ query = context->root->parse;
+
+ if (var->varlevelsup != 0 || var->varattno != 1)
+ break;
+
+ pointedNode = list_nth(query->rtable, var->varno - 1);
+ Assert(IsA(pointedNode, RangeTblEntry));
+
+ if (pointedNode->rtekind == RTE_FUNCTION && list_length(pointedNode->functions) == 1)
+ {
+ Form_pg_type type_form;
+ Node *result;
+ RangeTblFunction *tblFunction = linitial_node(RangeTblFunction, pointedNode->functions);
+ FuncExpr *expr = (FuncExpr *) tblFunction->funcexpr;
+ List *args = expr->args;
+ HeapTuple type_tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(expr->funcresulttype));
+
+ if (!HeapTupleIsValid(type_tuple))
+ elog(ERROR, "cache lookup failed for type %u", expr->funcresulttype);
+
+ type_form = (Form_pg_type) GETSTRUCT(type_tuple);
+
+ if (type_form->typtype != TYPTYPE_BASE)
+ {
+ ReleaseSysCache(type_tuple);
+ break;
+ }
+
+ result = simplify_function(expr->funcid,
+ expr->funcresulttype,
+ exprTypmod(expr),
+ expr->funccollid,
+ expr->inputcollid,
+ &args,
+ expr->funcvariadic,
+ true,
+ false,
+ context);
+
+ ReleaseSysCache(type_tuple);
+
+ if (result) /* successfully simplified it */
+ return (Node *) result;
+ }
+ break;
default:
break;
}
diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out
index cbc882d47b..eb92f556d8 100644
--- a/src/test/regress/expected/join.out
+++ b/src/test/regress/expected/join.out
@@ -3021,23 +3021,23 @@ select * from
int4(sin(1)) q1,
int4(sin(0)) q2
where q1 = thousand or q2 = thousand;
- QUERY PLAN
-------------------------------------------------------------------------
- Hash Join
- Hash Cond: (tenk1.twothousand = int4_tbl.f1)
+ QUERY PLAN
+-------------------------------------------------------------------------
+ Nested Loop
-> Nested Loop
- -> Nested Loop
- -> Function Scan on q1
- -> Function Scan on q2
- -> Bitmap Heap Scan on tenk1
- Recheck Cond: ((q1.q1 = thousand) OR (q2.q2 = thousand))
- -> BitmapOr
- -> Bitmap Index Scan on tenk1_thous_tenthous
- Index Cond: (q1.q1 = thousand)
- -> Bitmap Index Scan on tenk1_thous_tenthous
- Index Cond: (q2.q2 = thousand)
- -> Hash
- -> Seq Scan on int4_tbl
+ -> Hash Join
+ Hash Cond: (tenk1.twothousand = int4_tbl.f1)
+ -> Bitmap Heap Scan on tenk1
+ Recheck Cond: ((1 = thousand) OR (0 = thousand))
+ -> BitmapOr
+ -> Bitmap Index Scan on tenk1_thous_tenthous
+ Index Cond: (1 = thousand)
+ -> Bitmap Index Scan on tenk1_thous_tenthous
+ Index Cond: (0 = thousand)
+ -> Hash
+ -> Seq Scan on int4_tbl
+ -> Function Scan on q1
+ -> Function Scan on q2
(15 rows)
explain (costs off)
@@ -3046,20 +3046,20 @@ select * from
int4(sin(1)) q1,
int4(sin(0)) q2
where thousand = (q1 + q2);
- QUERY PLAN
---------------------------------------------------------------
- Hash Join
- Hash Cond: (tenk1.twothousand = int4_tbl.f1)
+ QUERY PLAN
+-------------------------------------------------------------------
+ Nested Loop
-> Nested Loop
- -> Nested Loop
- -> Function Scan on q1
- -> Function Scan on q2
- -> Bitmap Heap Scan on tenk1
- Recheck Cond: (thousand = (q1.q1 + q2.q2))
- -> Bitmap Index Scan on tenk1_thous_tenthous
- Index Cond: (thousand = (q1.q1 + q2.q2))
- -> Hash
- -> Seq Scan on int4_tbl
+ -> Hash Join
+ Hash Cond: (tenk1.twothousand = int4_tbl.f1)
+ -> Bitmap Heap Scan on tenk1
+ Recheck Cond: (thousand = 1)
+ -> Bitmap Index Scan on tenk1_thous_tenthous
+ Index Cond: (thousand = 1)
+ -> Hash
+ -> Seq Scan on int4_tbl
+ -> Function Scan on q1
+ -> Function Scan on q2
(12 rows)
--