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

Commit6eb8d25

Browse files
committed
Allow CREATE FUNCTION's WITH clause to be used for all language types,
not just C, so that ISCACHABLE attribute can be specified for user-definedfunctions. Get rid of ParamString node type, which wasn't actually beinggenerated by gram.y anymore, even though define.c thought that was whatit was getting. Clean up minor bug in dfmgr.c (premature heap_close).
1 parente23a2b1 commit6eb8d25

File tree

7 files changed

+117
-137
lines changed

7 files changed

+117
-137
lines changed

‎src/backend/commands/define.c

Lines changed: 89 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.35 1999/09/28 04:34:40 momjian Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.36 1999/10/02 21:33:24 tgl Exp $
1313
*
1414
* DESCRIPTION
1515
* The "DefineFoo" routines take the parse tree and pick out the
@@ -53,6 +53,7 @@
5353
#include"utils/syscache.h"
5454

5555
staticchar*defGetString(DefElem*def);
56+
staticdoubledefGetNumeric(DefElem*def);
5657
staticintdefGetTypeLength(DefElem*def);
5758

5859
#defineDEFAULT_TYPDELIM','
@@ -103,17 +104,26 @@ compute_return_type(const Node *returnType,
103104
}
104105

105106

106-
107107
staticvoid
108-
compute_full_attributes(constList*parameters,int32*byte_pct_p,
108+
compute_full_attributes(List*parameters,int32*byte_pct_p,
109109
int32*perbyte_cpu_p,int32*percall_cpu_p,
110110
int32*outin_ratio_p,bool*canCache_p)
111111
{
112112
/*--------------------------------------------------------------------------
113113
Interpret the parameters *parameters and return their contents as
114114
*byte_pct_p, etc.
115115
116-
These are the full parameters of a C or internal function.
116+
These parameters supply optional information about a function.
117+
All have defaults if not specified.
118+
119+
Note: as of version 6.6, canCache is used (if set, the optimizer's
120+
constant-folder is allowed to pre-evaluate the function if all its
121+
inputs are constant). The other four are not used. They used to be
122+
used in the "expensive functions" optimizer, but that's been dead code
123+
for a long time.
124+
125+
Since canCache is useful for any function, we now allow attributes to be
126+
supplied for all functions regardless of language.
117127
---------------------------------------------------------------------------*/
118128
List*pl;
119129

@@ -122,58 +132,33 @@ compute_full_attributes(const List *parameters, int32 *byte_pct_p,
122132
*perbyte_cpu_p=PERBYTE_CPU;
123133
*percall_cpu_p=PERCALL_CPU;
124134
*outin_ratio_p=OUTIN_RATIO;
135+
*canCache_p= false;
125136

126-
foreach(pl,(List*)parameters)
137+
foreach(pl,parameters)
127138
{
128-
ParamString*param= (ParamString*)lfirst(pl);
139+
DefElem*param= (DefElem*)lfirst(pl);
129140

130-
if (strcasecmp(param->name,"iscachable")==0)
141+
if (strcasecmp(param->defname,"iscachable")==0)
131142
*canCache_p= true;
132-
elseif (strcasecmp(param->name,"trusted")==0)
143+
elseif (strcasecmp(param->defname,"trusted")==0)
133144
{
134-
135145
/*
136146
* we don't have untrusted functions any more. The 4.2
137147
* implementation is lousy anyway so I took it out. -ay 10/94
138148
*/
139149
elog(ERROR,"untrusted function has been decommissioned.");
140150
}
141-
elseif (strcasecmp(param->name,"byte_pct")==0)
142-
{
143-
144-
/*
145-
* * handle expensive function parameters
146-
*/
147-
*byte_pct_p=atoi(param->val);
148-
}
149-
elseif (strcasecmp(param->name,"perbyte_cpu")==0)
150-
{
151-
if (sscanf(param->val,"%d",perbyte_cpu_p)==0)
152-
{
153-
intcount;
154-
char*ptr;
155-
156-
for (count=0,ptr=param->val;*ptr!='\0';ptr++)
157-
if (*ptr=='!')
158-
count++;
159-
*perbyte_cpu_p= (int)pow(10.0, (double)count);
160-
}
161-
}
162-
elseif (strcasecmp(param->name,"percall_cpu")==0)
163-
{
164-
if (sscanf(param->val,"%d",percall_cpu_p)==0)
165-
{
166-
intcount;
167-
char*ptr;
168-
169-
for (count=0,ptr=param->val;*ptr!='\0';ptr++)
170-
if (*ptr=='!')
171-
count++;
172-
*percall_cpu_p= (int)pow(10.0, (double)count);
173-
}
174-
}
175-
elseif (strcasecmp(param->name,"outin_ratio")==0)
176-
*outin_ratio_p=atoi(param->val);
151+
elseif (strcasecmp(param->defname,"byte_pct")==0)
152+
*byte_pct_p= (int)defGetNumeric(param);
153+
elseif (strcasecmp(param->defname,"perbyte_cpu")==0)
154+
*perbyte_cpu_p= (int)defGetNumeric(param);
155+
elseif (strcasecmp(param->defname,"percall_cpu")==0)
156+
*percall_cpu_p= (int)defGetNumeric(param);
157+
elseif (strcasecmp(param->defname,"outin_ratio")==0)
158+
*outin_ratio_p= (int)defGetNumeric(param);
159+
else
160+
elog(NOTICE,"Unrecognized function attribute '%s' ignored",
161+
param->defname);
177162
}
178163
}
179164

@@ -215,8 +200,8 @@ interpret_AS_clause(const char *languageName, const List *as,
215200
*probin_str_p="-";
216201

217202
if (lnext(as)!=NULL)
218-
elog(ERROR,"CREATE FUNCTION:parse error in 'AS%s, %s'.",
219-
strVal(lfirst(as)),strVal(lsecond(as)));
203+
elog(ERROR,"CREATE FUNCTION:only oneASitem needed for %s language",
204+
languageName);
220205
}
221206
}
222207

@@ -246,39 +231,37 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
246231
* or "SQL"
247232
*/
248233

234+
boolreturnsSet;
235+
/* The function returns a set of values, as opposed to a singleton. */
236+
237+
boollanisPL= false;
238+
249239
/*
250-
* The following are attributes of the function, as expressed in the
251-
* CREATE FUNCTION statement, where applicable.
240+
* The following are optional user-supplied attributes of the function.
252241
*/
253242
int32byte_pct,
254243
perbyte_cpu,
255244
percall_cpu,
256245
outin_ratio;
257246
boolcanCache;
258-
boolreturnsSet;
259-
260-
boollanisPL= false;
261-
262-
/* The function returns a set of values, as opposed to a singleton. */
263247

264248

265249
case_translate_language_name(stmt->language,languageName);
266250

267-
compute_return_type(stmt->returnType,&prorettype,&returnsSet);
268-
269251
if (strcmp(languageName,"C")==0||
270252
strcmp(languageName,"internal")==0)
271253
{
272-
compute_full_attributes(stmt->withClause,
273-
&byte_pct,&perbyte_cpu,&percall_cpu,
274-
&outin_ratio,&canCache);
254+
if (!superuser())
255+
elog(ERROR,
256+
"Only users with Postgres superuser privilege are "
257+
"permitted to create a function "
258+
"in the '%s' language. Others may use the 'sql' language "
259+
"or the created procedural languages.",
260+
languageName);
275261
}
276262
elseif (strcmp(languageName,"sql")==0)
277263
{
278-
/* query optimizer groks sql, these are meaningless */
279-
perbyte_cpu=percall_cpu=0;
280-
byte_pct=outin_ratio=100;
281-
canCache= false;
264+
/* No security check needed for SQL functions */
282265
}
283266
else
284267
{
@@ -321,47 +304,34 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
321304
}
322305

323306
lanisPL= true;
324-
325-
/*
326-
* These are meaningless
327-
*/
328-
perbyte_cpu=percall_cpu=0;
329-
byte_pct=outin_ratio=100;
330-
canCache= false;
331307
}
332308

