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

Commit0bb51aa

Browse files
committed
Improve parsetree representation of special functions such as CURRENT_DATE.
We implement a dozen or so parameterless functions that the SQL standarddefines special syntax for. Up to now, that was done by converting theminto more or less ad-hoc constructs such as "'now'::text::date". That'smessy for multiple reasons: it exposes what should be implementationdetails to users, and performance is worse than it needs to be in severalcases. To improve matters, invent a new expression node typeSQLValueFunction that can represent any of these parameterless functions.Bump catversion because this changes stored parsetrees for rules.Discussion: <30058.1463091294@sss.pgh.pa.us>
1 parent4bc4cfe commit0bb51aa

File tree

24 files changed

+626
-168
lines changed

24 files changed

+626
-168
lines changed

‎contrib/pg_stat_statements/pg_stat_statements.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2632,6 +2632,15 @@ JumbleExpr(pgssJumbleState *jstate, Node *node)
26322632
JumbleExpr(jstate, (Node*)mmexpr->args);
26332633
}
26342634
break;
2635+
caseT_SQLValueFunction:
2636+
{
2637+
SQLValueFunction*svf= (SQLValueFunction*)node;
2638+
2639+
APP_JUMB(svf->op);
2640+
/* type is fully determined by op */
2641+
APP_JUMB(svf->typmod);
2642+
}
2643+
break;
26352644
caseT_XmlExpr:
26362645
{
26372646
XmlExpr*xexpr= (XmlExpr*)node;

‎src/backend/executor/execQual.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,10 @@
5353
#include"pgstat.h"
5454
#include"utils/acl.h"
5555
#include"utils/builtins.h"
56+
#include"utils/date.h"
5657
#include"utils/lsyscache.h"
5758
#include"utils/memutils.h"
59+
#include"utils/timestamp.h"
5860
#include"utils/typcache.h"
5961
#include"utils/xml.h"
6062

@@ -147,6 +149,9 @@ static Datum ExecEvalCoalesce(CoalesceExprState *coalesceExpr,
147149
staticDatumExecEvalMinMax(MinMaxExprState*minmaxExpr,
148150
ExprContext*econtext,
149151
bool*isNull,ExprDoneCond*isDone);
152+
staticDatumExecEvalSQLValueFunction(ExprState*svfExpr,
153+
ExprContext*econtext,
154+
bool*isNull,ExprDoneCond*isDone);
150155
staticDatumExecEvalXml(XmlExprState*xmlExpr,ExprContext*econtext,
151156
bool*isNull,ExprDoneCond*isDone);
152157
staticDatumExecEvalNullIf(FuncExprState*nullIfExpr,
@@ -3530,6 +3535,75 @@ ExecEvalMinMax(MinMaxExprState *minmaxExpr, ExprContext *econtext,
35303535
returnresult;
35313536
}
35323537

3538+
/* ----------------------------------------------------------------
3539+
*ExecEvalSQLValueFunction
3540+
* ----------------------------------------------------------------
3541+
*/
3542+
staticDatum
3543+
ExecEvalSQLValueFunction(ExprState*svfExpr,
3544+
ExprContext*econtext,
3545+
bool*isNull,ExprDoneCond*isDone)
3546+
{
3547+
Datumresult= (Datum)0;
3548+
SQLValueFunction*svf= (SQLValueFunction*)svfExpr->expr;
3549+
FunctionCallInfoDatafcinfo;
3550+
3551+
if (isDone)
3552+
*isDone=ExprSingleResult;
3553+
*isNull= false;
3554+
3555+
/*
3556+
* Note: current_schema() can return NULL. current_user() etc currently
3557+
* cannot, but might as well code those cases the same way for safety.
3558+
*/
3559+
switch (svf->op)
3560+
{
3561+
caseSVFOP_CURRENT_DATE:
3562+
result=DateADTGetDatum(GetSQLCurrentDate());
3563+
break;
3564+
caseSVFOP_CURRENT_TIME:
3565+
caseSVFOP_CURRENT_TIME_N:
3566+
result=TimeTzADTPGetDatum(GetSQLCurrentTime(svf->typmod));
3567+
break;
3568+
caseSVFOP_CURRENT_TIMESTAMP:
3569+
caseSVFOP_CURRENT_TIMESTAMP_N:
3570+
result=TimestampTzGetDatum(GetSQLCurrentTimestamp(svf->typmod));
3571+
break;
3572+
caseSVFOP_LOCALTIME:
3573+
caseSVFOP_LOCALTIME_N:
3574+
result=TimeADTGetDatum(GetSQLLocalTime(svf->typmod));
3575+
break;
3576+
caseSVFOP_LOCALTIMESTAMP:
3577+
caseSVFOP_LOCALTIMESTAMP_N:
3578+
result=TimestampGetDatum(GetSQLLocalTimestamp(svf->typmod));
3579+
break;
3580+
caseSVFOP_CURRENT_ROLE:
3581+
caseSVFOP_CURRENT_USER:
3582+
caseSVFOP_USER:
3583+
InitFunctionCallInfoData(fcinfo,NULL,0,InvalidOid,NULL,NULL);
3584+
result=current_user(&fcinfo);
3585+
*isNull=fcinfo.isnull;
3586+
break;
3587+
caseSVFOP_SESSION_USER:
3588+
InitFunctionCallInfoData(fcinfo,NULL,0,InvalidOid,NULL,NULL);
3589+
result=session_user(&fcinfo);
3590+
*isNull=fcinfo.isnull;
3591+
break;
3592+
caseSVFOP_CURRENT_CATALOG:
3593+
InitFunctionCallInfoData(fcinfo,NULL,0,InvalidOid,NULL,NULL);
3594+
result=current_database(&fcinfo);
3595+
*isNull=fcinfo.isnull;
3596+
break;
3597+
caseSVFOP_CURRENT_SCHEMA:
3598+
InitFunctionCallInfoData(fcinfo,NULL,0,InvalidOid,NULL,NULL);
3599+
result=current_schema(&fcinfo);
3600+
*isNull=fcinfo.isnull;
3601+
break;
3602+
}
3603+
3604+
returnresult;
3605+
}
3606+
35333607
/* ----------------------------------------------------------------
35343608
*ExecEvalXml
35353609
* ----------------------------------------------------------------
@@ -5086,6 +5160,10 @@ ExecInitExpr(Expr *node, PlanState *parent)
50865160
state= (ExprState*)mstate;
50875161
}
50885162
break;
5163+
caseT_SQLValueFunction:
5164+
state= (ExprState*)makeNode(ExprState);
5165+
state->evalfunc=ExecEvalSQLValueFunction;
5166+
break;
50895167
caseT_XmlExpr:
50905168
{
50915169
XmlExpr*xexpr= (XmlExpr*)node;

‎src/backend/nodes/copyfuncs.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1752,6 +1752,22 @@ _copyMinMaxExpr(const MinMaxExpr *from)
17521752
returnnewnode;
17531753
}
17541754

1755+
/*
1756+
* _copySQLValueFunction
1757+
*/
1758+
staticSQLValueFunction*
1759+
_copySQLValueFunction(constSQLValueFunction*from)
1760+
{
1761+
SQLValueFunction*newnode=makeNode(SQLValueFunction);
1762+
1763+
COPY_SCALAR_FIELD(op);
1764+
COPY_SCALAR_FIELD(type);
1765+
COPY_SCALAR_FIELD(typmod);
1766+
COPY_LOCATION_FIELD(location);
1767+
1768+
returnnewnode;
1769+
}
1770+
17551771
/*
17561772
* _copyXmlExpr
17571773
*/
@@ -4525,6 +4541,9 @@ copyObject(const void *from)
45254541
caseT_MinMaxExpr:
45264542
retval=_copyMinMaxExpr(from);
45274543
break;
4544+
caseT_SQLValueFunction:
4545+
retval=_copySQLValueFunction(from);
4546+
break;
45284547
caseT_XmlExpr:
45294548
retval=_copyXmlExpr(from);
45304549
break;

‎src/backend/nodes/equalfuncs.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,17 @@ _equalMinMaxExpr(const MinMaxExpr *a, const MinMaxExpr *b)
619619
return true;
620620
}
621621

622+
staticbool
623+
_equalSQLValueFunction(constSQLValueFunction*a,constSQLValueFunction*b)
624+
{
625+
COMPARE_SCALAR_FIELD(op);
626+
COMPARE_SCALAR_FIELD(type);
627+
COMPARE_SCALAR_FIELD(typmod);
628+
COMPARE_LOCATION_FIELD(location);
629+
630+
return true;
631+
}
632+
622633
staticbool
623634
_equalXmlExpr(constXmlExpr*a,constXmlExpr*b)
624635
{
@@ -2842,6 +2853,9 @@ equal(const void *a, const void *b)
28422853
caseT_MinMaxExpr:
28432854
retval=_equalMinMaxExpr(a,b);
28442855
break;
2856+
caseT_SQLValueFunction:
2857+
retval=_equalSQLValueFunction(a,b);
2858+
break;
28452859
caseT_XmlExpr:
28462860
retval=_equalXmlExpr(a,b);
28472861
break;

‎src/backend/nodes/nodeFuncs.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,9 @@ exprType(const Node *expr)
218218
caseT_MinMaxExpr:
219219
type= ((constMinMaxExpr*)expr)->minmaxtype;
220220
break;
221+
caseT_SQLValueFunction:
222+
type= ((constSQLValueFunction*)expr)->type;
223+
break;
221224
caseT_XmlExpr:
222225
if (((constXmlExpr*)expr)->op==IS_DOCUMENT)
223226
type=BOOLOID;
@@ -479,6 +482,8 @@ exprTypmod(const Node *expr)
479482
returntypmod;
480483
}
481484
break;
485+
caseT_SQLValueFunction:
486+
return ((constSQLValueFunction*)expr)->typmod;
482487
caseT_CoerceToDomain:
483488
return ((constCoerceToDomain*)expr)->resulttypmod;
484489
caseT_CoerceToDomainValue:
@@ -718,6 +723,8 @@ expression_returns_set_walker(Node *node, void *context)
718723
return false;
719724
if (IsA(node,MinMaxExpr))
720725
return false;
726+
if (IsA(node,SQLValueFunction))
727+
return false;
721728
if (IsA(node,XmlExpr))
722729
return false;
723730

@@ -883,6 +890,9 @@ exprCollation(const Node *expr)
883890
caseT_MinMaxExpr:
884891
coll= ((constMinMaxExpr*)expr)->minmaxcollid;
885892
break;
893+
caseT_SQLValueFunction:
894+
coll=InvalidOid;/* all cases return non-collatable types */
895+
break;
886896
caseT_XmlExpr:
887897

888898
/*
@@ -1091,6 +1101,9 @@ exprSetCollation(Node *expr, Oid collation)
10911101
caseT_MinMaxExpr:
10921102
((MinMaxExpr*)expr)->minmaxcollid=collation;
10931103
break;
1104+
caseT_SQLValueFunction:
1105+
Assert(!OidIsValid(collation));/* no collatable results */
1106+
break;
10941107
caseT_XmlExpr:
10951108
Assert((((XmlExpr*)expr)->op==IS_XMLSERIALIZE) ?
10961109
(collation==DEFAULT_COLLATION_OID) :
@@ -1364,6 +1377,10 @@ exprLocation(const Node *expr)
13641377
/* GREATEST/LEAST keyword should always be the first thing */
13651378
loc= ((constMinMaxExpr*)expr)->location;
13661379
break;
1380+
caseT_SQLValueFunction:
1381+
/* function keyword should always be the first thing */
1382+
loc= ((constSQLValueFunction*)expr)->location;
1383+
break;
13671384
caseT_XmlExpr:
13681385
{
13691386
constXmlExpr*xexpr= (constXmlExpr*)expr;
@@ -1633,9 +1650,10 @@ set_sa_opfuncid(ScalarArrayOpExpr *opexpr)
16331650
* for themselves, in case additional checks should be made, or because they
16341651
* have special rules about which parts of the tree need to be visited.
16351652
*
1636-
* Note: we ignore MinMaxExpr, XmlExpr, and CoerceToDomain nodes, because they
1637-
* do not contain SQL function OIDs. However, they can invoke SQL-visible
1638-
* functions, so callers should take thought about how to treat them.
1653+
* Note: we ignore MinMaxExpr, SQLValueFunction, XmlExpr, and CoerceToDomain
1654+
* nodes, because they do not contain SQL function OIDs. However, they can
1655+
* invoke SQL-visible functions, so callers should take thought about how to
1656+
* treat them.
16391657
*/
16401658
bool
16411659
check_functions_in_node(Node*node,check_function_callbackchecker,
@@ -1859,6 +1877,7 @@ expression_tree_walker(Node *node,
18591877
caseT_CaseTestExpr:
18601878
caseT_SetToDefault:
18611879
caseT_CurrentOfExpr:
1880+
caseT_SQLValueFunction:
18621881
caseT_RangeTblRef:
18631882
caseT_SortGroupClause:
18641883
/* primitive node types with no expression subnodes */
@@ -2433,6 +2452,7 @@ expression_tree_mutator(Node *node,
24332452
caseT_CaseTestExpr:
24342453
caseT_SetToDefault:
24352454
caseT_CurrentOfExpr:
2455+
caseT_SQLValueFunction:
24362456
caseT_RangeTblRef:
24372457
caseT_SortGroupClause:
24382458
return (Node*)copyObject(node);
@@ -3197,6 +3217,7 @@ raw_expression_tree_walker(Node *node,
31973217
{
31983218
caseT_SetToDefault:
31993219
caseT_CurrentOfExpr:
3220+
caseT_SQLValueFunction:
32003221
caseT_Integer:
32013222
caseT_Float:
32023223
caseT_String:

‎src/backend/nodes/outfuncs.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,6 +1423,17 @@ _outMinMaxExpr(StringInfo str, const MinMaxExpr *node)
14231423
WRITE_LOCATION_FIELD(location);
14241424
}
14251425

1426+
staticvoid
1427+
_outSQLValueFunction(StringInfostr,constSQLValueFunction*node)
1428+
{
1429+
WRITE_NODE_TYPE("SQLVALUEFUNCTION");
1430+
1431+
WRITE_ENUM_FIELD(op,SQLValueFunctionOp);
1432+
WRITE_OID_FIELD(type);
1433+
WRITE_INT_FIELD(typmod);
1434+
WRITE_LOCATION_FIELD(location);
1435+
}
1436+
14261437
staticvoid
14271438
_outXmlExpr(StringInfostr,constXmlExpr*node)
14281439
{
@@ -3522,6 +3533,9 @@ outNode(StringInfo str, const void *obj)
35223533
caseT_MinMaxExpr:
35233534
_outMinMaxExpr(str,obj);
35243535
break;
3536+
caseT_SQLValueFunction:
3537+
_outSQLValueFunction(str,obj);
3538+
break;
35253539
caseT_XmlExpr:
35263540
_outXmlExpr(str,obj);
35273541
break;

‎src/backend/nodes/readfuncs.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,6 +1041,22 @@ _readMinMaxExpr(void)
10411041
READ_DONE();
10421042
}
10431043

1044+
/*
1045+
* _readSQLValueFunction
1046+
*/
1047+
staticSQLValueFunction*
1048+
_readSQLValueFunction(void)
1049+
{
1050+
READ_LOCALS(SQLValueFunction);
1051+
1052+
READ_ENUM_FIELD(op,SQLValueFunctionOp);
1053+
READ_OID_FIELD(type);
1054+
READ_INT_FIELD(typmod);
1055+
READ_LOCATION_FIELD(location);
1056+
1057+
READ_DONE();
1058+
}
1059+
10441060
/*
10451061
* _readXmlExpr
10461062
*/
@@ -2348,6 +2364,8 @@ parseNodeString(void)
23482364
return_value=_readCoalesceExpr();
23492365
elseif (MATCH("MINMAX",6))
23502366
return_value=_readMinMaxExpr();
2367+
elseif (MATCH("SQLVALUEFUNCTION",16))
2368+
return_value=_readSQLValueFunction();
23512369
elseif (MATCH("XMLEXPR",7))
23522370
return_value=_readXmlExpr();
23532371
elseif (MATCH("NULLTEST",8))

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

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -962,6 +962,12 @@ contain_mutable_functions_walker(Node *node, void *context)
962962
context))
963963
return true;
964964

965+
if (IsA(node,SQLValueFunction))
966+
{
967+
/* all variants of SQLValueFunction are stable */
968+
return true;
969+
}
970+
965971
/*
966972
* It should be safe to treat MinMaxExpr as immutable, because it will
967973
* depend on a non-cross-type btree comparison function, and those should
@@ -1031,7 +1037,8 @@ contain_volatile_functions_walker(Node *node, void *context)
10311037

10321038
/*
10331039
* See notes in contain_mutable_functions_walker about why we treat
1034-
* MinMaxExpr, XmlExpr, and CoerceToDomain as immutable.
1040+
* MinMaxExpr, XmlExpr, and CoerceToDomain as immutable, while
1041+
* SQLValueFunction is stable. Hence, none of them are of interest here.
10351042
*/
10361043

10371044
/* Recurse to check arguments */
@@ -1076,7 +1083,8 @@ contain_volatile_functions_not_nextval_walker(Node *node, void *context)
10761083

10771084
/*
10781085
* See notes in contain_mutable_functions_walker about why we treat
1079-
* MinMaxExpr, XmlExpr, and CoerceToDomain as immutable.
1086+
* MinMaxExpr, XmlExpr, and CoerceToDomain as immutable, while
1087+
* SQLValueFunction is stable. Hence, none of them are of interest here.
10801088
*/
10811089

10821090
/* Recurse to check arguments */
@@ -1143,7 +1151,8 @@ has_parallel_hazard_walker(Node *node, has_parallel_hazard_arg *context)
11431151
* (Note: in principle that's wrong because a domain constraint could
11441152
* contain a parallel-unsafe function; but useful constraints probably
11451153
* never would have such, and assuming they do would cripple use of
1146-
* parallel query in the presence of domain types.)
1154+
* parallel query in the presence of domain types.) SQLValueFunction
1155+
* should be safe in all cases.
11471156
*/
11481157
if (IsA(node,CoerceToDomain))
11491158
{
@@ -1458,6 +1467,7 @@ contain_leaked_vars_walker(Node *node, void *context)
14581467
caseT_CaseTestExpr:
14591468
caseT_RowExpr:
14601469
caseT_MinMaxExpr:
1470+
caseT_SQLValueFunction:
14611471
caseT_NullTest:
14621472
caseT_BooleanTest:
14631473
caseT_List:

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp