9
9
*
10
10
*
11
11
* IDENTIFICATION
12
- * $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.3 2002/04/27 03:45:01 tgl Exp $
12
+ * $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.4 2002/05/17 18:32:52 petere Exp $
13
13
*
14
14
* DESCRIPTION
15
15
* These routines take the parse tree and pick out the
@@ -159,6 +159,104 @@ compute_parameter_types(List *argTypes, Oid languageOid,
159
159
return parameterCount ;
160
160
}
161
161
162
+
163
+ /*
164
+ * Dissect the list of options assembled in gram.y into function
165
+ * attributes.
166
+ */
167
+
168
+ static void
169
+ compute_attributes_sql_style (const List * options ,
170
+ List * * as ,
171
+ char * * language ,
172
+ char * volatility_p ,
173
+ bool * strict_p ,
174
+ bool * security_definer ,
175
+ bool * implicit_cast )
176
+ {
177
+ const List * option ;
178
+ DefElem * as_item = NULL ;
179
+ DefElem * language_item = NULL ;
180
+ DefElem * volatility_item = NULL ;
181
+ DefElem * strict_item = NULL ;
182
+ DefElem * security_item = NULL ;
183
+ DefElem * implicit_item = NULL ;
184
+
185
+ foreach (option , options )
186
+ {
187
+ DefElem * defel = (DefElem * ) lfirst (option );
188
+
189
+ if (strcmp (defel -> defname , "as" )== 0 )
190
+ {
191
+ if (as_item )
192
+ elog (ERROR , "conflicting or redundant options" );
193
+ as_item = defel ;
194
+ }
195
+ else if (strcmp (defel -> defname , "language" )== 0 )
196
+ {
197
+ if (language_item )
198
+ elog (ERROR , "conflicting or redundant options" );
199
+ language_item = defel ;
200
+ }
201
+ else if (strcmp (defel -> defname , "volatility" )== 0 )
202
+ {
203
+ if (volatility_item )
204
+ elog (ERROR , "conflicting or redundant options" );
205
+ volatility_item = defel ;
206
+ }
207
+ else if (strcmp (defel -> defname , "strict" )== 0 )
208
+ {
209
+ if (strict_item )
210
+ elog (ERROR , "conflicting or redundant options" );
211
+ strict_item = defel ;
212
+ }
213
+ else if (strcmp (defel -> defname , "security" )== 0 )
214
+ {
215
+ if (security_item )
216
+ elog (ERROR , "conflicting or redundant options" );
217
+ security_item = defel ;
218
+ }
219
+ else if (strcmp (defel -> defname , "implicit" )== 0 )
220
+ {
221
+ if (implicit_item )
222
+ elog (ERROR , "conflicting or redundant options" );
223
+ implicit_item = defel ;
224
+ }
225
+ else
226
+ elog (ERROR , "invalid CREATE FUNCTION option" );
227
+ }
228
+
229
+ if (as_item )
230
+ * as = (List * )as_item -> arg ;
231
+ else
232
+ elog (ERROR , "no function body specified" );
233
+
234
+ if (language_item )
235
+ * language = strVal (language_item -> arg );
236
+ else
237
+ elog (ERROR , "no language specified" );
238
+
239
+ if (volatility_item )
240
+ {
241
+ if (strcmp (strVal (volatility_item -> arg ), "immutable" )== 0 )
242
+ * volatility_p = PROVOLATILE_IMMUTABLE ;
243
+ else if (strcmp (strVal (volatility_item -> arg ), "stable" )== 0 )
244
+ * volatility_p = PROVOLATILE_STABLE ;
245
+ else if (strcmp (strVal (volatility_item -> arg ), "volatile" )== 0 )
246
+ * volatility_p = PROVOLATILE_VOLATILE ;
247
+ else
248
+ elog (ERROR , "invalid volatility" );
249
+ }
250
+
251
+ if (strict_item )
252
+ * strict_p = intVal (strict_item -> arg );
253
+ if (security_item )
254
+ * security_definer = intVal (security_item -> arg );
255
+ if (implicit_item )
256
+ * implicit_cast = intVal (implicit_item -> arg );
257
+ }
258
+
259
+
162
260
/*-------------
163
261
* Interpret the parameters *parameters and return their contents as
164
262
* *byte_pct_p, etc.
@@ -183,23 +281,14 @@ compute_parameter_types(List *argTypes, Oid languageOid,
183
281
*------------
184
282
*/
185
283
static void
186
- compute_full_attributes (List * parameters ,
187
- int32 * byte_pct_p , int32 * perbyte_cpu_p ,
188
- int32 * percall_cpu_p , int32 * outin_ratio_p ,
189
- bool * isImplicit_p , bool * isStrict_p ,
190
- char * volatility_p )
284
+ compute_attributes_with_style (List * parameters ,
285
+ int32 * byte_pct_p , int32 * perbyte_cpu_p ,
286
+ int32 * percall_cpu_p , int32 * outin_ratio_p ,
287
+ bool * isImplicit_p , bool * isStrict_p ,
288
+ char * volatility_p )
191
289
{
192
290
List * pl ;
193
291
194
- /* the defaults */
195
- * byte_pct_p = BYTE_PCT ;
196
- * perbyte_cpu_p = PERBYTE_CPU ;
197
- * percall_cpu_p = PERCALL_CPU ;
198
- * outin_ratio_p = OUTIN_RATIO ;
199
- * isImplicit_p = false;
200
- * isStrict_p = false;
201
- * volatility_p = PROVOLATILE_VOLATILE ;
202
-
203
292
foreach (pl , parameters )
204
293
{
205
294
DefElem * param = (DefElem * ) lfirst (pl );
@@ -290,12 +379,13 @@ interpret_AS_clause(Oid languageOid, const char *languageName, const List *as,
290
379
* Execute a CREATE FUNCTION utility statement.
291
380
*/
292
381
void
293
- CreateFunction (ProcedureStmt * stmt )
382
+ CreateFunction (CreateFunctionStmt * stmt )
294
383
{
295
384
char * probin_str ;
296
385
char * prosrc_str ;
297
386
Oid prorettype ;
298
387
bool returnsSet ;
388
+ char * language ;
299
389
char languageName [NAMEDATALEN ];
300
390
Oid languageOid ;
301
391
char * funcname ;
@@ -308,10 +398,12 @@ CreateFunction(ProcedureStmt *stmt)
308
398
percall_cpu ,
309
399
outin_ratio ;
310
400
bool isImplicit ,
311
- isStrict ;
401
+ isStrict ,
402
+ security ;
312
403
char volatility ;
313
404
HeapTuple languageTuple ;
314
405
Form_pg_language languageStruct ;
406
+ List * as_clause ;
315
407
316
408
/* Convert list of names to a name and namespace */
317
409
namespaceId = QualifiedNameGetCreationNamespace (stmt -> funcname ,
@@ -322,8 +414,21 @@ CreateFunction(ProcedureStmt *stmt)
322
414
if (aclresult != ACLCHECK_OK )
323
415
aclcheck_error (aclresult , get_namespace_name (namespaceId ));
324
416
417
+ /* defaults attributes */
418
+ byte_pct = BYTE_PCT ;
419
+ perbyte_cpu = PERBYTE_CPU ;
420
+ percall_cpu = PERCALL_CPU ;
421
+ outin_ratio = OUTIN_RATIO ;
422
+ isImplicit = false;
423
+ isStrict = false;
424
+ volatility = PROVOLATILE_VOLATILE ;
425
+
426
+ /* override attributes from explicit list */
427
+ compute_attributes_sql_style (stmt -> options ,
428
+ & as_clause , & language , & volatility , & isStrict , & security , & isImplicit );
429
+
325
430
/* Convert language name to canonical case */
326
- case_translate_language_name (stmt -> language , languageName );
431
+ case_translate_language_name (language , languageName );
327
432
328
433
/* Look up the language and validate permissions */
329
434
languageTuple = SearchSysCache (LANGNAME ,
@@ -363,12 +468,12 @@ CreateFunction(ProcedureStmt *stmt)
363
468
parameterCount = compute_parameter_types (stmt -> argTypes , languageOid ,
364
469
parameterTypes );
365
470
366
- compute_full_attributes (stmt -> withClause ,
367
- & byte_pct , & perbyte_cpu , & percall_cpu ,
368
- & outin_ratio , & isImplicit , & isStrict ,
369
- & volatility );
471
+ compute_attributes_with_style (stmt -> withClause ,
472
+ & byte_pct , & perbyte_cpu , & percall_cpu ,
473
+ & outin_ratio , & isImplicit , & isStrict ,
474
+ & volatility );
370
475
371
- interpret_AS_clause (languageOid , languageName , stmt -> as ,
476
+ interpret_AS_clause (languageOid , languageName , as_clause ,
372
477
& prosrc_str , & probin_str );
373
478
374
479
/*
0 commit comments