333-
interpret_AS_clause(languageName,stmt->as,&prosrc_str,&probin_str);
309+
compute_return_type(stmt->returnType,&prorettype,&returnsSet);
334310

335-
if (strcmp(languageName,"sql")!=0&&lanisPL== false&& !superuser())
336-
elog(ERROR,
337-
"Only users with Postgres superuser privilege are permitted "
338-
"to create a function "
339-
"in the '%s' language. Others may use the 'sql' language "
340-
"or the created procedural languages.",
341-
languageName);
342-
/* Above does not return. */
343-
else
344-
{
311+
compute_full_attributes(stmt->withClause,
312+
&byte_pct,&perbyte_cpu,&percall_cpu,
313+
&outin_ratio,&canCache);
345314

346-
/*
347-
* And now that we have all the parameters, and know we're
348-
* permitted to do so, go ahead and create the function.
349-
*/
350-
ProcedureCreate(stmt->funcname,
351-
returnsSet,
352-
prorettype,
353-
languageName,
354-
prosrc_str,/* converted to text later */
355-
probin_str,/* converted to text later */
356-
canCache,
357-
true,/* (obsolete "trusted") */
358-
byte_pct,
359-
perbyte_cpu,
360-
percall_cpu,
361-
outin_ratio,
362-
stmt->defArgs,
363-
dest);
364-
}
315+
interpret_AS_clause(languageName,stmt->as,&prosrc_str,&probin_str);
316+
317+
/*
318+
* And now that we have all the parameters, and know we're
319+
* permitted to do so, go ahead and create the function.
320+
*/
321+
ProcedureCreate(stmt->funcname,
322+
returnsSet,
323+
prorettype,
324+
languageName,
325+
prosrc_str,/* converted to text later */
326+
probin_str,/* converted to text later */
327+
canCache,
328+
true,/* (obsolete "trusted") */
329+
byte_pct,
330+
perbyte_cpu,
331+
percall_cpu,
332+
outin_ratio,
333+
stmt->defArgs,
334+
dest);
365335
}
366336

367337

@@ -734,6 +704,25 @@ defGetString(DefElem *def)
734704
returnstrVal(def->arg);
735705
}
736706

707+
staticdouble
708+
defGetNumeric(DefElem*def)
709+
{
710+
if (def->arg==NULL)
711+
elog(ERROR,"Define: \"%s\" requires a numeric value",
712+
def->defname);
713+
switch (nodeTag(def->arg))
714+
{
715+
caseT_Integer:
716+
return (double)intVal(def->arg);
717+
caseT_Float:
718+
returnfloatVal(def->arg);
719+
default:
720+
elog(ERROR,"Define: \"%s\" requires a numeric value",
721+
def->defname);
722+
}
723+
return0;/* keep compiler quiet */
724+
}
725+
737726
staticint
738727
defGetTypeLength(DefElem*def)
739728
{

‎src/backend/commands/indexcmds.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.11 1999/09/18 19:06:40 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.12 1999/10/02 21:33:24 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -50,7 +50,7 @@ static char *GetDefaultOpClass(Oid atttypid);
5050
*
5151
* 'attributeList' is a list of IndexElem specifying either a functional
5252
*index or a list of attributes to index on.
53-
* 'parameterList' is a list ofParamString specified in the with clause.
53+
* 'parameterList' is a list ofDefElem specified in the with clause.
5454
* 'predicate' is the qual specified in the where clause.
5555
* 'rangetable' is for the predicate
5656
*
@@ -116,22 +116,20 @@ DefineIndex(char *heapRelationName,
116116
}
117117
accessMethodId=tuple->t_data->t_oid;
118118

119-
120119
/*
121-
* Handle parameters [param list is now different (NOT USED, really) -
122-
* ay 10/94]
123-
*
124120
* WITH clause reinstated to handle lossy indices. -- JMH, 7/22/96
125121
*/
126122
foreach(pl,parameterList)
127123
{
128-
ParamString*param= (ParamString*)lfirst(pl);
124+
DefElem*param= (DefElem*)lfirst(pl);
129125

130-
if (!strcasecmp(param->name,"islossy"))
126+
if (!strcasecmp(param->defname,"islossy"))
131127
lossy= TRUE;
128+
else
129+
elog(NOTICE,"Unrecognized index attribute '%s' ignored",
130+
param->defname);
132131
}
133132

134-
135133
/*
136134
* Convert the partial-index predicate from parsetree form to plan
137135
* form, so it can be readily evaluated during index creation. Note:

‎src/backend/parser/gram.y

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.104 1999/09/29 16:06:06 wieck Exp $
13+
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.105 1999/10/02 21:33:21 tgl Exp $
1414
*
1515
* HISTORY
1616
* AUTHORDATEMAJOR EVENT
@@ -103,7 +103,6 @@ Oidparam_type(int t); /* used in parse_expr.c */
103103

104104
TypeName*typnam;
105105
DefElem*defelt;
106-
ParamString*param;
107106
SortGroupBy*sortgroupby;
108107
JoinExpr*joinexpr;
109108
IndexElem*ielem;

‎src/backend/utils/fmgr/dfmgr.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.34 1999/09/28 11:27:13 vadim Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.35 1999/10/02 21:33:25 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -42,15 +42,16 @@ fmgr_dynamic(Oid procedureId, int *pronargs)
4242
HeapTupleprocedureTuple;
4343
Form_pg_procprocedureStruct;
4444
char*proname,
45-
*probinstring,
46-
*prosrcstring,
47-
*linksymbol;
45+
*linksymbol,
46+
*probinstring;
47+
char*prosrcstring=NULL;
4848
Datumprobinattr;
4949
Datumprosrcattr;
5050
func_ptruser_fn;
5151
Relationrel;
5252
boolisnull;
5353

54+
/* Implement simple one-element cache for function lookups */
5455
if (procedureId==procedureId_save)
5556
{
5657
*pronargs=pronargs_save;
@@ -91,8 +92,6 @@ fmgr_dynamic(Oid procedureId, int *pronargs)
9192
}
9293
probinstring=textout((structvarlena*)probinattr);
9394

94-
heap_close(rel,AccessShareLock);
95-
9695
prosrcattr=heap_getattr(procedureTuple,
9796
Anum_pg_proc_prosrc,
9897
RelationGetDescr(rel),&isnull);
@@ -118,9 +117,12 @@ fmgr_dynamic(Oid procedureId, int *pronargs)
118117
linksymbol=prosrcstring;
119118
}
120119

120+
heap_close(rel,AccessShareLock);
121+
121122
user_fn=handle_load(probinstring,linksymbol);
122123

123124
pfree(probinstring);
125+
if (prosrcstring)pfree(prosrcstring);
124126

125127
procedureId_save=procedureId;
126128
user_fn_save=user_fn;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp