Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd6429e5

Browse files
committed
Minor code rearrangement & doc improvement in eval_const_expressions().
1 parentcf6420d commitd6429e5

File tree

1 file changed

+129
-105
lines changed

1 file changed

+129
-105
lines changed

‎src/backend/optimizer/util/clauses.c

Lines changed: 129 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.61 2000/03/12 19:32:06 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.62 2000/03/19 18:20:38 tgl Exp $
1212
*
1313
* HISTORY
1414
* AUTHORDATEMAJOR EVENT
@@ -52,6 +52,7 @@ static bool check_subplans_for_ungrouped_vars_walker(Node *node,
5252
check_subplans_for_ungrouped_vars_context*context);
5353
staticintis_single_func(Node*node);
5454
staticNode*eval_const_expressions_mutator (Node*node,void*context);
55+
staticExpr*simplify_op_or_func(Expr*expr,List*args);
5556

5657

5758
Expr*
@@ -918,108 +919,15 @@ eval_const_expressions_mutator (Node *node, void *context)
918919
{
919920
caseOP_EXPR:
920921
caseFUNC_EXPR:
921-
{
922-
/*
923-
* For an operator or function, we cannot simplify
924-
* unless all the inputs are constants. (XXX possible
925-
* future improvement: if the op/func is strict and
926-
* at least one input is NULL, we could simplify to NULL.
927-
* But we do not currently have any way to know if the
928-
* op/func is strict or not. For now, a NULL input is
929-
* treated the same as any other constant node.)
930-
*/
931-
boolargs_all_const= true;
932-
List*arg;
933-
Oidfuncid;
934-
Oidresult_typeid;
935-
HeapTuplefunc_tuple;
936-
Form_pg_procfuncform;
937-
TyperesultType;
938-
Datumconst_val;
939-
boolconst_is_null;
940-
boolisDone;
941-
942-
foreach(arg,args)
943-
{
944-
if (!IsA(lfirst(arg),Const))
945-
{
946-
args_all_const= false;
947-
break;
948-
}
949-
}
950-
if (!args_all_const)
951-
break;
952-
/*
953-
* Get the function procedure's OID and look to see
954-
* whether it is marked proiscachable.
955-
*/
956-
if (expr->opType==OP_EXPR)
957-
{
958-
Oper*oper= (Oper*)expr->oper;
959-
960-
replace_opid(oper);
961-
funcid=oper->opid;
962-
result_typeid=oper->opresulttype;
963-
}
964-
else
965-
{
966-
Func*func= (Func*)expr->oper;
967-
968-
funcid=func->funcid;
969-
result_typeid=func->functype;
970-
}
971-
/* Someday lsyscache.c might provide a function for this */
972-
func_tuple=SearchSysCacheTuple(PROCOID,
973-
ObjectIdGetDatum(funcid),
974-
0,0,0);
975-
if (!HeapTupleIsValid(func_tuple))
976-
elog(ERROR,"Function OID %u does not exist",funcid);
977-
funcform= (Form_pg_proc)GETSTRUCT(func_tuple);
978-
if (!funcform->proiscachable)
979-
break;
980-
/*
981-
* Also check to make sure it doesn't return a set.
982-
*
983-
* XXX would it be better to take the result type from the
984-
* pg_proc tuple, rather than the Oper or Func node?
985-
*/
986-
if (funcform->proretset)
987-
break;
988-
/*
989-
* OK, looks like we can simplify this operator/function.
990-
* We use the executor's routine ExecEvalExpr() to avoid
991-
* duplication of code and ensure we get the same result
992-
* as the executor would get.
993-
*
994-
* Build a new Expr node containing the already-simplified
995-
* arguments. The only other setup needed here is the
996-
* replace_opid() that we already did for the OP_EXPR case.
997-
*/
998-
newexpr=makeNode(Expr);
999-
newexpr->typeOid=expr->typeOid;
1000-
newexpr->opType=expr->opType;
1001-
newexpr->oper=expr->oper;
1002-
newexpr->args=args;
1003-
/*
1004-
* It is OK to pass econtext = NULL because none of the
1005-
* ExecEvalExpr() code used in this situation will use
1006-
* econtext. That might seem fortuitous, but it's not
1007-
* so unreasonable --- a constant expression does not
1008-
* depend on context, by definition, n'est ce pas?
1009-
*/
1010-
const_val=ExecEvalExpr((Node*)newexpr,NULL,
1011-
&const_is_null,&isDone);
1012-
Assert(isDone);/* if this isn't set, we blew it... */
1013-
pfree(newexpr);
1014922
/*
1015-
* Make the constant result node.
923+
* Code for op/func case is pretty bulky, so split it out
924+
* as a separate function.
1016925
*/
1017-
resultType=typeidType(result_typeid);
1018-
return (Node*)makeConst(result_typeid,typeLen(resultType),
1019-
const_val,const_is_null,
1020-
typeByVal(resultType),
1021-
false, false);
1022-
}
926+
newexpr=simplify_op_or_func(expr,args);
927+
if (newexpr)/* successfully simplified it */
928+
return (Node*)newexpr;
929+
/* else fall out to build new Expr node with simplified args */
930+
break;
1023931
caseOR_EXPR:
1024932
{
1025933
/*
@@ -1163,10 +1071,7 @@ eval_const_expressions_mutator (Node *node, void *context)
11631071
/*
11641072
* If we can simplify the input to a constant, then we don't need
11651073
* the RelabelType node anymore: just change the type field of
1166-
* the Const node. Otherwise keep the RelabelType node.
1167-
*
1168-
* XXX if relabel has a nondefault resulttypmod, do we need to
1169-
* keep it to show that? At present I don't think so.
1074+
* the Const node. Otherwise, copy the RelabelType node.
11701075
*/
11711076
RelabelType*relabel= (RelabelType*)node;
11721077
Node*arg;
@@ -1177,6 +1082,11 @@ eval_const_expressions_mutator (Node *node, void *context)
11771082
Const*con= (Const*)arg;
11781083

11791084
con->consttype=relabel->resulttype;
1085+
/*
1086+
* relabel's resulttypmod is discarded, which is OK for now;
1087+
* if the type actually needs a runtime length coercion then
1088+
* there should be a function call to do it just above this node.
1089+
*/
11801090
return (Node*)con;
11811091
}
11821092
else
@@ -1296,6 +1206,120 @@ eval_const_expressions_mutator (Node *node, void *context)
12961206
(void*)context);
12971207
}
12981208

