From: Vadim B. Mikheev Date: Tue, 28 Oct 1997 15:11:45 +0000 (+0000) Subject: Now we are able to CREATE PROCEDURAL LANGUAGE (Thanks, Jan). X-Git-Tag: REL6_3~734 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7bff4c50787c52687ad5e23d90c0c5604c57893f;p=postgresql Now we are able to CREATE PROCEDURAL LANGUAGE (Thanks, Jan). --- diff --git a/src/backend/commands/Makefile b/src/backend/commands/Makefile index 5d8e945a66..c65f04da40 100644 --- a/src/backend/commands/Makefile +++ b/src/backend/commands/Makefile @@ -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 diff --git a/src/backend/commands/define.c b/src/backend/commands/define.c index 903bb51649..9aa8c09897 100644 --- a/src/backend/commands/define.c +++ b/src/backend/commands/define.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.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 index 0000000000..2b8836b70b --- /dev/null +++ b/src/backend/commands/proclang.c @@ -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); +} diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 9215f41055..273136b292 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -26,11 +26,11 @@ #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); diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 8132cc34d4..7eb361d3a9 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 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; + } + ; /***************************************************************************** * diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c index f3f957dbb0..b2bcce32d1 100644 --- a/src/backend/parser/keywords.c +++ b/src/backend/parser/keywords.c @@ -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}, diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 50013c8f7f..1fd20eb986 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -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 ******************************** * diff --git a/src/backend/utils/Gen_fmgrtab.sh.in b/src/backend/utils/Gen_fmgrtab.sh.in index 1d7c8d2356..409372e8ce 100644 --- a/src/backend/utils/Gen_fmgrtab.sh.in +++ b/src/backend/utils/Gen_fmgrtab.sh.in @@ -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 < $TABCFILE <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; diff --git a/src/include/catalog/pg_language.h b/src/include/catalog/pg_language.h index 8c8490b486..d666688cb4 100644 --- a/src/include/catalog/pg_language.h +++ b/src/include/catalog/pg_language.h @@ -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 index 0000000000..af6182ccca --- /dev/null +++ b/src/include/commands/proclang.h @@ -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 */ diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index f60e39d791..152a1cdd28 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: nodes.h,v 1.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, diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 0bff16711c..6e9e49b1c0 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: parsenodes.h,v 1.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 */ diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index 0dbf0e1c39..951e12d6f3 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -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]; diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h index 54c42a1984..0e37771a67 100644 --- a/src/include/utils/syscache.h +++ b/src/include/utils/syscache.h @@ -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()