Now we are able to CREATE PROCEDURAL LANGUAGE (Thanks, Jan).
authorVadim B. Mikheev
Tue, 28 Oct 1997 15:11:45 +0000 (15:11 +0000)
committerVadim B. Mikheev
Tue, 28 Oct 1997 15:11:45 +0000 (15:11 +0000)
16 files changed:
src/backend/commands/Makefile
src/backend/commands/define.c
src/backend/commands/proclang.c [new file with mode: 0644]
src/backend/commands/trigger.c
src/backend/parser/gram.y
src/backend/parser/keywords.c
src/backend/tcop/utility.c
src/backend/utils/Gen_fmgrtab.sh.in
src/backend/utils/cache/syscache.c
src/backend/utils/fmgr/fmgr.c
src/include/catalog/pg_language.h
src/include/commands/proclang.h [new file with mode: 0644]
src/include/nodes/nodes.h
src/include/nodes/parsenodes.h
src/include/utils/rel.h
src/include/utils/syscache.h

index 5d8e945a66ad19c20febb800d142d4a6897fdd81..c65f04da402cca9e5c7d4116f71f06ed747c00d9 100644 (file)
@@ -4,7 +4,7 @@
 #    Makefile for commands
 #
 # IDENTIFICATION
-#    $Header: /cvsroot/pgsql/src/backend/commands/Makefile,v 1.4 1997/08/31 11:40:12 vadim Exp $
+#    $Header: /cvsroot/pgsql/src/backend/commands/Makefile,v 1.5 1997/10/28 14:54:43 vadim Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -19,7 +19,7 @@ CFLAGS+=$(INCLUDE_OPT)
 
 OBJS = async.o creatinh.o command.o copy.o defind.o define.o \
        purge.o remove.o rename.o vacuum.o version.o view.o cluster.o \
-       recipe.o explain.o sequence.o trigger.o
+       recipe.o explain.o sequence.o trigger.o proclang.o
 
 all: SUBSYS.o
 
index 903bb5164953f71bc757fef085b4265c1867767b..9aa8c09897329c5e3fa27017fecb9b4040f80429 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.16 1997/09/08 21:42:38 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.17 1997/10/28 14:54:46 vadim Exp $
  *
  * DESCRIPTION
  *   The "DefineFoo" routines take the parse tree and pick out the
@@ -45,6 +45,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include               /* for fmgr */
 #include         /* prototype for textin() */
@@ -239,6 +240,8 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
    bool        canCache;
    bool        returnsSet;
 
+   bool        lanisPL = false;
+
    /* The function returns a set of values, as opposed to a singleton. */
 
 
@@ -262,19 +265,59 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
    }
    else
    {
-       elog(WARN,
+       HeapTuple       languageTuple;
+       Form_pg_language    languageStruct;
+
+           /* Lookup the language in the system cache */
+       languageTuple = SearchSysCacheTuple(LANNAME,
+           PointerGetDatum(languageName),
+           0, 0, 0);
+       
+       if (!HeapTupleIsValid(languageTuple)) {
+
+           elog(WARN,
             "Unrecognized language specified in a CREATE FUNCTION: "
-            "'%s'.  Recognized languages are sql, C, and internal.",
+            "'%s'.  Recognized languages are sql, C, internal "
+            "and the created procedural languages.",
             languageName);
+       }
+
+       /* Check that this language is a PL */
+       languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
+       if (!(languageStruct->lanispl)) {
+           elog(WARN,
+               "Language '%s' isn't defined as PL", languageName);
+       }
+
+       /*
+        * Functions in untrusted procedural languages are
+        * restricted to be defined by postgres superusers only
+        */
+       if (languageStruct->lanpltrusted == false && !superuser()) {
+           elog(WARN, "Only users with Postgres superuser privilege "
+               "are permitted to create a function in the '%s' "
+           "language.",
+           languageName);
+       }
+
+       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);
 
-   if (strcmp(languageName, "sql") != 0 && !superuser())
+   if (strcmp(languageName, "sql") != 0 && lanisPL == false && !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.",
+            "in the '%s' language.  Others may use the 'sql' language "
+            "or the created procedural languages.",
             languageName);
    /* Above does not return. */
    else
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
new file mode 100644 (file)
index 0000000..2b8836b
--- /dev/null
@@ -0,0 +1,205 @@
+/*-------------------------------------------------------------------------
+ *
+ * proclang.c--
+ *   PostgreSQL PROCEDURAL LANGUAGE support code.
+ *
+ *-------------------------------------------------------------------------
+ */
+#include 
+#include 
+#include "postgres.h"
+
+#include "access/heapam.h"
+#include "catalog/catname.h"
+#include "catalog/pg_user.h"
+#include "catalog/pg_proc.h"
+#include "catalog/pg_language.h"
+#include "utils/syscache.h"
+#include "commands/proclang.h"
+#include "fmgr.h"
+
+
+static void
+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';
+}
+
+
+/* ---------------------------------------------------------------------
+ * CREATE PROCEDURAL LANGUAGE
+ * ---------------------------------------------------------------------
+ */
+void
+CreateProceduralLanguage(CreatePLangStmt * stmt)
+{
+   char        languageName[NAMEDATALEN];
+   HeapTuple   langTup;
+   HeapTuple   procTup;
+
+   Oid         typev[8];
+   char        nulls[Natts_pg_language];
+   Datum       values[Natts_pg_language];
+   Relation    rdesc;
+   HeapTuple   tup;
+   TupleDesc   tupDesc;
+
+   int         i;
+
+   /* ----------------
+    * Check permission
+    * ----------------
+    */
+   if (!superuser())
+   {
+       elog(WARN, "Only users with Postgres superuser privilege are "
+            "permitted to create procedural languages");
+   }
+
+   /* ----------------
+    * Translate the language name and check that
+    * this language doesn't already exist
+    * ----------------
+    */
+   case_translate_language_name(stmt->plname, languageName);
+
+   langTup = SearchSysCacheTuple(LANNAME,
+                                 PointerGetDatum(languageName),
+                                 0, 0, 0);
+   if (HeapTupleIsValid(langTup))
+   {
+       elog(WARN, "Language %s already exists", languageName);
+   }
+
+   /* ----------------
+    * Lookup the PL handler function and check that it is
+    * of return type Opaque
+    * ----------------
+    */
+   memset(typev, 0, sizeof(typev));
+   procTup = SearchSysCacheTuple(PRONAME,
+                                 PointerGetDatum(stmt->plhandler),
+                                 UInt16GetDatum(0),
+                                 PointerGetDatum(typev),
+                                 0);
+   if (!HeapTupleIsValid(procTup))
+   {
+       elog(WARN, "PL handler function %s() doesn't exist",
+            stmt->plhandler);
+   }
+   if (((Form_pg_proc) GETSTRUCT(procTup))->prorettype != InvalidOid)
+   {
+       elog(WARN, "PL handler function %s() isn't of return type Opaque",
+            stmt->plhandler);
+   }
+
+   /* ----------------
+    * Insert the new language into pg_language
+    * ----------------
+    */
+   for (i = 0; i < Natts_pg_language; i++)
+   {
+       nulls[i] = ' ';
+       values[i] = (Datum) NULL;
+   }
+
+   i = 0;
+   values[i++] = PointerGetDatum(languageName);
+   values[i++] = Int8GetDatum((bool) 1);
+   values[i++] = Int8GetDatum(stmt->pltrusted);
+   values[i++] = ObjectIdGetDatum(procTup->t_oid);
+   values[i++] = (Datum) fmgr(TextInRegProcedure, stmt->plcompiler);
+
+   rdesc = heap_openr(LanguageRelationName);
+
+   tupDesc = rdesc->rd_att;
+   tup = heap_formtuple(tupDesc, values, nulls);
+
+   heap_insert(rdesc, tup);
+
+   heap_close(rdesc);
+   return;
+}
+
+
+/* ---------------------------------------------------------------------
+ * DROP PROCEDURAL LANGUAGE
+ * ---------------------------------------------------------------------
+ */
+void
+DropProceduralLanguage(DropPLangStmt * stmt)
+{
+   char        languageName[NAMEDATALEN];
+   HeapTuple   langTup;
+
+   Relation    rdesc;
+   HeapScanDesc scanDesc;
+   ScanKeyData scanKeyData;
+   HeapTuple   tup;
+
+   /* ----------------
+    * Check permission
+    * ----------------
+    */
+   if (!superuser())
+   {
+       elog(WARN, "Only users with Postgres superuser privilege are "
+            "permitted to drop procedural languages");
+   }
+
+   /* ----------------
+    * Translate the language name, check that
+    * this language exist and is a PL
+    * ----------------
+    */
+   case_translate_language_name(stmt->plname, languageName);
+
+   langTup = SearchSysCacheTuple(LANNAME,
+                                 PointerGetDatum(languageName),
+                                 0, 0, 0);
+   if (!HeapTupleIsValid(langTup))
+   {
+       elog(WARN, "Language %s doesn't exist", languageName);
+   }
+
+   if (!((Form_pg_language) GETSTRUCT(langTup))->lanispl)
+   {
+       elog(WARN, "Language %s isn't a created procedural language",
+            languageName);
+   }
+
+   /* ----------------
+    * Now scan pg_language and delete the PL tuple
+    * ----------------
+    */
+   rdesc = heap_openr(LanguageRelationName);
+
+   ScanKeyEntryInitialize(&scanKeyData, 0, Anum_pg_language_lanname,
+                          F_NAMEEQ, PointerGetDatum(languageName));
+
+   scanDesc = heap_beginscan(rdesc, 0, NowTimeQual, 1, &scanKeyData);
+
+   tup = heap_getnext(scanDesc, 0, (Buffer *) NULL);
+
+   if (!HeapTupleIsValid(tup))
+   {
+       elog(WARN, "Language with name '%s' not found", languageName);
+   }
+
+   heap_delete(rdesc, &(tup->t_ctid));
+
+   heap_endscan(scanDesc);
+   heap_close(rdesc);
+}
index 9215f41055596fd433bc0bd2f6b3d124983e58cc..273136b29233811edc59c54b790ef261fd657c10 100644 (file)
 #include "utils/mcxt.h"
 #include "utils/inval.h"
 #include "utils/builtins.h"
+#include "utils/syscache.h"
 
 #ifndef NO_SECURITY
 #include "miscadmin.h"
 #include "utils/acl.h"
-#include "utils/syscache.h"
 #endif
 
 TriggerData *CurrentTriggerData = NULL;
@@ -87,8 +87,8 @@ CreateTrigger(CreateTrigStmt * stmt)
    if (stmt->row)
        TRIGGER_SETT_ROW(tgtype);
    else
-       elog (WARN, "CreateTrigger: STATEMENT triggers are unimplemented, yet");
-   
+       elog(WARN, "CreateTrigger: STATEMENT triggers are unimplemented, yet");
+
    for (i = 0; i < 3 && stmt->actions[i]; i++)
    {
        switch (stmt->actions[i])
@@ -142,7 +142,22 @@ CreateTrigger(CreateTrigStmt * stmt)
        elog(WARN, "CreateTrigger: function %s () does not exist", stmt->funcname);
 
    if (((Form_pg_proc) GETSTRUCT(tuple))->prolang != ClanguageId)
-       elog(WARN, "CreateTrigger: only C functions are supported");
+   {
+       HeapTuple   langTup;
+
+       langTup = SearchSysCacheTuple(LANOID,
+           ObjectIdGetDatum(((Form_pg_proc) GETSTRUCT(tuple))->prolang),
+                                     0, 0, 0);
+       if (!HeapTupleIsValid(langTup))
+       {
+           elog(WARN, "CreateTrigger: cache lookup for PL failed");
+       }
+
+       if (((Form_pg_language) GETSTRUCT(langTup))->lanispl == false)
+       {
+           elog(WARN, "CreateTrigger: only C and PL functions are supported");
+       }
+   }
 
    MemSet(nulls, ' ', Natts_pg_trigger * sizeof(char));
 
@@ -159,10 +174,10 @@ CreateTrigger(CreateTrigStmt * stmt)
 
        foreach(le, stmt->args)
        {
-           char   *ar = (char *) lfirst(le);
+           char       *ar = (char *) lfirst(le);
 
            len += strlen(ar) + 4;
-           for ( ; *ar; ar++)
+           for (; *ar; ar++)
            {
                if (*ar == '\\')
                    len++;
@@ -172,9 +187,9 @@ CreateTrigger(CreateTrigStmt * stmt)
        args[0] = 0;
        foreach(le, stmt->args)
        {
-           char   *s = (char *) lfirst(le);
-           char   *d = args + strlen(args);
-           
+           char       *s = (char *) lfirst(le);
+           char       *d = args + strlen(args);
+
            while (*s)
            {
                if (*s == '\\')
@@ -399,6 +414,7 @@ RelationBuildTriggers(Relation relation)
        build->tgname = nameout(&(pg_trigger->tgname));
        build->tgfoid = pg_trigger->tgfoid;
        build->tgfunc = NULL;
+       build->tgplfunc = NULL;
        build->tgtype = pg_trigger->tgtype;
        build->tgnargs = pg_trigger->tgnargs;
        memcpy(build->tgattr, &(pg_trigger->tgattr), 8 * sizeof(int16));
@@ -578,6 +594,54 @@ DescribeTrigger(TriggerDesc * trigdesc, Trigger * trigger)
 
 }
 
+static HeapTuple
+ExecCallTriggerFunc(Trigger * trigger)
+{
+
+   if (trigger->tgfunc != NULL)
+   {
+       return (HeapTuple) ((*(trigger->tgfunc)) ());
+   }
+
+   if (trigger->tgplfunc == NULL)
+   {
+       HeapTuple   procTuple;
+       HeapTuple   langTuple;
+       Form_pg_proc procStruct;
+       Form_pg_language langStruct;
+       int         nargs;
+
+       procTuple = SearchSysCacheTuple(PROOID,
+                                       ObjectIdGetDatum(trigger->tgfoid),
+                                       0, 0, 0);
+       if (!HeapTupleIsValid(procTuple))
+       {
+           elog(WARN, "ExecCallTriggerFunc(): Cache lookup for proc %ld failed",
+                ObjectIdGetDatum(trigger->tgfoid));
+       }
+       procStruct = (Form_pg_proc) GETSTRUCT(procTuple);
+
+       langTuple = SearchSysCacheTuple(LANOID,
+                                  ObjectIdGetDatum(procStruct->prolang),
+                                       0, 0, 0);
+       if (!HeapTupleIsValid(langTuple))
+       {
+           elog(WARN, "ExecCallTriggerFunc(): Cache lookup for language %ld failed",
+                ObjectIdGetDatum(procStruct->prolang));
+       }
+       langStruct = (Form_pg_language) GETSTRUCT(langTuple);
+
+       if (langStruct->lanispl == false)
+       {
+           fmgr_info(trigger->tgfoid, &(trigger->tgfunc), &nargs);
+           return (HeapTuple) ((*(trigger->tgfunc)) ());
+       }
+       fmgr_info(langStruct->lanplcallfoid, &(trigger->tgplfunc), &nargs);
+   }
+
+   return (HeapTuple) ((*(trigger->tgplfunc)) (trigger->tgfoid));
+}
+
 HeapTuple
 ExecBRInsertTriggers(Relation rel, HeapTuple trigtuple)
 {
@@ -586,7 +650,6 @@ ExecBRInsertTriggers(Relation rel, HeapTuple trigtuple)
    Trigger   **trigger = rel->trigdesc->tg_before_row[TRIGGER_EVENT_INSERT];
    HeapTuple   newtuple = trigtuple;
    HeapTuple   oldtuple;
-   int         nargs;
    int         i;
 
    SaveTriggerData = (TriggerData *) palloc(sizeof(TriggerData));
@@ -599,9 +662,7 @@ ExecBRInsertTriggers(Relation rel, HeapTuple trigtuple)
        CurrentTriggerData = SaveTriggerData;
        CurrentTriggerData->tg_trigtuple = oldtuple = newtuple;
        CurrentTriggerData->tg_trigger = trigger[i];
-       if (trigger[i]->tgfunc == NULL)
-           fmgr_info(trigger[i]->tgfoid, &(trigger[i]->tgfunc), &nargs);
-       newtuple = (HeapTuple) ((*(trigger[i]->tgfunc)) ());
+       newtuple = ExecCallTriggerFunc(trigger[i]);
        if (newtuple == NULL)
            break;
        else if (oldtuple != newtuple && oldtuple != trigtuple)
@@ -618,7 +679,6 @@ ExecARInsertTriggers(Relation rel, HeapTuple trigtuple)
    TriggerData *SaveTriggerData;
    int         ntrigs = rel->trigdesc->n_after_row[TRIGGER_EVENT_INSERT];
    Trigger   **trigger = rel->trigdesc->tg_after_row[TRIGGER_EVENT_INSERT];
-   int         nargs;
    int         i;
 
    SaveTriggerData = (TriggerData *) palloc(sizeof(TriggerData));
@@ -630,9 +690,7 @@ ExecARInsertTriggers(Relation rel, HeapTuple trigtuple)
        CurrentTriggerData = SaveTriggerData;
        CurrentTriggerData->tg_trigtuple = trigtuple;
        CurrentTriggerData->tg_trigger = trigger[i];
-       if (trigger[i]->tgfunc == NULL)
-           fmgr_info(trigger[i]->tgfoid, &(trigger[i]->tgfunc), &nargs);
-       (void) ((*(trigger[i]->tgfunc)) ());
+       ExecCallTriggerFunc(trigger[i]);
    }
    CurrentTriggerData = NULL;
    pfree(SaveTriggerData);
@@ -647,7 +705,6 @@ ExecBRDeleteTriggers(Relation rel, ItemPointer tupleid)
    Trigger   **trigger = rel->trigdesc->tg_before_row[TRIGGER_EVENT_DELETE];
    HeapTuple   trigtuple;
    HeapTuple   newtuple = NULL;
-   int         nargs;
    int         i;
 
    trigtuple = GetTupleForTrigger(rel, tupleid, true);
@@ -664,9 +721,7 @@ ExecBRDeleteTriggers(Relation rel, ItemPointer tupleid)
        CurrentTriggerData = SaveTriggerData;
        CurrentTriggerData->tg_trigtuple = trigtuple;
        CurrentTriggerData->tg_trigger = trigger[i];
-       if (trigger[i]->tgfunc == NULL)
-           fmgr_info(trigger[i]->tgfoid, &(trigger[i]->tgfunc), &nargs);
-       newtuple = (HeapTuple) ((*(trigger[i]->tgfunc)) ());
+       newtuple = ExecCallTriggerFunc(trigger[i]);
        if (newtuple == NULL)
            break;
    }
@@ -684,7 +739,6 @@ ExecARDeleteTriggers(Relation rel, ItemPointer tupleid)
    int         ntrigs = rel->trigdesc->n_after_row[TRIGGER_EVENT_DELETE];
    Trigger   **trigger = rel->trigdesc->tg_after_row[TRIGGER_EVENT_DELETE];
    HeapTuple   trigtuple;
-   int         nargs;
    int         i;
 
    trigtuple = GetTupleForTrigger(rel, tupleid, false);
@@ -700,9 +754,7 @@ ExecARDeleteTriggers(Relation rel, ItemPointer tupleid)
        CurrentTriggerData = SaveTriggerData;
        CurrentTriggerData->tg_trigtuple = trigtuple;
        CurrentTriggerData->tg_trigger = trigger[i];
-       if (trigger[i]->tgfunc == NULL)
-           fmgr_info(trigger[i]->tgfoid, &(trigger[i]->tgfunc), &nargs);
-       (void) ((*(trigger[i]->tgfunc)) ());
+       ExecCallTriggerFunc(trigger[i]);
    }
    CurrentTriggerData = NULL;
    pfree(SaveTriggerData);
@@ -719,7 +771,6 @@ ExecBRUpdateTriggers(Relation rel, ItemPointer tupleid, HeapTuple newtuple)
    HeapTuple   trigtuple;
    HeapTuple   oldtuple;
    HeapTuple   intuple = newtuple;
-   int         nargs;
    int         i;
 
    trigtuple = GetTupleForTrigger(rel, tupleid, true);
@@ -736,9 +787,7 @@ ExecBRUpdateTriggers(Relation rel, ItemPointer tupleid, HeapTuple newtuple)
        CurrentTriggerData->tg_trigtuple = trigtuple;
        CurrentTriggerData->tg_newtuple = oldtuple = newtuple;
        CurrentTriggerData->tg_trigger = trigger[i];
-       if (trigger[i]->tgfunc == NULL)
-           fmgr_info(trigger[i]->tgfoid, &(trigger[i]->tgfunc), &nargs);
-       newtuple = (HeapTuple) ((*(trigger[i]->tgfunc)) ());
+       newtuple = ExecCallTriggerFunc(trigger[i]);
        if (newtuple == NULL)
            break;
        else if (oldtuple != newtuple && oldtuple != intuple)
@@ -757,7 +806,6 @@ ExecARUpdateTriggers(Relation rel, ItemPointer tupleid, HeapTuple newtuple)
    int         ntrigs = rel->trigdesc->n_after_row[TRIGGER_EVENT_UPDATE];
    Trigger   **trigger = rel->trigdesc->tg_after_row[TRIGGER_EVENT_UPDATE];
    HeapTuple   trigtuple;
-   int         nargs;
    int         i;
 
    trigtuple = GetTupleForTrigger(rel, tupleid, false);
@@ -773,9 +821,7 @@ ExecARUpdateTriggers(Relation rel, ItemPointer tupleid, HeapTuple newtuple)
        CurrentTriggerData->tg_trigtuple = trigtuple;
        CurrentTriggerData->tg_newtuple = newtuple;
        CurrentTriggerData->tg_trigger = trigger[i];
-       if (trigger[i]->tgfunc == NULL)
-           fmgr_info(trigger[i]->tgfoid, &(trigger[i]->tgfunc), &nargs);
-       (void) ((*(trigger[i]->tgfunc)) ());
+       ExecCallTriggerFunc(trigger[i]);
    }
    CurrentTriggerData = NULL;
    pfree(SaveTriggerData);
index 8132cc34d4837d9ce32b46204a322615931821c6..7eb361d3a93e21541479b3785d9a1560980fd1f5 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.58 1997/10/25 05:56:41 thomas Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.59 1997/10/28 14:56:08 vadim Exp $
  *
  * HISTORY
  *   AUTHOR            DATE            MAJOR EVENT
@@ -109,6 +109,7 @@ static char *FlattenStringList(List *list);
        AddAttrStmt, ClosePortalStmt,
        CopyStmt, CreateStmt, CreateSeqStmt, DefineStmt, DestroyStmt,
        ExtendStmt, FetchStmt,  GrantStmt, CreateTrigStmt, DropTrigStmt,
+       CreatePLangStmt, DropPLangStmt,
        IndexStmt, ListenStmt, OptimizableStmt,
        ProcedureStmt, PurgeStmt,
        RecipeStmt, RemoveAggrStmt, RemoveOperStmt, RemoveFuncStmt, RemoveStmt,
@@ -119,7 +120,7 @@ static char *FlattenStringList(List *list);
 
 %type    SubSelect
 %type         join_expr, join_outer, join_spec
-%type  TriggerActionTime, TriggerForSpec
+%type  TriggerActionTime, TriggerForSpec, PLangTrusted
 
 %type         TriggerEvents, TriggerFuncArg
 
@@ -225,9 +226,9 @@ static char *FlattenStringList(List *list);
 /* Keywords (in SQL92 reserved words) */
 %token ACTION, ADD, ALL, ALTER, AND, AS, ASC,
        BEGIN_TRANS, BETWEEN, BOTH, BY,
-       CASCADE, CAST, CHAR, CHARACTER, CHECK, CLOSE,
-       COLLATE, COLUMN, COMMIT, CONSTRAINT, CREATE, CROSS,
-       CURRENT, CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
+       CASCADE, CAST, CHAR, CHARACTER, CHECK, CLOSE, COLLATE, COLUMN, COMMIT, 
+       CONSTRAINT, CREATE, CROSS, CURRENT, CURRENT_DATE, CURRENT_TIME, 
+       CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
        DAY_P, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
        END_TRANS, EXECUTE, EXISTS, EXTRACT,
        FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
@@ -256,12 +257,12 @@ static char *FlattenStringList(List *list);
        APPEND, ARCHIVE, ARCH_STORE,
        BACKWARD, BEFORE, BINARY, CHANGE, CLUSTER, COPY,
        DATABASE, DELIMITERS, DO, EXPLAIN, EXTEND,
-       FORWARD, FUNCTION, HEAVY,
+       FORWARD, FUNCTION, HANDLER, HEAVY,
        INDEX, INHERITS, INSTEAD, ISNULL,
-       LIGHT, LISTEN, LOAD, MERGE, MOVE,
-       NEW, NONE, NOTHING, OIDS, OPERATOR, PURGE,
+       LANCOMPILER, LIGHT, LISTEN, LOAD, MERGE, MOVE,
+       NEW, NONE, NOTHING, OIDS, OPERATOR, PROCEDURAL, PURGE,
        RECIPE, RENAME, REPLACE, RESET, RETRIEVE, RETURNS, RULE,
-       SEQUENCE, SETOF, SHOW, STDIN, STDOUT, STORE,
+       SEQUENCE, SETOF, SHOW, STDIN, STDOUT, STORE, TRUSTED, 
        VACUUM, VERBOSE, VERSION
 
 /* Special keywords, not in the query language - see the "lex" file */
@@ -318,10 +319,12 @@ stmt :      AddAttrStmt
        | CopyStmt
        | CreateStmt
        | CreateSeqStmt
+       | CreatePLangStmt
        | CreateTrigStmt
        | ClusterStmt
        | DefineStmt
        | DestroyStmt
+       | DropPLangStmt
        | DropTrigStmt
        | ExtendStmt
        | ExplainStmt
@@ -857,6 +860,36 @@ OptSeqElem:        IDENT NumConst
                }
        ;
 
+/*****************************************************************************
+ *
+ *     QUERIES :
+ *             CREATE PROCEDURAL LANGUAGE ...
+ *             DROP PROCEDURAL LANGUAGE ...
+ *
+ *****************************************************************************/
+
+CreatePLangStmt: CREATE PLangTrusted PROCEDURAL LANGUAGE Sconst 
+           HANDLER def_name LANCOMPILER Sconst
+           {
+               CreatePLangStmt *n = makeNode(CreatePLangStmt);
+               n->plname = $5;
+               n->plhandler = $7;
+               n->plcompiler = $9;
+               n->pltrusted = $2;
+               $$ = (Node *)n;
+           }
+       ;
+
+PLangTrusted:      TRUSTED { $$ = TRUE; }
+           |   { $$ = FALSE; }
+
+DropPLangStmt: DROP PROCEDURAL LANGUAGE Sconst
+           {
+               DropPLangStmt *n = makeNode(DropPLangStmt);
+               n->plname = $4;
+               $$ = (Node *)n;
+           }
+       ;
 
 /*****************************************************************************
  *
index f3f957dbb0f8896ea7a756675e1102ddfca210f5..b2bcce32d1e9fc59ab9cd979ad73f32651fa6cf6 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.20 1997/10/25 05:44:11 thomas Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.21 1997/10/28 14:56:10 vadim Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -104,6 +104,7 @@ static ScanKeyword ScanKeywords[] = {
    {"function", FUNCTION},
    {"grant", GRANT},
    {"group", GROUP},
+   {"handler", HANDLER},
    {"having", HAVING},
    {"heavy", HEAVY},
    {"hour", HOUR_P},
@@ -119,6 +120,7 @@ static ScanKeyword ScanKeywords[] = {
    {"isnull", ISNULL},
    {"join", JOIN},
    {"key", KEY},
+   {"lancompiler", LANCOMPILER},
    {"language", LANGUAGE},
    {"leading", LEADING},
    {"left", LEFT},
@@ -156,6 +158,7 @@ static ScanKeyword ScanKeywords[] = {
    {"precision", PRECISION},
    {"primary", PRIMARY},
    {"privileges", PRIVILEGES},
+   {"procedural", PROCEDURAL},
    {"procedure", PROCEDURE},
    {"public", PUBLIC},
    {"purge", PURGE},
@@ -188,6 +191,7 @@ static ScanKeyword ScanKeywords[] = {
    {"trigger", TRIGGER},
    {"trim", TRIM},
    {"true", TRUE_P},
+   {"trusted", TRUSTED},
    {"type", TYPE_P},
    {"union", UNION},
    {"unique", UNIQUE},
index 50013c8f7f1ca2901022a04029a0b77438d6030b..1fd20eb986a9c66d87736be6dc1301ee57395e1b 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.26 1997/10/25 05:34:07 thomas Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.27 1997/10/28 14:57:24 vadim Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -35,6 +35,7 @@
 #include "commands/recipe.h"
 #include "commands/explain.h"
 #include "commands/trigger.h"
+#include "commands/proclang.h"
 
 #include "nodes/parsenodes.h"
 #include "../backend/parser/parse.h"
@@ -75,7 +76,7 @@
  * ----------------
  */
 void
-ProcessUtility(Node *parsetree,
+ProcessUtility(Node * parsetree,
               CommandDest dest)
 {
    char       *commandTag = NULL;
@@ -149,8 +150,8 @@ ProcessUtility(Node *parsetree,
                 */
 
                count = stmt->howMany;
-               PerformPortalFetch(portalName, forward, count, commandTag, 
-                   (stmt->ismove) ? None : dest);  /* /dev/null for MOVE */
+               PerformPortalFetch(portalName, forward, count, commandTag,
+                                  (stmt->ismove) ? None : dest);       /* /dev/null for MOVE */
            }
            break;
 
@@ -718,6 +719,23 @@ ProcessUtility(Node *parsetree,
            DropTrigger((DropTrigStmt *) parsetree);
            break;
 
+           /*
+            * ************* PROCEDURAL LANGUAGE statements *****************
+            */
+       case T_CreatePLangStmt:
+           commandTag = "CREATE";
+           CHECK_IF_ABORTED();
+
+           CreateProceduralLanguage((CreatePLangStmt *) parsetree);
+           break;
+
+       case T_DropPLangStmt:
+           commandTag = "DROP";
+           CHECK_IF_ABORTED();
+
+           DropProceduralLanguage((DropPLangStmt *) parsetree);
+           break;
+
            /*
             * ******************************** default ********************************
             *
index 1d7c8d23568ef95c5564fd4445a71fc4f8beab87..409372e8ce2f1a41346246bed0b2aa4c2bc632fb 100644 (file)
@@ -8,7 +8,7 @@
 #
 #
 # IDENTIFICATION
-#    $Header: /cvsroot/pgsql/src/backend/utils/Attic/Gen_fmgrtab.sh.in,v 1.4 1997/07/28 00:55:41 momjian Exp $
+#    $Header: /cvsroot/pgsql/src/backend/utils/Attic/Gen_fmgrtab.sh.in,v 1.5 1997/10/28 15:02:24 vadim Exp $
 #
 # NOTES
 #    Passes any -D options on to cpp prior to generating the list
@@ -81,7 +81,7 @@ cat > $HFILE <
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: Gen_fmgrtab.sh.in,v 1.4 1997/07/28 00:55:41 momjian Exp $
+ * $Id: Gen_fmgrtab.sh.in,v 1.5 1997/10/28 15:02:24 vadim Exp $
  *
  * NOTES
  * ******************************
@@ -114,6 +114,8 @@ typedef struct {
 /*
  * defined in fmgr.c
  */
+extern char *fmgr_pl(Oid func_id, int n_arguments, FmgrValues *values,
+   bool *isNull);
 extern char *fmgr_c(func_ptr user_fn, Oid func_id, int n_arguments,
    FmgrValues *values, bool *isNull);
 extern void fmgr_info(Oid procedureId, func_ptr *function, int *nargs);
@@ -175,7 +177,7 @@ cat > $TABCFILE <
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/backend/utils/Attic/Gen_fmgrtab.sh.in,v 1.4 1997/07/28 00:55:41 momjian Exp $
+ *    $Header: /cvsroot/pgsql/src/backend/utils/Attic/Gen_fmgrtab.sh.in,v 1.5 1997/10/28 15:02:24 vadim Exp $
  *
  * NOTES
  *
index 149e99888ea5de1922104e6f0be793ca084d7c14..f12e17f03d8163a9e12d4288d2549b36d4c5b510 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.9 1997/09/18 20:22:25 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.10 1997/10/28 15:03:06 vadim Exp $
  *
  * NOTES
  *   These routines allow the parser/planner/executor to perform
@@ -57,7 +57,7 @@ extern bool AMI_OVERRIDE;     /* XXX style */
 #include "utils/syscache.h"
 #include "catalog/indexing.h"
 
-typedef HeapTuple (*ScanFunc) ();
+typedef        HeapTuple(*ScanFunc) ();
 
 /* ----------------
  *     Warning:  cacheinfo[] below is changed, then be sure and
@@ -179,7 +179,7 @@ static struct cachedesc cacheinfo[] = {
            0,
            0,
        0},
-       offsetof(TypeTupleFormData, typalign) +sizeof(char),
+       offsetof(TypeTupleFormData, typalign) + sizeof(char),
        TypeNameIndex,
    TypeNameIndexScan},
    {TypeRelationName,          /* TYPOID */
@@ -316,7 +316,16 @@ static struct cachedesc cacheinfo[] = {
        0},
        sizeof(FormData_pg_opclass),
        NULL,
-   (ScanFunc) NULL}
+   (ScanFunc) NULL},
+   {LanguageRelationName,      /* LANOID */
+       1,
+       {ObjectIdAttributeNumber,
+           0,
+           0,
+       0},
+       offsetof(FormData_pg_language, lancompiler),
+       NULL,
+   NULL}
 };
 
 static struct catcache *SysCache[
@@ -383,7 +392,7 @@ InitCatalogCache()
  * XXX The tuple that is returned is NOT supposed to be pfree'd!
  */
 HeapTuple
-SearchSysCacheTuple(int cacheId,/* cache selection code */
+SearchSysCacheTuple(int cacheId,       /* cache selection code */
                    Datum key1,
                    Datum key2,
                    Datum key3,
@@ -562,7 +571,7 @@ SearchSysCacheGetAttribute(int cacheId,
        : attributeLength;      /* fixed length */
 
        tmp = (char *) palloc(size);
-       memmove(tmp, (void *)attributeValue, size);
+       memmove(tmp, (void *) attributeValue, size);
        returnValue = (void *) tmp;
    }
 
index 939341a3ded4eb535dc35618aaf55a759f4b362f..a225c982555e3589e93c52c7f6a73e5f462a1cd1 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.6 1997/09/08 21:49:07 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.7 1997/10/28 15:05:32 vadim Exp $
  *
  *-------------------------------------------------------------------------
  */
 
 #include "utils/elog.h"
 
+#include "nodes/parsenodes.h"
+#include "commands/trigger.h"
+
+
+char      *
+fmgr_pl(Oid func_id,
+       int n_arguments,
+       FmgrValues * values,
+       bool * isNull)
+{
+   HeapTuple   procedureTuple;
+   HeapTuple   languageTuple;
+   Form_pg_proc procedureStruct;
+   Form_pg_language languageStruct;
+   func_ptr    plcall_fn;
+   int         plcall_nargs;
+
+   /* Fetch the pg_proc tuple from the syscache */
+   procedureTuple = SearchSysCacheTuple(PROOID,
+                                        ObjectIdGetDatum(func_id),
+                                        0, 0, 0);
+   if (!HeapTupleIsValid(procedureTuple))
+   {
+       elog(WARN, "fmgr_pl(): Cache lookup of procedure %ld failed.",
+            ObjectIdGetDatum(func_id));
+   }
+   procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
+
+   /* Fetch the pg_language tuple from the syscache */
+   languageTuple = SearchSysCacheTuple(LANOID,
+                             ObjectIdGetDatum(procedureStruct->prolang),
+                                       0, 0, 0);
+   if (!HeapTupleIsValid(languageTuple))
+   {
+       elog(WARN, "fmgr_pl(): Cache lookup of language %ld for procedure %ld failed.",
+            ObjectIdGetDatum(procedureStruct->prolang),
+            ObjectIdGetDatum(func_id));
+   }
+   languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
+
+   /* Get the function pointer for the PL call handler */
+   fmgr_info(languageStruct->lanplcallfoid, &plcall_fn, &plcall_nargs);
+   if (plcall_fn == NULL)
+   {
+       elog(WARN, "fmgr_pl(): failed to load PL handler for procedure %ld.",
+            ObjectIdGetDatum(func_id));
+   }
+
+   /* Call the PL handler */
+   CurrentTriggerData = NULL;
+   return (*plcall_fn) (func_id,
+                        n_arguments,
+                        values,
+                        isNull);
+}
+
 
 char      *
 fmgr_c(func_ptr user_fn,
       Oid func_id,
       int n_arguments,
-      FmgrValues *values,
-      bool *isNull)
+      FmgrValues * values,
+      bool * isNull)
 {
    char       *returnValue = (char *) NULL;
 
@@ -43,11 +99,11 @@ fmgr_c(func_ptr user_fn,
    {
 
        /*
-        * a NULL func_ptr denotes untrusted function (in postgres 4.2).
-        * Untrusted functions have very limited use and is clumsy. We
-        * just get rid of it.
+        * a NULL func_ptr denotet untrusted function (in postgres 4.2).
+        * Untrusted functions have very limited use and is clumsy. We now
+        * use this feature for procedural languages.
         */
-       elog(WARN, "internal error: untrusted function not supported.");
+       return fmgr_pl(func_id, n_arguments, values, isNull);
    }
 
    switch (n_arguments)
@@ -115,12 +171,14 @@ fmgr_c(func_ptr user_fn,
 }
 
 void
-fmgr_info(Oid procedureId, func_ptr *function, int *nargs)
+fmgr_info(Oid procedureId, func_ptr * function, int *nargs)
 {
    func_ptr    user_fn = NULL;
    FmgrCall   *fcp;
    HeapTuple   procedureTuple;
    FormData_pg_proc *procedureStruct;
+   HeapTuple   languageTuple;
+   Form_pg_language languageStruct;
    Oid         language;
 
    if (!(fcp = fmgr_isbuiltin(procedureId)))
@@ -158,8 +216,35 @@ fmgr_info(Oid procedureId, func_ptr *function, int *nargs)
                *nargs = procedureStruct->pronargs;
                break;
            default:
-               elog(WARN, "fmgr_info: function %d: unknown language %d",
-                    procedureId, language);
+
+               /*
+                * Might be a created procedural language Lookup the
+                * syscache for the language and check the lanispl flag If
+                * this is the case, we return a NULL function pointer and
+                * the number of arguments from the procedure.
+                */
+               languageTuple = SearchSysCacheTuple(LANOID,
+                             ObjectIdGetDatum(procedureStruct->prolang),
+                                                   0, 0, 0);
+               if (!HeapTupleIsValid(languageTuple))
+               {
+                   elog(WARN, "fmgr_info: %s %ld",
+                        "Cache lookup for language %d failed",
+                        ObjectIdGetDatum(procedureStruct->prolang));
+               }
+               languageStruct = (Form_pg_language)
+                   GETSTRUCT(languageTuple);
+               if (languageStruct->lanispl)
+               {
+                   user_fn = (func_ptr) NULL;
+                   *nargs = procedureStruct->pronargs;
+               }
+               else
+               {
+                   elog(WARN, "fmgr_info: function %d: unknown language %d",
+                        procedureId, language);
+               }
+               break;
        }
    }
    else
@@ -252,7 +337,7 @@ fmgr_ptr(func_ptr user_fn, Oid func_id,...)
  * to fmgr_c().
  */
 char      *
-fmgr_array_args(Oid procedureId, int nargs, char *args[], bool *isNull)
+fmgr_array_args(Oid procedureId, int nargs, char *args[], bool * isNull)
 {
    func_ptr    user_fn;
    int         true_arguments;
index 8c8490b4861d43aa09ee8e5a78a01ddcb1758c2d..d666688cb40cfced76127a85c85a9daaa880a293 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_language.h,v 1.4 1997/09/08 02:35:16 momjian Exp $
+ * $Id: pg_language.h,v 1.5 1997/10/28 15:08:05 vadim Exp $
  *
  * NOTES
  *   the genbki.sh script reads this file and generates .bki
@@ -33,6 +33,9 @@
 CATALOG(pg_language)
 {
    NameData    lanname;
+   bool        lanispl;        /* Is a procedural language */
+   bool        lanpltrusted;   /* PL is trusted */
+   Oid         lanplcallfoid;  /* Call handler for PL */
    text        lancompiler;    /* VARIABLE LENGTH FIELD */
 } FormData_pg_language;
 
@@ -47,21 +50,24 @@ typedef FormData_pg_language *Form_pg_language;
  *     compiler constants for pg_language
  * ----------------
  */
-#define Natts_pg_language              2
+#define Natts_pg_language              5
 #define Anum_pg_language_lanname       1
-#define Anum_pg_language_lancompiler   2
+#define Anum_pg_language_lanispl       2
+#define Anum_pg_language_lanpltrusted      3
+#define Anum_pg_language_lanplcallfoid     4
+#define Anum_pg_language_lancompiler       5
 
 /* ----------------
  *     initial contents of pg_language
  * ----------------
  */
 
-DATA(insert OID = 11 ( internal "n/a" ));
+DATA(insert OID = 11 ( internal f 0 0 "n/a" ));
 #define INTERNALlanguageId 11
-DATA(insert OID = 12 ( lisp "/usr/ucb/liszt" ));
-DATA(insert OID = 13 ( "C" "/bin/cc" ));
+DATA(insert OID = 12 ( lisp f 0 0 "/usr/ucb/liszt" ));
+DATA(insert OID = 13 ( "C" f 0 0 "/bin/cc" ));
 #define ClanguageId 13
-DATA(insert OID = 14 ( "sql" "postgres"));
+DATA(insert OID = 14 ( "sql" f 0 0 "postgres"));
 #define SQLlanguageId 14
 
 
diff --git a/src/include/commands/proclang.h b/src/include/commands/proclang.h
new file mode 100644 (file)
index 0000000..af6182c
--- /dev/null
@@ -0,0 +1,17 @@
+/*-------------------------------------------------------------------------
+ *
+ * proclang.h--
+ *   prototypes for proclang.c.
+ *
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PROCLANG_H
+#define PROCLANG_H
+
+#include 
+
+extern void CreateProceduralLanguage(CreatePLangStmt * stmt);
+extern void DropProceduralLanguage(DropPLangStmt * stmt);
+
+#endif                         /* PROCLANG_H */
index f60e39d79143084840d7b228aefe8b01e1432091..152a1cdd28e2ed548233f8ed815a33c485b4fb72 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: nodes.h,v 1.15 1997/09/29 06:01:44 vadim Exp $
+ * $Id: nodes.h,v 1.16 1997/10/28 15:10:37 vadim Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -185,6 +185,8 @@ typedef enum NodeTag
    T_VariableResetStmt,
    T_CreateTrigStmt,
    T_DropTrigStmt,
+   T_CreatePLangStmt,
+   T_DropPLangStmt,
 
    T_A_Expr = 700,
    T_Attr,
index 0bff16711c83bed18c26bf886a6dc98ca941542f..6e9e49b1c016fa2285bc724220976e99ff87fba2 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parsenodes.h,v 1.28 1997/09/29 06:01:46 vadim Exp $
+ * $Id: parsenodes.h,v 1.29 1997/10/28 15:10:39 vadim Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -64,7 +64,7 @@ typedef struct Query
    List       *join_relation_list_;    /* list of relations generated by
                                         * joins */
    bool        query_is_archival_;     /* archival query flag */
-} Query;
+}          Query;
 
 
 /*****************************************************************************
@@ -98,7 +98,7 @@ typedef struct ChangeACLStmt
    struct AclItem *aclitem;
    unsigned    modechg;
    List       *relNames;
-} ChangeACLStmt;
+}          ChangeACLStmt;
 
 /* ----------------------
  *     Close Portal Statement
@@ -108,7 +108,7 @@ typedef struct ClosePortalStmt
 {
    NodeTag     type;
    char       *portalname;     /* name of the portal (cursor) */
-} ClosePortalStmt;
+}          ClosePortalStmt;
 
 /* ----------------------
  *     Copy Statement
@@ -123,7 +123,7 @@ typedef struct CopyStmt
    int         direction;      /* TO or FROM */
    char       *filename;       /* if NULL, use stdin/stdout */
    char       *delimiter;      /* delimiter character, \t by default */
-} CopyStmt;
+}          CopyStmt;
 
 /* ----------------------
  *     Create Table Statement
@@ -145,19 +145,19 @@ typedef struct CreateStmt
    int         location;       /* smgrid (-1 if none) */
    int         archiveLoc;     /* smgrid (-1 if none) */
    List       *constraints;    /* list of constraints (ConstaintDef) */
-} CreateStmt;
+}          CreateStmt;
 
 typedef enum ConstrType
 {
    CONSTR_NONE, CONSTR_CHECK   /* type of constaints */
-} ConstrType;
+}          ConstrType;
 
 typedef struct ConstraintDef
 {
    ConstrType  type;
    char       *name;           /* name */
    void       *def;            /* definition */
-} ConstraintDef;
+}          ConstraintDef;
 
 /* ----------------------
  *     Create/Drop TRIGGER Statements
@@ -178,14 +178,35 @@ typedef struct CreateTrigStmt
    char       *text;           /* AS 'text' */
    List       *attr;           /* UPDATE OF a, b,... (NI) or NULL */
    char       *when;           /* WHEN 'a > 10 ...' (NI) or NULL */
-} CreateTrigStmt;
+}          CreateTrigStmt;
 
 typedef struct DropTrigStmt
 {
    NodeTag     type;
    char       *trigname;       /* TRIGGER' name */
    char       *relname;        /* triggered relation */
-} DropTrigStmt;
+}          DropTrigStmt;
+
+
+/* ----------------------
+ *     Create/Drop PROCEDURAL LANGUAGE Statement
+ * ----------------------
+ */
+typedef struct CreatePLangStmt
+{
+   NodeTag     type;
+   char       *plname;         /* PL name */
+   char       *plhandler;      /* PL call handler function */
+   char       *plcompiler;     /* lancompiler text */
+   bool        pltrusted;      /* PL is trusted */
+}          CreatePLangStmt;
+
+typedef struct DropPLangStmt
+{
+   NodeTag     type;
+   char       *plname;         /* PL name */
+}          DropPLangStmt;
+
 
 /* ----------------------
  *     Create SEQUENCE Statement
@@ -197,7 +218,7 @@ typedef struct CreateSeqStmt
    NodeTag     type;
    char       *seqname;        /* the relation to create */
    List       *options;
-} CreateSeqStmt;
+}          CreateSeqStmt;
 
 /* ----------------------
  *     Create Version Statement
@@ -210,7 +231,7 @@ typedef struct VersionStmt
    int         direction;      /* FORWARD | BACKWARD */
    char       *fromRelname;    /* relation to create a version */
    char       *date;           /* date of the snapshot */
-} VersionStmt;
+}          VersionStmt;
 
 /* ----------------------
  *     Create {Operator|Type|Aggregate} Statement
@@ -222,7 +243,7 @@ typedef struct DefineStmt
    int         defType;        /* OPERATOR|P_TYPE|AGGREGATE */
    char       *defname;
    List       *definition;     /* a list of DefElem */
-} DefineStmt;
+}          DefineStmt;
 
 /* ----------------------
  *     Drop Table Statement
@@ -233,7 +254,7 @@ typedef struct DestroyStmt
    NodeTag     type;
    List       *relNames;       /* relations to be dropped */
    bool        sequence;
-} DestroyStmt;
+}          DestroyStmt;
 
 /* ----------------------
  *     Extend Index Statement
@@ -246,7 +267,7 @@ typedef struct ExtendStmt
    Node       *whereClause;    /* qualifications */
    List       *rangetable;     /* range table, filled in by
                                 * transformStmt() */
-} ExtendStmt;
+}          ExtendStmt;
 
 /* ----------------------
  *     Begin Recipe Statement
@@ -256,7 +277,7 @@ typedef struct RecipeStmt
 {
    NodeTag     type;
    char       *recipeName;     /* name of the recipe */
-} RecipeStmt;
+}          RecipeStmt;
 
 /* ----------------------
  *     Fetch Statement
@@ -269,7 +290,7 @@ typedef struct FetchStmt
    int         howMany;        /* amount to fetch ("ALL" --> 0) */
    char       *portalname;     /* name of portal (cursor) */
    bool        ismove;         /* TRUE if MOVE */
-} FetchStmt;
+}          FetchStmt;
 
 /* ----------------------
  *     Create Index Statement
@@ -288,7 +309,7 @@ typedef struct IndexStmt
                                 * transformStmt() */
    bool       *lossy;          /* is index lossy? */
    bool        unique;         /* is index unique? */
-} IndexStmt;
+}          IndexStmt;
 
 /* ----------------------
  *     Create Function Statement
@@ -305,7 +326,7 @@ typedef struct ProcedureStmt
    List       *withClause;     /* a list of ParamString */
    char       *as;             /* the SQL statement or filename */
    char       *language;       /* C or SQL */
-} ProcedureStmt;
+}          ProcedureStmt;
 
 /* ----------------------
  *     Purge Statement
@@ -317,7 +338,7 @@ typedef struct PurgeStmt
    char       *relname;        /* relation to purge */
    char       *beforeDate;     /* purge before this date */
    char       *afterDate;      /* purge after this date */
-} PurgeStmt;
+}          PurgeStmt;
 
 /* ----------------------
  *     Drop Aggregate Statement
@@ -328,7 +349,7 @@ typedef struct RemoveAggrStmt
    NodeTag     type;
    char       *aggname;        /* aggregate to drop */
    char       *aggtype;        /* for this type */
-} RemoveAggrStmt;
+}          RemoveAggrStmt;
 
 /* ----------------------
  *     Drop Function Statement
@@ -339,7 +360,7 @@ typedef struct RemoveFuncStmt
    NodeTag     type;
    char       *funcname;       /* function to drop */
    List       *args;           /* types of the arguments */
-} RemoveFuncStmt;
+}          RemoveFuncStmt;
 
 /* ----------------------
  *     Drop Operator Statement
@@ -350,7 +371,7 @@ typedef struct RemoveOperStmt
    NodeTag     type;
    char       *opname;         /* operator to drop */
    List       *args;           /* types of the arguments */
-} RemoveOperStmt;
+}          RemoveOperStmt;
 
 /* ----------------------
  *     Drop {Type|Index|Rule|View} Statement
@@ -361,7 +382,7 @@ typedef struct RemoveStmt
    NodeTag     type;
    int         removeType;     /* P_TYPE|INDEX|RULE|VIEW */
    char       *name;           /* name to drop */
-} RemoveStmt;
+}          RemoveStmt;
 
 /* ----------------------
  *     Alter Table Statement
@@ -376,7 +397,7 @@ typedef struct RenameStmt
                                 * the new name. Otherwise, rename this
                                 * column name. */
    char       *newname;        /* the new name */
-} RenameStmt;
+}          RenameStmt;
 
 /* ----------------------
  *     Create Rule Statement
@@ -391,7 +412,7 @@ typedef struct RuleStmt
    struct Attr *object;        /* object affected */
    bool        instead;        /* is a 'do instead'? */
    List       *actions;        /* the action statements */
-} RuleStmt;
+}          RuleStmt;
 
 /* ----------------------
  *     Notify Statement
@@ -401,7 +422,7 @@ typedef struct NotifyStmt
 {
    NodeTag     type;
    char       *relname;        /* relation to notify */
-} NotifyStmt;
+}          NotifyStmt;
 
 /* ----------------------
  *     Listen Statement
@@ -411,7 +432,7 @@ typedef struct ListenStmt
 {
    NodeTag     type;
    char       *relname;        /* relation to listen on */
-} ListenStmt;
+}          ListenStmt;
 
 /* ----------------------
  *     {Begin|Abort|End} Transaction Statement
@@ -421,7 +442,7 @@ typedef struct TransactionStmt
 {
    NodeTag     type;
    int         command;        /* BEGIN|END|ABORT */
-} TransactionStmt;
+}          TransactionStmt;
 
 /* ----------------------
  *     Create View Statement
@@ -432,7 +453,7 @@ typedef struct ViewStmt
    NodeTag     type;
    char       *viewname;       /* name of the view */
    Query      *query;          /* the SQL statement */
-} ViewStmt;
+}          ViewStmt;
 
 /* ----------------------
  *     Load Statement
@@ -442,7 +463,7 @@ typedef struct LoadStmt
 {
    NodeTag     type;
    char       *filename;       /* file to load */
-} LoadStmt;
+}          LoadStmt;
 
 /* ----------------------
  *     Createdb Statement
@@ -452,7 +473,7 @@ typedef struct CreatedbStmt
 {
    NodeTag     type;
    char       *dbname;         /* database to create */
-} CreatedbStmt;
+}          CreatedbStmt;
 
 /* ----------------------
  *     Destroydb Statement
@@ -462,7 +483,7 @@ typedef struct DestroydbStmt
 {
    NodeTag     type;
    char       *dbname;         /* database to drop */
-} DestroydbStmt;
+}          DestroydbStmt;
 
 /* ----------------------
  *     Cluster Statement (support pbrown's cluster index implementation)
@@ -473,7 +494,7 @@ typedef struct ClusterStmt
    NodeTag     type;
    char       *relname;        /* relation being indexed */
    char       *indexname;      /* original index defined */
-} ClusterStmt;
+}          ClusterStmt;
 
 /* ----------------------
  *     Vacuum Statement
@@ -486,7 +507,7 @@ typedef struct VacuumStmt
    bool        analyze;        /* analyze data */
    char       *vacrel;         /* table to vacuum */
    List       *va_spec;        /* columns to analyse */
-} VacuumStmt;
+}          VacuumStmt;
 
 /* ----------------------
  *     Explain Statement
@@ -497,7 +518,7 @@ typedef struct ExplainStmt
    NodeTag     type;
    Query      *query;          /* the query */
    bool        verbose;        /* print plan info */
-} ExplainStmt;
+}          ExplainStmt;
 
 /* ----------------------
  * Set Statement
@@ -509,7 +530,7 @@ typedef struct VariableSetStmt
    NodeTag     type;
    char       *name;
    char       *value;
-} VariableSetStmt;
+}          VariableSetStmt;
 
 /* ----------------------
  * Show Statement
@@ -520,7 +541,7 @@ typedef struct VariableShowStmt
 {
    NodeTag     type;
    char       *name;
-} VariableShowStmt;
+}          VariableShowStmt;
 
 /* ----------------------
  * Reset Statement
@@ -531,7 +552,7 @@ typedef struct VariableResetStmt
 {
    NodeTag     type;
    char       *name;
-} VariableResetStmt;
+}          VariableResetStmt;
 
 
 /*****************************************************************************
@@ -561,7 +582,7 @@ typedef struct DeleteStmt
    NodeTag     type;
    char       *relname;        /* relation to delete from */
    Node       *whereClause;    /* qualifications */
-} DeleteStmt;
+}          DeleteStmt;
 
 /* ----------------------
  *     Update Statement
@@ -574,7 +595,7 @@ typedef struct ReplaceStmt
    List       *targetList;     /* the target list (of ResTarget) */
    Node       *whereClause;    /* qualifications */
    List       *fromClause;     /* the from clause */
-} ReplaceStmt;
+}          ReplaceStmt;
 
 /* ----------------------
  *     Create Cursor Statement
@@ -591,7 +612,7 @@ typedef struct CursorStmt
    Node       *whereClause;    /* qualifications */
    List       *groupClause;    /* group by clause */
    List       *sortClause;     /* sort clause (a list of SortGroupBy's) */
-} CursorStmt;
+}          CursorStmt;
 
 /* ----------------------
  *     Select Statement
@@ -609,7 +630,7 @@ typedef struct RetrieveStmt
    Node       *havingClause;   /* having conditional-expression */
    List       *selectClause;   /* subselect parameters */
    List       *sortClause;     /* sort clause (a list of SortGroupBy's) */
-} RetrieveStmt;
+}          RetrieveStmt;
 
 
 /****************************************************************************
@@ -628,7 +649,7 @@ typedef struct SubSelect
    Node       *whereClause;    /* qualifications */
    List       *groupClause;    /* group by clause */
    Node       *havingClause;   /* having conditional-expression */
-} SubSelect;
+}          SubSelect;
 
 /*
  * TypeName - specifies a type in definitions
@@ -641,7 +662,7 @@ typedef struct TypeName
    bool        setof;          /* is a set? */
    List       *arrayBounds;    /* array bounds */
    int         typlen;         /* length for char() and varchar() */
-} TypeName;
+}          TypeName;
 
 /*
  * ParamNo - specifies a parameter reference
@@ -651,7 +672,7 @@ typedef struct ParamNo
    NodeTag     type;
    int         number;         /* the number of the parameter */
    TypeName   *typename;       /* the typecast */
-} ParamNo;
+}          ParamNo;
 
 /*
  * A_Expr - binary expressions
@@ -702,7 +723,7 @@ typedef struct ColumnDef
    TypeName   *typename;       /* type of column */
    bool        is_not_null;    /* flag to NOT NULL constraint */
    char       *defval;         /* default value of column */
-} ColumnDef;
+}          ColumnDef;
 
 /*
  * Ident -
@@ -718,7 +739,7 @@ typedef struct Ident
    List       *indirection;    /* array references */
    bool        isRel;          /* is a relation - filled in by
                                 * transformExpr() */
-} Ident;
+}          Ident;
 
 /*
  * FuncCall - a function/aggregate invocation
@@ -728,7 +749,7 @@ typedef struct FuncCall
    NodeTag     type;
    char       *funcname;       /* name of function */
    List       *args;           /* the arguments (list of exprs) */
-} FuncCall;
+}          FuncCall;
 
 /*
  * A_Indices - array reference or bounds ([lidx:uidx] or [uidx])
@@ -751,7 +772,7 @@ typedef struct ResTarget
    List       *indirection;    /* array references */
    Node       *val;            /* the value of the result (A_Expr or
                                 * Attr) (or A_Const) */
-} ResTarget;
+}          ResTarget;
 
 /*
  * ParamString - used in with clauses
@@ -761,7 +782,7 @@ typedef struct ParamString
    NodeTag     type;
    char       *name;
    char       *val;
-} ParamString;
+}          ParamString;
 
 /*
  * TimeRange - specifies a time range
@@ -771,7 +792,7 @@ typedef struct TimeRange
    NodeTag     type;
    char       *startDate;
    char       *endDate;        /* snapshot if NULL */
-} TimeRange;
+}          TimeRange;
 
 /*
  * RelExpr - relation expressions
@@ -782,7 +803,7 @@ typedef struct RelExpr
    char       *relname;        /* the relation name */
    bool        inh;            /* inheritance query */
    TimeRange  *timeRange;      /* the time range */
-} RelExpr;
+}          RelExpr;
 
 /*
  * SortGroupBy - for order by clause
@@ -794,7 +815,7 @@ typedef struct SortGroupBy
    char       *range;
    char       *name;           /* name of column to sort on */
    char       *useOp;          /* operator to use */
-} SortGroupBy;
+}          SortGroupBy;
 
 /*
  * RangeVar - range variable, used in from clauses
@@ -804,7 +825,7 @@ typedef struct RangeVar
    NodeTag     type;
    RelExpr    *relExpr;        /* the relation expression */
    char       *name;           /* the name to be referenced (optional) */
-} RangeVar;
+}          RangeVar;
 
 /*
  * IndexElem - index parameters (used in create index)
@@ -816,7 +837,7 @@ typedef struct IndexElem
    List       *args;           /* if not NULL, function index */
    char       *class;
    TypeName   *tname;          /* type of index's keys (optional) */
-} IndexElem;
+}          IndexElem;
 
 /*
  * DefElem -
@@ -827,7 +848,7 @@ typedef struct DefElem
    NodeTag     type;
    char       *defname;
    Node       *arg;            /* a (Value *) or a (TypeName *) */
-} DefElem;
+}          DefElem;
 
 
 /****************************************************************************
@@ -847,7 +868,7 @@ typedef struct TargetEntry
    Resdom     *resdom;         /* fjoin overload this to be a list?? */
    Fjoin      *fjoin;
    Node       *expr;           /* can be a list too */
-} TargetEntry;
+}          TargetEntry;
 
 /*
  * RangeTblEntry -
@@ -873,7 +894,7 @@ typedef struct RangeTblEntry
    bool        archive;        /* filled in by plan_archive */
    bool        inFromCl;       /* comes from From Clause */
    TimeQual    timeQual;       /* filled in by pg_plan */
-} RangeTblEntry;
+}          RangeTblEntry;
 
 /*
  * SortClause -
@@ -884,7 +905,7 @@ typedef struct SortClause
    NodeTag     type;
    Resdom     *resdom;         /* attributes in tlist to be sorted */
    Oid         opoid;          /* sort operators */
-} SortClause;
+}          SortClause;
 
 /*
  * GroupClause -
@@ -895,6 +916,6 @@ typedef struct GroupClause
    NodeTag     type;
    TargetEntry *entry;         /* attributes to group on */
    Oid         grpOpoid;       /* the sort operator to use */
-} GroupClause;
+}          GroupClause;
 
 #endif                         /* PARSENODES_H */
index 0dbf0e1c397337d1e07d3151b2bf315fe5cc60a2..951e12d6f3040aa1c81fa05a093e10558ff62b25 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: rel.h,v 1.12 1997/09/08 21:55:16 momjian Exp $
+ * $Id: rel.h,v 1.13 1997/10/28 15:11:43 vadim Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -25,6 +25,7 @@ typedef struct Trigger
    char       *tgname;
    Oid         tgfoid;
    func_ptr    tgfunc;
+   func_ptr    tgplfunc;
    int16       tgtype;
    int16       tgnargs;
    int16       tgattr[8];
index 54c42a198444d90c296d72f0f3c2412508caf08d..0e37771a67ea591753a5e137243d4d13bcffa80c 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: syscache.h,v 1.7 1997/09/08 21:55:17 momjian Exp $
+ * $Id: syscache.h,v 1.8 1997/10/28 15:11:45 vadim Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -59,6 +59,7 @@
 #define REWRITENAME        25
 #define PROSRC         26
 #define CLADEFTYPE     27
+#define LANOID         28
 
 /* ----------------
  *     struct cachedesc:       information needed for a call to InitSysCache()