]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Require superuser privilege to create C function.
authorBryan Henderson <bryanh@giraffe.netgate.net>
Thu, 31 Oct 1996 09:08:10 +0000 (09:08 +0000)
committerBryan Henderson <bryanh@giraffe.netgate.net>
Thu, 31 Oct 1996 09:08:10 +0000 (09:08 +0000)
src/backend/commands/define.c
src/backend/tcop/utility.c

index 9f6b0abc8d51e581cd0e5c3985c2fd8b3ea7791e..1409c1d2881a2809deec556313bff93cfea9b27c 100644 (file)
@@ -1,31 +1,34 @@
 /*-------------------------------------------------------------------------
  *
  * define.c--
- *    POSTGRES "define" utility code.
+ *
+ *    These routines execute some of the CREATE statements.  In an earlier
+ *    version of Postgres, these were "define" statements.
  *
  * Copyright (c) 1994, Regents of the University of California
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.2 1996/10/23 07:40:01 scrappy Exp $
+ *    $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.3 1996/10/31 09:07:41 bryanh Exp $
  *
  * DESCRIPTION
  *    The "DefineFoo" routines take the parse tree and pick out the
  *    appropriate arguments/flags, passing the results to the
  *    corresponding "FooDefine" routines (in src/catalog) that do
- *    the actual catalog-munging.
+ *    the actual catalog-munging.  These routines also verify permission
+ *    of the user to execute the command.
  *
  * NOTES
  *    These things must be defined and committed in the following order:
- *     "define function":
- *             input/output, recv/send procedures
- *     "define type":
- *             type
- *     "define operator":
- *             operators
+ *      "create function":
+ *              input/output, recv/send procedures
+ *      "create type":
+ *              type
+ *      "create operator":
+ *              operators
  *
- *     Most of the parse-tree manipulation routines are defined in
- *     commands/manip.c.
+ *      Most of the parse-tree manipulation routines are defined in
+ *      commands/manip.c.
  *
  *-------------------------------------------------------------------------
  */
 #include <ctype.h>
 #include <math.h>
 
-#include "postgres.h"
-
-#include "access/heapam.h"
-#include "access/htup.h"
-#include "utils/tqual.h"
-#include "catalog/catname.h"
-#include "catalog/pg_aggregate.h"
-#include "catalog/pg_proc.h"
-#include "catalog/pg_type.h"
-#include "catalog/pg_operator.h"
-#include "utils/syscache.h"
-#include "nodes/pg_list.h"
-#include "nodes/parsenodes.h"
-#include "fmgr.h"              /* for fmgr */
-
-#include "utils/builtins.h"    /* prototype for textin() */
-
-#include "utils/elog.h"
-#include "utils/palloc.h"
-#include "commands/defrem.h"
-#include "optimizer/xfunc.h"
-#include "tcop/dest.h"
+#include <postgres.h>
+
+#include <access/heapam.h>
+#include <access/htup.h>
+#include <utils/tqual.h>
+#include <catalog/catname.h>
+#include <catalog/pg_aggregate.h>
+#include <catalog/pg_operator.h>
+#include <catalog/pg_proc.h>
+#include <catalog/pg_type.h>
+#include <catalog/pg_user.h>    /* superuser() uses this */
+#include <utils/syscache.h>
+#include <nodes/pg_list.h>
+#include <nodes/parsenodes.h>
+#include <fmgr.h>               /* for fmgr */
+
+#include <utils/builtins.h>     /* prototype for textin() */
+
+#include <utils/elog.h>
+#include <utils/palloc.h>
+#include <commands/defrem.h>
+#include <optimizer/xfunc.h>
+#include <tcop/dest.h>
 
 static char *defGetString(DefElem *def);
 static int  defGetTypeLength(DefElem *def);
 
-#define        DEFAULT_TYPDELIM        ','
+#define DEFAULT_TYPDELIM        ','
+
+
+bool
+superuser(void) {
+/*--------------------------------------------------------------------------
+    The Postgres user running this command has Postgres superuser 
+    privileges.
+--------------------------------------------------------------------------*/
+    HeapTuple utup;
+    char *userName;
+
+    userName = GetPgUserName();
+    utup = SearchSysCacheTuple(USENAME, PointerGetDatum(userName),
+                              0,0,0);
+    Assert(utup != NULL);
+    return ((Form_pg_user)GETSTRUCT(utup))->usesuper;
+}
+
+
 
-/*
- * DefineFunction --
- *     Registers a new function.
- *
- */
 void
-DefineFunction(ProcedureStmt *stmt, CommandDest dest)
-{
-    List       *parameters = stmt->withClause;
-    char        *proname = stmt->funcname;
-    char*      probin_str;
-    char*      prosrc_str;
-    char *prorettype;
-    char *languageName;
-    bool       canCache = FALSE;
-    List       *argList;
-    int32       byte_pct = 100, perbyte_cpu, percall_cpu, outin_ratio = 100;
-    bool       returnsSet;
-    int                i;
-    
-    /* ----------------
-     * figure out the language and convert it to lowercase.
-     * ----------------
-     */
-    languageName = stmt->language;
-    for (i = 0; i < NAMEDATALEN && languageName[i]; ++i) {
-       languageName[i] = tolower(languageName[i]);
-    }
-    
-    /* ----------------
-     * handle "returntype = X".  The function could return a singleton
-     * value or a set of values.  Figure out which.
-     * ----------------
-     */
-    if (nodeTag(stmt->returnType)==T_TypeName) {
-       TypeName *setType = (TypeName *)stmt->returnType;
-       /* a set of values */
-       prorettype = setType->name,
-       returnsSet = true;
+case_translate_language_name(const char *input, char *output) {
+/*-------------------------------------------------------------------------
+  Translate the input language name to lower case, except if it's C,
+  translate to upper case.  
+--------------------------------------------------------------------------*/
+    int i;
+
+    for (i = 0; i < NAMEDATALEN && input[i] != '\0'; ++i) 
+        output[i] = tolower(input[i]);
+
+    output[i] = '\0';
+
+    if (strcmp(output, "c") == 0) output[0] = 'C';
+}    
+
+
+
+void
+compute_return_type(const Node *returnType, 
+                    char **prorettype_p, bool *returnsSet_p) {
+/*---------------------------------------------------------------------------
+   Examine the "returns" clause returnType of the CREATE FUNCTION statement 
+   and return information about it as **prorettype_p and **returnsSet.
+----------------------------------------------------------------------------*/
+    if (nodeTag(returnType) == T_TypeName) {
+        /* a set of values */
+        TypeName *setType = (TypeName *)returnType;
+        *prorettype_p = setType->name,
+        *returnsSet_p = true;
     }else {
-       /* singleton */
-       prorettype = strVal(stmt->returnType);
-       returnsSet = false;
+        /* singleton */
+        *prorettype_p = strVal(returnType);
+        *returnsSet_p = false;
     }
+}
+
     
-    /* Next attributes are only defined for C functions */
-    if ( strcmp(languageName, "c") == 0 ||
-        strcmp(languageName, "internal") == 0 )  {
-       List *pl;
-
-       /* the defaults */
-       byte_pct = BYTE_PCT;
-       perbyte_cpu = PERBYTE_CPU;
-       percall_cpu = PERCALL_CPU;
-       outin_ratio = OUTIN_RATIO;
-
-       foreach(pl, parameters) {
-           int count;
-           char *ptr;
-           ParamString *param = (ParamString*)lfirst(pl);
-
-           if (!strcasecmp(param->name, "isacachable")) {
-               /* ----------------
-                * handle "[ iscachable ]": figure out if Postquel functions 
-                * are cacheable automagically?
-                * ----------------
-                */
-               canCache = TRUE;
-           }else if (!strcasecmp(param->name, "trusted")) {
-               /*
-                * we don't have untrusted functions any more. The 4.2
-                * implementation is lousy anyway so I took it out.
-                *                                         -ay 10/94
-                */
-               elog(WARN, "untrusted function has been decommissioned.");
-           }else if (!strcasecmp(param->name, "byte_pct")) {
-               /*
-                ** handle expensive function parameters
-                */
-               byte_pct = atoi(param->val);
-           }else if (!strcasecmp(param->name, "perbyte_cpu")) {
-               if (!sscanf(param->val, "%d", &perbyte_cpu)) {
-                   for (count = 0, ptr = param->val; *ptr != '\0'; ptr++) {
-                       if (*ptr == '!') {
-                           count++;
-                       }
-                   }
-                   perbyte_cpu = (int) pow(10.0, (double) count);
-               }
-           }else if (!strcasecmp(param->name, "percall_cpu")) {
-               if (!sscanf(param->val, "%d", &percall_cpu)) {
-                   for (count = 0, ptr = param->val; *ptr != '\0'; ptr++) {
-                       if (*ptr == '!') {
-                           count++;
-                       }
-                   }
-                   percall_cpu = (int) pow(10.0, (double) count);
-               }
-           }else if (!strcasecmp(param->name, "outin_ratio")) {
-               outin_ratio = atoi(param->val);
-           }
-       }
-    } else if (!strcmp(languageName, "sql")) {
-       /* query optimizer groks sql, these are meaningless */
-       perbyte_cpu = percall_cpu = 0;
-    } else {
-       elog(WARN, "DefineFunction: language '%s' is not supported",
-            languageName);
+
+void 
+compute_full_attributes(const List *parameters, int32 *byte_pct_p, 
+                        int32 *perbyte_cpu_p, int32 *percall_cpu_p, 
+                        int32 *outin_ratio_p, bool *canCache_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.
+---------------------------------------------------------------------------*/
+    List *pl;
+
+    /* the defaults */
+    *byte_pct_p = BYTE_PCT;
+    *perbyte_cpu_p = PERBYTE_CPU;
+    *percall_cpu_p = PERCALL_CPU;
+    *outin_ratio_p = OUTIN_RATIO;
+
+    foreach(pl, (List *)parameters) {
+        int count;
+        char *ptr;
+        ParamString *param = (ParamString*)lfirst(pl);
+
+        if (strcasecmp(param->name, "iscachable") == 0) {
+            *canCache_p = true;
+        } else if (strcasecmp(param->name, "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(WARN, "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) {
+                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) {
+                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);
+        }
     }
-    
-    /* ----------------
-     * handle "[ arg is (...) ]"
-     * XXX fix optional arg handling below
-     * ----------------
-     */
-    argList = stmt->defArgs;
-    
-    if ( strcmp(languageName, "c") == 0 ||
-        strcmp(languageName, "internal") == 0 ) {
-       prosrc_str = "-";
-       probin_str = stmt->as;
+}
+
+
+
+void
+interpret_AS_clause(const char languageName[], const char as[],
+                    char **prosrc_str_p, char **probin_str_p) {
+
+    if ( strcmp(languageName, "C") == 0 ||
+         strcmp(languageName, "internal") == 0 ) {
+        *prosrc_str_p = "-";
+        *probin_str_p = (char *)as;
     } else {
-       prosrc_str = stmt->as;
-       probin_str = "-";
+        *prosrc_str_p = (char *)as;
+        *probin_str_p = "-";
     }
-    
-    /* C is stored uppercase in pg_language */
-    if (!strcmp(languageName, "c")) {
-       languageName[0] = 'C';
+}
+
+
+
+/*
+ * CreateFunction --
+ *   Execute a CREATE FUNCTION utility statement.
+ *
+ */
+void
+CreateFunction(ProcedureStmt *stmt, CommandDest dest)
+{
+    char   *probin_str;   
+      /* pathname of executable file that executes this function, if any */
+    char   *prosrc_str;
+      /* SQL that executes this function, if any */
+    char   *prorettype;
+      /* Type of return value (or member of set of values) from function */
+    char   languageName[NAMEDATALEN+1];
+      /* name of language of function, with case adjusted:
+         "C", "internal", or "SQL" 
+      */
+    /* The following are attributes of the function, as expressed in the 
+       CREATE FUNCTION statement, where applicable.
+    */
+    int32  byte_pct, perbyte_cpu, percall_cpu, outin_ratio;
+    bool   canCache;
+    bool   returnsSet;
+      /* 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);
+    } 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;
+    } else {
+        elog(WARN, 
+             "Unrecognized language specified in a CREATE FUNCTION: "
+             "'%s'.  Recognized languages are sql, C, and internal.",
+             languageName);
     }
-    
-    /* ----------------
-     * now have ProcedureDefine do all the work..
-     * ----------------
-     */
-    ProcedureCreate(proname,
-                   returnsSet,
-                   prorettype,
-                   languageName,
-                   prosrc_str,         /* converted to text later */
-                   probin_str,         /* converted to text later */
-                   canCache,
-                   TRUE,
-                   byte_pct,
-                   perbyte_cpu,
-                   percall_cpu, 
-                   outin_ratio,
-                   argList,
-                   dest);
-    
+   
+    interpret_AS_clause(languageName, stmt->as, &prosrc_str, &probin_str);
+
+    if (strcmp(languageName, "sql") != 0 && !superuser())
+        elog(WARN, 
+             "Only users with Postgres superuser privilege are permitted "
+             "to create a function "
+             "in the '%s' language.  Others may use the 'sql' language.", 
+             languageName);
+        /* Above does not return. */
+    else {
+        /* 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);
+    }        
 }
 
+
+
 /* --------------------------------
  * DefineOperator--
  *
- *     this function extracts all the information from the
- *     parameter list generated by the parser and then has
- *     OperatorCreate() do all the actual work.
+ *      this function extracts all the information from the
+ *      parameter list generated by the parser and then has
+ *      OperatorCreate() do all the actual work.
  *
  * 'parameters' is a list of DefElem
  * --------------------------------
  */
 void
-DefineOperator(char *oprName,  
-              List *parameters)
+DefineOperator(char *oprName,   
+               List *parameters)
 {
-    uint16     precedence=0;           /* operator precedence */
-    bool       canHash=false;          /* operator hashes */
-    bool       isLeftAssociative=true; /* operator is left associative */
-    char *functionName=NULL;   /* function for operator */
-    char *typeName1=NULL;              /* first type name */
-    char *typeName2=NULL;              /* second type name */
-    char *commutatorName=NULL;         /* optional commutator operator name */
-    char *negatorName=NULL;    /* optional negator operator name */
-    char *restrictionName=NULL;        /* optional restrict. sel. procedure */
-    char *joinName=NULL;               /* optional join sel. procedure name */
-    char *sortName1=NULL;              /* optional first sort operator */
-    char *sortName2=NULL;              /* optional second sort operator */
-    List       *pl;
+    uint16      precedence=0;           /* operator precedence */
+    bool        canHash=false;          /* operator hashes */
+    bool        isLeftAssociative=true; /* operator is left associative */
+    char *functionName=NULL;    /* function for operator */
+    char *typeName1=NULL;               /* first type name */
+    char *typeName2=NULL;               /* second type name */
+    char *commutatorName=NULL;  /* optional commutator operator name */
+    char *negatorName=NULL;     /* optional negator operator name */
+    char *restrictionName=NULL; /* optional restrict. sel. procedure */
+    char *joinName=NULL;                /* optional join sel. procedure name */
+    char *sortName1=NULL;               /* optional first sort operator */
+    char *sortName2=NULL;               /* optional second sort operator */
+    List        *pl;
 
     /*
      * loop over the definition list and extract the information we need.
      */
     foreach (pl, parameters) {
-       DefElem *defel = (DefElem *)lfirst(pl);
-
-       if (!strcasecmp(defel->defname, "leftarg")) {
-           /* see gram.y, must be setof */
-           if (nodeTag(defel->arg)==T_TypeName) 
-               elog(WARN, "setof type not implemented for leftarg");
-
-           if (nodeTag(defel->arg)==T_String) {
-               typeName1 = defGetString(defel);
-           }else {
-               elog(WARN, "type for leftarg is malformed.");
-           }
-       } else if (!strcasecmp(defel->defname, "rightarg")) {
-           /* see gram.y, must be setof */
-           if (nodeTag(defel->arg)==T_TypeName) 
-               elog(WARN, "setof type not implemented for rightarg");
-
-           if (nodeTag(defel->arg)==T_String) {
-               typeName2 = defGetString(defel);
-           }else {
-               elog(WARN, "type for rightarg is malformed.");
-           }
-       } else if (!strcasecmp(defel->defname, "procedure")) {
-           functionName = defGetString(defel);
-       } else if (!strcasecmp(defel->defname, "precedence")) {
-           /* NOT IMPLEMENTED (never worked in v4.2) */
-           elog(NOTICE, "CREATE OPERATOR: precedence not implemented");
-       } else if (!strcasecmp(defel->defname, "associativity")) {
-           /* NOT IMPLEMENTED (never worked in v4.2) */
-           elog(NOTICE, "CREATE OPERATOR: associativity not implemented");
-       } else if (!strcasecmp(defel->defname, "commutator")) {
-           commutatorName = defGetString(defel);
-       } else if (!strcasecmp(defel->defname, "negator")) {
-           negatorName = defGetString(defel);
-       } else if (!strcasecmp(defel->defname, "restrict")) {
-           restrictionName = defGetString(defel);
-       } else if (!strcasecmp(defel->defname, "join")) {
-           joinName = defGetString(defel);
-       } else if (!strcasecmp(defel->defname, "hashes")) {
-           canHash = TRUE;
-       } else if (!strcasecmp(defel->defname, "sort1")) {
-           /* ----------------
-            * XXX ( ... [ , sort1 = oprname ] [ , sort2 = oprname ] ... )
-            * XXX is undocumented in the reference manual source as of
-            * 89/8/22.
-            * ----------------
-            */
-           sortName1 = defGetString(defel);
-       } else if (!strcasecmp(defel->defname, "sort2")) {
-           sortName2 = defGetString(defel);
-       } else {
-           elog(NOTICE, "DefineOperator: attribute \"%s\" not recognized",
-                defel->defname);
-       }
+        DefElem *defel = (DefElem *)lfirst(pl);
+
+        if (!strcasecmp(defel->defname, "leftarg")) {
+            /* see gram.y, must be setof */
+            if (nodeTag(defel->arg)==T_TypeName) 
+                elog(WARN, "setof type not implemented for leftarg");
+
+            if (nodeTag(defel->arg)==T_String) {
+                typeName1 = defGetString(defel);
+            }else {
+                elog(WARN, "type for leftarg is malformed.");
+            }
+        } else if (!strcasecmp(defel->defname, "rightarg")) {
+            /* see gram.y, must be setof */
+            if (nodeTag(defel->arg)==T_TypeName) 
+                elog(WARN, "setof type not implemented for rightarg");
+
+            if (nodeTag(defel->arg)==T_String) {
+                typeName2 = defGetString(defel);
+            }else {
+                elog(WARN, "type for rightarg is malformed.");
+            }
+        } else if (!strcasecmp(defel->defname, "procedure")) {
+            functionName = defGetString(defel);
+        } else if (!strcasecmp(defel->defname, "precedence")) {
+            /* NOT IMPLEMENTED (never worked in v4.2) */
+            elog(NOTICE, "CREATE OPERATOR: precedence not implemented");
+        } else if (!strcasecmp(defel->defname, "associativity")) {
+            /* NOT IMPLEMENTED (never worked in v4.2) */
+            elog(NOTICE, "CREATE OPERATOR: associativity not implemented");
+        } else if (!strcasecmp(defel->defname, "commutator")) {
+            commutatorName = defGetString(defel);
+        } else if (!strcasecmp(defel->defname, "negator")) {
+            negatorName = defGetString(defel);
+        } else if (!strcasecmp(defel->defname, "restrict")) {
+            restrictionName = defGetString(defel);
+        } else if (!strcasecmp(defel->defname, "join")) {
+            joinName = defGetString(defel);
+        } else if (!strcasecmp(defel->defname, "hashes")) {
+            canHash = TRUE;
+        } else if (!strcasecmp(defel->defname, "sort1")) {
+            /* ----------------
+             * XXX ( ... [ , sort1 = oprname ] [ , sort2 = oprname ] ... )
+             * XXX is undocumented in the reference manual source as of
+             * 89/8/22.
+             * ----------------
+             */
+            sortName1 = defGetString(defel);
+        } else if (!strcasecmp(defel->defname, "sort2")) {
+            sortName2 = defGetString(defel);
+        } else {
+            elog(NOTICE, "DefineOperator: attribute \"%s\" not recognized",
+                 defel->defname);
+        }
     }
 
     /*
      * make sure we have our required definitions
      */
     if (functionName==NULL) {
-       elog(WARN, "Define: \"procedure\" unspecified");
+        elog(WARN, "Define: \"procedure\" unspecified");
     }
     
     /* ----------------
-     * now have OperatorCreate do all the work..
+     *  now have OperatorCreate do all the work..
      * ----------------
      */
-    OperatorCreate(oprName,    /* operator name */
-                  typeName1,           /* first type name */
-                  typeName2,           /* second type name */
-                  functionName,        /* function for operator */
-                  precedence,          /* operator precedence */
-                  isLeftAssociative,   /* operator is left associative */
-                  commutatorName,      /* optional commutator operator name */
-                  negatorName,         /* optional negator operator name */
-                  restrictionName,     /* optional restrict. sel. procedure */
-                  joinName,            /* optional join sel. procedure name */
-                  canHash,             /* operator hashes */
-                  sortName1,           /* optional first sort operator */
-                  sortName2);          /* optional second sort operator */
+    OperatorCreate(oprName,     /* operator name */
+                   typeName1,           /* first type name */
+                   typeName2,           /* second type name */
+                   functionName,        /* function for operator */
+                   precedence,          /* operator precedence */
+                   isLeftAssociative,   /* operator is left associative */
+                   commutatorName,      /* optional commutator operator name */
+                   negatorName,         /* optional negator operator name */
+                   restrictionName,     /* optional restrict. sel. procedure */
+                   joinName,            /* optional join sel. procedure name */
+                   canHash,             /* operator hashes */
+                   sortName1,           /* optional first sort operator */
+                   sortName2);          /* optional second sort operator */
     
 }
 
@@ -347,170 +410,170 @@ DefineAggregate(char *aggName, List *parameters)
     List *pl;
     
     foreach (pl, parameters) {
-       DefElem *defel = (DefElem *)lfirst(pl);
-
-       /*
-        * sfunc1
-        */
-       if (!strcasecmp(defel->defname, "sfunc1")) {
-           stepfunc1Name = defGetString(defel);
-       } else if (!strcasecmp(defel->defname, "basetype")) {
-           baseType = defGetString(defel);
-       } else if (!strcasecmp(defel->defname, "stype1")) {
-           stepfunc1Type = defGetString(defel);
-
-       /*
-        * sfunc2
-        */
-       } else if (!strcasecmp(defel->defname, "sfunc2")) {
-           stepfunc2Name = defGetString(defel);
-       } else if (!strcasecmp(defel->defname, "stype2")) {
-           stepfunc2Type = defGetString(defel);
-       /*
-        * final
-        */
-       } else if (!strcasecmp(defel->defname, "finalfunc")) {
-           finalfuncName = defGetString(defel);
-       /*
-        * initial conditions
-        */
-       } else if (!strcasecmp(defel->defname, "initcond1")) {
-           init1 = defGetString(defel);
-       } else if (!strcasecmp(defel->defname, "initcond2")) {
-           init2 = defGetString(defel);
-       } else {
-           elog(NOTICE, "DefineAggregate: attribute \"%s\" not recognized",
-                defel->defname);
-       }
+        DefElem *defel = (DefElem *)lfirst(pl);
+
+        /*
+         * sfunc1
+         */
+        if (!strcasecmp(defel->defname, "sfunc1")) {
+            stepfunc1Name = defGetString(defel);
+        } else if (!strcasecmp(defel->defname, "basetype")) {
+            baseType = defGetString(defel);
+        } else if (!strcasecmp(defel->defname, "stype1")) {
+            stepfunc1Type = defGetString(defel);
+
+        /*
+         * sfunc2
+         */
+        } else if (!strcasecmp(defel->defname, "sfunc2")) {
+            stepfunc2Name = defGetString(defel);
+        } else if (!strcasecmp(defel->defname, "stype2")) {
+            stepfunc2Type = defGetString(defel);
+        /*
+         * final
+         */
+        } else if (!strcasecmp(defel->defname, "finalfunc")) {
+            finalfuncName = defGetString(defel);
+        /*
+         * initial conditions
+         */
+        } else if (!strcasecmp(defel->defname, "initcond1")) {
+            init1 = defGetString(defel);
+        } else if (!strcasecmp(defel->defname, "initcond2")) {
+            init2 = defGetString(defel);
+        } else {
+            elog(NOTICE, "DefineAggregate: attribute \"%s\" not recognized",
+                 defel->defname);
+        }
     }
 
     /*
      * make sure we have our required definitions
      */
     if (baseType==NULL) 
-       elog(WARN, "Define: \"basetype\" unspecified");
+        elog(WARN, "Define: \"basetype\" unspecified");
     if (stepfunc1Name!=NULL) {
-       if (stepfunc1Type==NULL) 
-           elog(WARN, "Define: \"stype1\" unspecified");
+        if (stepfunc1Type==NULL) 
+            elog(WARN, "Define: \"stype1\" unspecified");
     }
     if (stepfunc2Name!=NULL) {
-       if (stepfunc2Type==NULL)
-           elog(WARN, "Define: \"stype2\" unspecified");
+        if (stepfunc2Type==NULL)
+            elog(WARN, "Define: \"stype2\" unspecified");
     }
 
     /*
      * Most of the argument-checking is done inside of AggregateCreate
      */
-    AggregateCreate(aggName,           /* aggregate name */
-                   stepfunc1Name,      /* first step function name */
-                   stepfunc2Name,      /* second step function name */
-                   finalfuncName,      /* final function name */
-                   baseType,           /* type of object being aggregated */
-                   stepfunc1Type,      /* return type of first function */
-                   stepfunc2Type,      /* return type of second function */
-                   init1,      /* first initial condition */
-                   init2);     /* second initial condition */
+    AggregateCreate(aggName,            /* aggregate name */
+                    stepfunc1Name,      /* first step function name */
+                    stepfunc2Name,      /* second step function name */
+                    finalfuncName,      /* final function name */
+                    baseType,           /* type of object being aggregated */
+                    stepfunc1Type,      /* return type of first function */
+                    stepfunc2Type,      /* return type of second function */
+                    init1,      /* first initial condition */
+                    init2);     /* second initial condition */
     
     /* XXX free palloc'd memory */
 }
 
 /*
  * DefineType --
- *     Registers a new type.
+ *      Registers a new type.
  *
  */
 void
 DefineType(char *typeName, List *parameters)
 {
-    int16              internalLength= 0;      /* int2 */
-    int16              externalLength= 0;      /* int2 */
+    int16               internalLength= 0;      /* int2 */
+    int16               externalLength= 0;      /* int2 */
     char *elemName = NULL;
     char *inputName = NULL;
     char *outputName = NULL;
     char *sendName = NULL;
     char *receiveName = NULL;
-    char               *defaultValue = NULL;   /* Datum */
-    bool               byValue = false;
-    char               delimiter = DEFAULT_TYPDELIM;
+    char                *defaultValue = NULL;   /* Datum */
+    bool                byValue = false;
+    char                delimiter = DEFAULT_TYPDELIM;
     char *shadow_type;
-    List               *pl;
-    char               alignment = 'i';        /* default alignment */
+    List                *pl;
+    char                alignment = 'i';        /* default alignment */
 
     /*
      * Type names can only be 15 characters long, so that the shadow type
      * can be created using the 16th character as necessary.
      */
     if (strlen(typeName) >= (NAMEDATALEN - 1)) {
-       elog(WARN, "DefineType: type names must be %d characters or less",
-            NAMEDATALEN - 1);
+        elog(WARN, "DefineType: type names must be %d characters or less",
+             NAMEDATALEN - 1);
     }
 
     foreach(pl, parameters) {
-       DefElem *defel = (DefElem*)lfirst(pl);
-
-       if (!strcasecmp(defel->defname, "internallength")) {
-           internalLength = defGetTypeLength(defel);
-       }else if (!strcasecmp(defel->defname, "externallength")) {
-           externalLength = defGetTypeLength(defel);
-       }else if (!strcasecmp(defel->defname, "input")) {
-           inputName = defGetString(defel);
-       }else if (!strcasecmp(defel->defname, "output")) {
-           outputName = defGetString(defel);
-       }else if (!strcasecmp(defel->defname, "send")) {
-           sendName = defGetString(defel);
-       }else if (!strcasecmp(defel->defname, "delimiter")) {
-           char *p = defGetString(defel);
-           delimiter = p[0];
-       }else if (!strcasecmp(defel->defname, "receive")) {
-           receiveName = defGetString(defel);
-       }else if (!strcasecmp(defel->defname, "element")) {
-           elemName = defGetString(defel);
-       }else if (!strcasecmp(defel->defname, "default")) {
-           defaultValue = defGetString(defel);
-       }else if (!strcasecmp(defel->defname, "passedbyvalue")) {
-           byValue = true;
-       }else if (!strcasecmp(defel->defname, "alignment")) {
-           char *a = defGetString(defel);
-           if (!strcasecmp(a, "double")) {
-               alignment = 'd';
-           } else if (!strcasecmp(a, "int")) {
-               alignment = 'i';
-           } else {
-               elog(WARN, "DefineType: \"%s\" alignment  not recognized",
-                    a);
-           }
-       }else {
-           elog(NOTICE, "DefineType: attribute \"%s\" not recognized",
-                defel->defname);
-       }
+        DefElem *defel = (DefElem*)lfirst(pl);
+
+        if (!strcasecmp(defel->defname, "internallength")) {
+            internalLength = defGetTypeLength(defel);
+        }else if (!strcasecmp(defel->defname, "externallength")) {
+            externalLength = defGetTypeLength(defel);
+        }else if (!strcasecmp(defel->defname, "input")) {
+            inputName = defGetString(defel);
+        }else if (!strcasecmp(defel->defname, "output")) {
+            outputName = defGetString(defel);
+        }else if (!strcasecmp(defel->defname, "send")) {
+            sendName = defGetString(defel);
+        }else if (!strcasecmp(defel->defname, "delimiter")) {
+            char *p = defGetString(defel);
+            delimiter = p[0];
+        }else if (!strcasecmp(defel->defname, "receive")) {
+            receiveName = defGetString(defel);
+        }else if (!strcasecmp(defel->defname, "element")) {
+            elemName = defGetString(defel);
+        }else if (!strcasecmp(defel->defname, "default")) {
+            defaultValue = defGetString(defel);
+        }else if (!strcasecmp(defel->defname, "passedbyvalue")) {
+            byValue = true;
+        }else if (!strcasecmp(defel->defname, "alignment")) {
+            char *a = defGetString(defel);
+            if (!strcasecmp(a, "double")) {
+                alignment = 'd';
+            } else if (!strcasecmp(a, "int")) {
+                alignment = 'i';
+            } else {
+                elog(WARN, "DefineType: \"%s\" alignment  not recognized",
+                     a);
+            }
+        }else {
+            elog(NOTICE, "DefineType: attribute \"%s\" not recognized",
+                 defel->defname);
+        }
     }
 
     /*
      * make sure we have our required definitions
      */
     if (inputName==NULL)
-       elog(WARN, "Define: \"input\" unspecified");
+        elog(WARN, "Define: \"input\" unspecified");
     if (outputName==NULL)
-       elog(WARN, "Define: \"output\" unspecified");
+        elog(WARN, "Define: \"output\" unspecified");
     
     /* ----------------
-     * now have TypeCreate do all the real work.
+     *  now have TypeCreate do all the real work.
      * ----------------
      */
-    (void) TypeCreate(typeName,        /* type name */
-                     InvalidOid,  /* relation oid (n/a here) */
-                     internalLength,   /* internal size */
-                     externalLength,   /* external size */
-                     'b',              /* type-type (base type) */
-                     delimiter,        /* array element delimiter */
-                     inputName,        /* input procedure */
-                     outputName,       /* output procedure */
-                     sendName,         /* send procedure */
-                     receiveName,      /* receive procedure */
-                     elemName,         /* element type name */
-                     defaultValue,     /* default type value */
-                     byValue,          /* passed by value */
-                     alignment);
+    (void) TypeCreate(typeName, /* type name */
+                      InvalidOid,  /* relation oid (n/a here) */
+                      internalLength,   /* internal size */
+                      externalLength,   /* external size */
+                      'b',              /* type-type (base type) */
+                      delimiter,        /* array element delimiter */
+                      inputName,        /* input procedure */
+                      outputName,       /* output procedure */
+                      sendName,         /* send procedure */
+                      receiveName,      /* receive procedure */
+                      elemName,         /* element type name */
+                      defaultValue,     /* default type value */
+                      byValue,          /* passed by value */
+                      alignment);
     
     /* ----------------
      *  When we create a true type (as opposed to a complex type)
@@ -519,20 +582,20 @@ DefineType(char *typeName, List *parameters)
      */
     shadow_type = makeArrayTypeName(typeName);
 
-    (void) TypeCreate(shadow_type,     /* type name */
-                     InvalidOid,  /* relation oid (n/a here) */
-                     -1,               /* internal size */
-                     -1,               /* external size */
-                     'b',              /* type-type (base type) */
-                     DEFAULT_TYPDELIM, /* array element delimiter */
-                     "array_in",               /* input procedure */
-                     "array_out",              /* output procedure */
-                     "array_out",              /* send procedure */
-                     "array_in",               /* receive procedure */
-                     typeName, /* element type name */
-                     defaultValue,     /* default type value */
-                     false,            /* never passed by value */
-                     alignment);
+    (void) TypeCreate(shadow_type,      /* type name */
+                      InvalidOid,  /* relation oid (n/a here) */
+                      -1,               /* internal size */
+                      -1,               /* external size */
+                      'b',              /* type-type (base type) */
+                      DEFAULT_TYPDELIM, /* array element delimiter */
+                      "array_in",               /* input procedure */
+                      "array_out",              /* output procedure */
+                      "array_out",              /* send procedure */
+                      "array_in",               /* receive procedure */
+                      typeName, /* element type name */
+                      defaultValue,     /* default type value */
+                      false,            /* never passed by value */
+                      alignment);
     
     pfree(shadow_type);
 }
@@ -541,7 +604,7 @@ static char *
 defGetString(DefElem *def)
 {
     if (nodeTag(def->arg)!=T_String)
-       elog(WARN, "Define: \"%s\" = what?", def->defname);
+        elog(WARN, "Define: \"%s\" = what?", def->defname);
     return (strVal(def->arg));
 }
 
@@ -549,10 +612,10 @@ static int
 defGetTypeLength(DefElem *def)
 {
     if (nodeTag(def->arg)==T_Integer)
-       return (intVal(def->arg));
+        return (intVal(def->arg));
     else if (nodeTag(def->arg)==T_String &&
-            !strcasecmp(strVal(def->arg),"variable"))
-       return -1;      /* variable length */
+             !strcasecmp(strVal(def->arg),"variable"))
+        return -1;      /* variable length */
 
     elog(WARN, "Define: \"%s\" = what?", def->defname);
     return -1;
index a7df82c0ff4ffdeae64a1d45dbae5848a02c0d21..93ca5229181b6ace558de43d72c673f2d87d5754 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.2 1996/08/24 20:49:03 scrappy Exp $
+ *    $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.3 1996/10/31 09:08:10 bryanh Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -367,7 +367,7 @@ ProcessUtility(Node *parsetree,
        }
        break;
       
-    case T_ViewStmt:           /* VIEW */
+    case T_ViewStmt:           /* CREATE VIEW */
        {
            ViewStmt *stmt = (ViewStmt *)parsetree;
 
@@ -377,13 +377,13 @@ ProcessUtility(Node *parsetree,
        }
        break;
       
-    case T_ProcedureStmt:      /* FUNCTION */
+    case T_ProcedureStmt:      /* CREATE FUNCTION */
        commandTag = "CREATE";
        CHECK_IF_ABORTED();
-       DefineFunction((ProcedureStmt *)parsetree, dest); /* everything */
+       CreateFunction((ProcedureStmt *)parsetree, dest); /* everything */
        break;
       
-    case T_IndexStmt:
+    case T_IndexStmt:           /* CREATE INDEX */
        {
            IndexStmt *stmt = (IndexStmt *)parsetree;
 
@@ -400,7 +400,7 @@ ProcessUtility(Node *parsetree,
        }
        break;
       
-    case T_RuleStmt:
+    case T_RuleStmt:            /* CREATE RULE */
        {
            RuleStmt *stmt = (RuleStmt *)parsetree;
 #ifndef NO_SECURITY