1209+
/*
1210+
* Subroutine for eval_const_expressions: try to evaluate an op or func
1211+
*
1212+
* Inputs are the op or func Expr node, and the pre-simplified argument list.
1213+
* Returns a simplified expression if successful, or NULL if cannot
1214+
* simplify the op/func.
1215+
*
1216+
* XXX Possible future improvement: if the func is SQL-language, and its
1217+
* definition is simply "SELECT expression", we could parse and substitute
1218+
* the expression here. This would avoid much runtime overhead, and perhaps
1219+
* expose opportunities for constant-folding within the expression even if
1220+
* not all the func's input args are constants. It'd be appropriate to do
1221+
* here, and not in the parser, since we wouldn't want it to happen until
1222+
* after rule substitution/rewriting.
1223+
*/
1224+
staticExpr*
1225+
simplify_op_or_func(Expr*expr,List*args)
1226+
{
1227+
List*arg;
1228+
Oidfuncid;
1229+
Oidresult_typeid;
1230+
HeapTuplefunc_tuple;
1231+
Form_pg_procfuncform;
1232+
TyperesultType;
1233+
Expr*newexpr;
1234+
Datumconst_val;
1235+
boolconst_is_null;
1236+
boolisDone;
1237+
1238+
/*
1239+
* For an operator or function, we cannot simplify unless all the inputs
1240+
* are constants. (XXX possible future improvement: if the op/func is
1241+
* strict and at least one input is NULL, we could simplify to NULL.
1242+
* But we do not currently have any way to know if the op/func is strict
1243+
* or not. For now, a NULL input is treated the same as any other
1244+
* constant node.)
1245+
*/
1246+
foreach(arg,args)
1247+
{
1248+
if (!IsA(lfirst(arg),Const))
1249+
returnNULL;
1250+
}
1251+
/*
1252+
* Get the function procedure's OID and look to see
1253+
* whether it is marked proiscachable.
1254+
*/
1255+
if (expr->opType==OP_EXPR)
1256+
{
1257+
Oper*oper= (Oper*)expr->oper;
1258+
1259+
replace_opid(oper);/* OK to scribble on input to this extent */
1260+
funcid=oper->opid;
1261+
result_typeid=oper->opresulttype;
1262+
}
1263+
else
1264+
{
1265+
Func*func= (Func*)expr->oper;
1266+
1267+
funcid=func->funcid;
1268+
result_typeid=func->functype;
1269+
}
1270+
/* Someday lsyscache.c might provide a function for this */
1271+
func_tuple=SearchSysCacheTuple(PROCOID,
1272+
ObjectIdGetDatum(funcid),
1273+
0,0,0);
1274+
if (!HeapTupleIsValid(func_tuple))
1275+
elog(ERROR,"Function OID %u does not exist",funcid);
1276+
funcform= (Form_pg_proc)GETSTRUCT(func_tuple);
1277+
if (!funcform->proiscachable)
1278+
returnNULL;
1279+
/*
1280+
* Also check to make sure it doesn't return a set.
1281+
*/
1282+
if (funcform->proretset)
1283+
returnNULL;
1284+
/*
1285+
* OK, looks like we can simplify this operator/function.
1286+
*
1287+
* We use the executor's routine ExecEvalExpr() to avoid duplication of
1288+
* code and ensure we get the same result as the executor would get.
1289+
*
1290+
* Build a new Expr node containing the already-simplified arguments.
1291+
* The only other setup needed here is the replace_opid() that we already
1292+
* did for the OP_EXPR case.
1293+
*/
1294+
newexpr=makeNode(Expr);
1295+
newexpr->typeOid=expr->typeOid;
1296+
newexpr->opType=expr->opType;
1297+
newexpr->oper=expr->oper;
1298+
newexpr->args=args;
1299+
/*
1300+
* It is OK to pass econtext = NULL because none of the ExecEvalExpr()
1301+
* code used in this situation will use econtext. That might seem
1302+
* fortuitous, but it's not so unreasonable --- a constant expression does
1303+
* not depend on context, by definition, n'est ce pas?
1304+
*/
1305+
const_val=ExecEvalExpr((Node*)newexpr,NULL,
1306+
&const_is_null,&isDone);
1307+
Assert(isDone);/* if this isn't set, we blew it... */
1308+
pfree(newexpr);
1309+
/*
1310+
* Make the constant result node.
1311+
*
1312+
* XXX would it be better to take the result type from the
1313+
* pg_proc tuple, rather than the Oper or Func node?
1314+
*/
1315+
resultType=typeidType(result_typeid);
1316+
return (Expr*)makeConst(result_typeid,typeLen(resultType),
1317+
const_val,const_is_null,
1318+
typeByVal(resultType),
1319+
false, false);
1320+
}
1321+
1322+
12991323
/*
13001324
* Standard expression-tree walking support
13011325
*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp