aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/define.c189
-rw-r--r--src/backend/commands/indexcmds.c16
-rw-r--r--src/backend/parser/gram.y3
-rw-r--r--src/backend/utils/fmgr/dfmgr.c14
-rw-r--r--src/bin/psql/psqlHelp.h12
-rw-r--r--src/include/nodes/nodes.h4
-rw-r--r--src/include/nodes/parsenodes.h16
7 files changed, 117 insertions, 137 deletions
diff --git a/src/backend/commands/define.c b/src/backend/commands/define.c
index 509d5026d30..2aa197654c7 100644
--- a/src/backend/commands/define.c
+++ b/src/backend/commands/define.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.35 1999/09/28 04:34:40 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.36 1999/10/02 21:33:24 tgl Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
@@ -53,6 +53,7 @@
#include "utils/syscache.h"
static char *defGetString(DefElem *def);
+static double defGetNumeric(DefElem *def);
static int defGetTypeLength(DefElem *def);
#define DEFAULT_TYPDELIM ','
@@ -103,9 +104,8 @@ compute_return_type(const Node *returnType,
}
-
static void
-compute_full_attributes(const List *parameters, int32 *byte_pct_p,
+compute_full_attributes(List *parameters, int32 *byte_pct_p,
int32 *perbyte_cpu_p, int32 *percall_cpu_p,
int32 *outin_ratio_p, bool *canCache_p)
{
@@ -113,7 +113,17 @@ compute_full_attributes(const List *parameters, int32 *byte_pct_p,
Interpret the parameters *parameters and return their contents as
*byte_pct_p, etc.
- These are the full parameters of a C or internal function.
+ These parameters supply optional information about a function.
+ All have defaults if not specified.
+
+ Note: as of version 6.6, canCache is used (if set, the optimizer's
+ constant-folder is allowed to pre-evaluate the function if all its
+ inputs are constant). The other four are not used. They used to be
+ used in the "expensive functions" optimizer, but that's been dead code
+ for a long time.
+
+ Since canCache is useful for any function, we now allow attributes to be
+ supplied for all functions regardless of language.
---------------------------------------------------------------------------*/
List *pl;
@@ -122,58 +132,33 @@ compute_full_attributes(const List *parameters, int32 *byte_pct_p,
*perbyte_cpu_p = PERBYTE_CPU;
*percall_cpu_p = PERCALL_CPU;
*outin_ratio_p = OUTIN_RATIO;
+ *canCache_p = false;
- foreach(pl, (List *) parameters)
+ foreach(pl, parameters)
{
- ParamString *param = (ParamString *) lfirst(pl);
+ DefElem *param = (DefElem *) lfirst(pl);
- if (strcasecmp(param->name, "iscachable") == 0)
+ if (strcasecmp(param->defname, "iscachable") == 0)
*canCache_p = true;
- else if (strcasecmp(param->name, "trusted") == 0)
+ else if (strcasecmp(param->defname, "trusted") == 0)
{
-
/*
* we don't have untrusted functions any more. The 4.2
* implementation is lousy anyway so I took it out. -ay 10/94
*/
elog(ERROR, "untrusted function has been decommissioned.");
}
- else if (strcasecmp(param->name, "byte_pct") == 0)
- {
-
- /*
- * * handle expensive function parameters
- */
- *byte_pct_p = atoi(param->val);
- }
- else if (strcasecmp(param->name, "perbyte_cpu") == 0)
- {
- if (sscanf(param->val, "%d", perbyte_cpu_p) == 0)
- {
- int count;
- char *ptr;
-
- for (count = 0, ptr = param->val; *ptr != '\0'; ptr++)
- if (*ptr == '!')
- count++;
- *perbyte_cpu_p = (int) pow(10.0, (double) count);
- }
- }
- else if (strcasecmp(param->name, "percall_cpu") == 0)
- {
- if (sscanf(param->val, "%d", percall_cpu_p) == 0)
- {
- int count;
- char *ptr;
-
- for (count = 0, ptr = param->val; *ptr != '\0'; ptr++)
- if (*ptr == '!')
- count++;
- *percall_cpu_p = (int) pow(10.0, (double) count);
- }
- }
- else if (strcasecmp(param->name, "outin_ratio") == 0)
- *outin_ratio_p = atoi(param->val);
+ else if (strcasecmp(param->defname, "byte_pct") == 0)
+ *byte_pct_p = (int) defGetNumeric(param);
+ else if (strcasecmp(param->defname, "perbyte_cpu") == 0)
+ *perbyte_cpu_p = (int) defGetNumeric(param);
+ else if (strcasecmp(param->defname, "percall_cpu") == 0)
+ *percall_cpu_p = (int) defGetNumeric(param);
+ else if (strcasecmp(param->defname, "outin_ratio") == 0)
+ *outin_ratio_p = (int) defGetNumeric(param);
+ else
+ elog(NOTICE, "Unrecognized function attribute '%s' ignored",
+ param->defname);
}
}
@@ -215,8 +200,8 @@ interpret_AS_clause(const char *languageName, const List *as,
*probin_str_p = "-";
if (lnext(as) != NULL)
- elog(ERROR, "CREATE FUNCTION: parse error in 'AS %s, %s'.",
- strVal(lfirst(as)), strVal(lsecond(as)));
+ elog(ERROR, "CREATE FUNCTION: only one AS item needed for %s language",
+ languageName);
}
}
@@ -246,39 +231,37 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
* or "SQL"
*/
+ bool returnsSet;
+ /* The function returns a set of values, as opposed to a singleton. */
+
+ bool lanisPL = false;
+
/*
- * The following are attributes of the function, as expressed in the
- * CREATE FUNCTION statement, where applicable.
+ * The following are optional user-supplied attributes of the function.
*/
int32 byte_pct,
perbyte_cpu,
percall_cpu,
outin_ratio;
bool canCache;
- bool returnsSet;
-
- bool lanisPL = false;
-
- /* The function returns a set of values, as opposed to a singleton. */
case_translate_language_name(stmt->language, languageName);
- compute_return_type(stmt->returnType, &prorettype, &returnsSet);
-
if (strcmp(languageName, "C") == 0 ||
strcmp(languageName, "internal") == 0)
{
- compute_full_attributes(stmt->withClause,
- &byte_pct, &perbyte_cpu, &percall_cpu,
- &outin_ratio, &canCache);
+ if (!superuser())
+ elog(ERROR,
+ "Only users with Postgres superuser privilege are "
+ "permitted to create a function "
+ "in the '%s' language. Others may use the 'sql' language "
+ "or the created procedural languages.",
+ languageName);
}
else if (strcmp(languageName, "sql") == 0)
{
- /* query optimizer groks sql, these are meaningless */
- perbyte_cpu = percall_cpu = 0;
- byte_pct = outin_ratio = 100;
- canCache = false;
+ /* No security check needed for SQL functions */
}
else
{
@@ -321,47 +304,34 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
}
lanisPL = true;
-
- /*
- * These are meaningless
- */
- perbyte_cpu = percall_cpu = 0;
- byte_pct = outin_ratio = 100;
- canCache = false;
}
- interpret_AS_clause(languageName, stmt->as, &prosrc_str, &probin_str);
+ compute_return_type(stmt->returnType, &prorettype, &returnsSet);
- if (strcmp(languageName, "sql") != 0 && lanisPL == false && !superuser())
- elog(ERROR,
- "Only users with Postgres superuser privilege are permitted "
- "to create a function "
- "in the '%s' language. Others may use the 'sql' language "
- "or the created procedural languages.",
- languageName);
- /* Above does not return. */
- else
- {
+ compute_full_attributes(stmt->withClause,
+ &byte_pct, &perbyte_cpu, &percall_cpu,
+ &outin_ratio, &canCache);
- /*
- * And now that we have all the parameters, and know we're
- * permitted to do so, go ahead and create the function.
- */
- ProcedureCreate(stmt->funcname,
- returnsSet,
- prorettype,
- languageName,
- prosrc_str, /* converted to text later */
- probin_str, /* converted to text later */
- canCache,
- true, /* (obsolete "trusted") */
- byte_pct,
- perbyte_cpu,
- percall_cpu,
- outin_ratio,
- stmt->defArgs,
- dest);
- }
+ interpret_AS_clause(languageName, stmt->as, &prosrc_str, &probin_str);
+
+ /*
+ * And now that we have all the parameters, and know we're
+ * permitted to do so, go ahead and create the function.
+ */
+ ProcedureCreate(stmt->funcname,
+ returnsSet,
+ prorettype,
+ languageName,
+ prosrc_str, /* converted to text later */
+ probin_str, /* converted to text later */
+ canCache,
+ true, /* (obsolete "trusted") */
+ byte_pct,
+ perbyte_cpu,
+ percall_cpu,
+ outin_ratio,
+ stmt->defArgs,
+ dest);
}
@@ -734,6 +704,25 @@ defGetString(DefElem *def)
return strVal(def->arg);
}
+static double
+defGetNumeric(DefElem *def)
+{
+ if (def->arg == NULL)
+ elog(ERROR, "Define: \"%s\" requires a numeric value",
+ def->defname);
+ switch (nodeTag(def->arg))
+ {
+ case T_Integer:
+ return (double) intVal(def->arg);
+ case T_Float:
+ return floatVal(def->arg);
+ default:
+ elog(ERROR, "Define: \"%s\" requires a numeric value",
+ def->defname);
+ }
+ return 0; /* keep compiler quiet */
+}
+
static int
defGetTypeLength(DefElem *def)
{
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 113854311d6..5f82c2b5321 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.11 1999/09/18 19:06:40 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.12 1999/10/02 21:33:24 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -50,7 +50,7 @@ static char *GetDefaultOpClass(Oid atttypid);
*
* 'attributeList' is a list of IndexElem specifying either a functional
* index or a list of attributes to index on.
- * 'parameterList' is a list of ParamString specified in the with clause.
+ * 'parameterList' is a list of DefElem specified in the with clause.
* 'predicate' is the qual specified in the where clause.
* 'rangetable' is for the predicate
*
@@ -116,22 +116,20 @@ DefineIndex(char *heapRelationName,
}
accessMethodId = tuple->t_data->t_oid;
-
/*
- * Handle parameters [param list is now different (NOT USED, really) -
- * ay 10/94]
- *
* WITH clause reinstated to handle lossy indices. -- JMH, 7/22/96
*/
foreach(pl, parameterList)
{
- ParamString *param = (ParamString *) lfirst(pl);
+ DefElem *param = (DefElem *) lfirst(pl);
- if (!strcasecmp(param->name, "islossy"))
+ if (!strcasecmp(param->defname, "islossy"))
lossy = TRUE;
+ else
+ elog(NOTICE, "Unrecognized index attribute '%s' ignored",
+ param->defname);
}
-
/*
* Convert the partial-index predicate from parsetree form to plan
* form, so it can be readily evaluated during index creation. Note:
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index b6583197be3..96f480ea0ca 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.104 1999/09/29 16:06:06 wieck Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.105 1999/10/02 21:33:21 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -103,7 +103,6 @@ Oid param_type(int t); /* used in parse_expr.c */
TypeName *typnam;
DefElem *defelt;
- ParamString *param;
SortGroupBy *sortgroupby;
JoinExpr *joinexpr;
IndexElem *ielem;
diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.c
index a69d20a0476..15b22bdfa41 100644
--- a/src/backend/utils/fmgr/dfmgr.c
+++ b/src/backend/utils/fmgr/dfmgr.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.34 1999/09/28 11:27:13 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.35 1999/10/02 21:33:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -42,15 +42,16 @@ fmgr_dynamic(Oid procedureId, int *pronargs)
HeapTuple procedureTuple;
Form_pg_proc procedureStruct;
char *proname,
- *probinstring,
- *prosrcstring,
- *linksymbol;
+ *linksymbol,
+ *probinstring;
+ char *prosrcstring = NULL;
Datum probinattr;
Datum prosrcattr;
func_ptr user_fn;
Relation rel;
bool isnull;
+ /* Implement simple one-element cache for function lookups */
if (procedureId == procedureId_save)
{
*pronargs = pronargs_save;
@@ -91,8 +92,6 @@ fmgr_dynamic(Oid procedureId, int *pronargs)
}
probinstring = textout((struct varlena *) probinattr);
- heap_close(rel, AccessShareLock);
-
prosrcattr = heap_getattr(procedureTuple,
Anum_pg_proc_prosrc,
RelationGetDescr(rel), &isnull);
@@ -118,9 +117,12 @@ fmgr_dynamic(Oid procedureId, int *pronargs)
linksymbol = prosrcstring;
}
+ heap_close(rel, AccessShareLock);
+
user_fn = handle_load(probinstring, linksymbol);
pfree(probinstring);
+ if (prosrcstring) pfree(prosrcstring);
procedureId_save = procedureId;
user_fn_save = user_fn;
diff --git a/src/bin/psql/psqlHelp.h b/src/bin/psql/psqlHelp.h
index 63268c2cbd9..3b39f7b2d8e 100644
--- a/src/bin/psql/psqlHelp.h
+++ b/src/bin/psql/psqlHelp.h
@@ -5,7 +5,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: psqlHelp.h,v 1.76 1999/09/28 04:34:48 momjian Exp $
+ * $Id: psqlHelp.h,v 1.77 1999/10/02 21:33:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -88,14 +88,16 @@ static struct _helpStruct QL_HELP[] = {
"create a user-defined function",
"\
\tCREATE FUNCTION function_name ([type1, ...typeN]) RETURNS return_type\n\
-\tAS 'sql-queries'|'builtin_function_name'|'object_filename'\n\
-\tLANGUAGE 'sql'|'internal'|'c';\n\
+\t[WITH ( attributes )]\n\
+\tAS 'sql_queries'|'builtin_function_name'|'procedural_commands'\n\
+\tLANGUAGE 'sql'|'internal'|'procedural_language_name';\n\
\n\
OR\n\
\n\
\tCREATE FUNCTION function_name ([type1, ...typeN]) RETURNS return_type\n\
-\tAS 'object_filename', 'link_symbol'\n\
-\tLANGUAGE 'c';"},
+\t[WITH ( attributes )]\n\
+\tAS 'object_filename' [, 'link_symbol']\n\
+\tLANGUAGE 'C';"},
{"create index",
"construct an index",
"\
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index 68d82473244..08705ea9f6e 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: nodes.h,v 1.53 1999/09/29 16:06:23 wieck Exp $
+ * $Id: nodes.h,v 1.54 1999/10/02 21:33:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -194,7 +194,7 @@ typedef enum NodeTag
T_FuncCall,
T_A_Indices,
T_ResTarget,
- T_ParamString,
+ T_ParamString, /* not used anymore */
T_RelExpr,
T_SortGroupBy,
T_RangeVar,
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index a736c1af67e..463ea1518e0 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: parsenodes.h,v 1.81 1999/09/29 16:06:23 wieck Exp $
+ * $Id: parsenodes.h,v 1.82 1999/10/02 21:33:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -346,7 +346,7 @@ typedef struct IndexStmt
char *relname; /* name of relation to index on */
char *accessMethod; /* name of acess methood (eg. btree) */
List *indexParams; /* a list of IndexElem */
- List *withClause; /* a list of ParamString */
+ List *withClause; /* a list of DefElem */
Node *whereClause; /* qualifications */
List *rangetable; /* range table, filled in by
* transformStmt() */
@@ -367,7 +367,7 @@ typedef struct ProcedureStmt
* (as Value *) */
Node *returnType; /* the return type (as a string or a
* TypeName (ie.setof) */
- List *withClause; /* a list of ParamString */
+ List *withClause; /* a list of DefElem */
List *as; /* the SQL statement or filename */
char *language; /* C or SQL */
} ProcedureStmt;
@@ -863,16 +863,6 @@ typedef struct ResTarget
} ResTarget;
/*
- * ParamString - used in WITH clauses
- */
-typedef struct ParamString
-{
- NodeTag type;
- char *name;
- char *val;
-} ParamString;
-
-/*
* RelExpr - relation expressions
*/
typedef struct RelExpr