1997-10-28 16:11:45 +01:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
1999-02-14 00:22:53 +01:00
|
|
|
* proclang.c
|
1997-10-28 16:11:45 +01:00
|
|
|
* PostgreSQL PROCEDURAL LANGUAGE support code.
|
|
|
|
*
|
2002-06-20 22:29:54 +02:00
|
|
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
2001-06-13 23:44:41 +02:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
2002-06-20 22:29:54 +02:00
|
|
|
* $Header: /cvsroot/pgsql/src/backend/commands/proclang.c,v 1.34 2002/06/20 20:29:27 momjian Exp $
|
2001-06-13 23:44:41 +02:00
|
|
|
*
|
1997-10-28 16:11:45 +01:00
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
#include "postgres.h"
|
|
|
|
|
2001-06-13 23:44:41 +02:00
|
|
|
#include <ctype.h>
|
|
|
|
|
1997-10-28 16:11:45 +01:00
|
|
|
#include "access/heapam.h"
|
|
|
|
#include "catalog/catname.h"
|
1999-11-22 18:56:41 +01:00
|
|
|
#include "catalog/indexing.h"
|
2002-04-09 22:35:55 +02:00
|
|
|
#include "catalog/namespace.h"
|
1997-10-28 16:11:45 +01:00
|
|
|
#include "catalog/pg_language.h"
|
1998-04-27 06:08:07 +02:00
|
|
|
#include "catalog/pg_proc.h"
|
2002-05-22 19:21:02 +02:00
|
|
|
#include "catalog/pg_type.h"
|
1997-10-28 16:11:45 +01:00
|
|
|
#include "commands/proclang.h"
|
2002-04-15 07:22:04 +02:00
|
|
|
#include "commands/defrem.h"
|
1997-10-28 16:11:45 +01:00
|
|
|
#include "fmgr.h"
|
2001-06-13 23:44:41 +02:00
|
|
|
#include "miscadmin.h"
|
2002-04-09 22:35:55 +02:00
|
|
|
#include "parser/parse_func.h"
|
2000-05-28 19:56:29 +02:00
|
|
|
#include "utils/builtins.h"
|
2002-04-09 22:35:55 +02:00
|
|
|
#include "utils/lsyscache.h"
|
1998-04-27 06:08:07 +02:00
|
|
|
#include "utils/syscache.h"
|
1997-10-28 16:11:45 +01:00
|
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------
|
|
|
|
* CREATE PROCEDURAL LANGUAGE
|
|
|
|
* ---------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
void
|
1998-02-26 05:46:47 +01:00
|
|
|
CreateProceduralLanguage(CreatePLangStmt *stmt)
|
1997-10-28 16:11:45 +01:00
|
|
|
{
|
|
|
|
char languageName[NAMEDATALEN];
|
2002-05-22 19:21:02 +02:00
|
|
|
Oid procOid, valProcOid;
|
2000-01-10 18:14:46 +01:00
|
|
|
Oid typev[FUNC_MAX_ARGS];
|
1997-10-28 16:11:45 +01:00
|
|
|
char nulls[Natts_pg_language];
|
|
|
|
Datum values[Natts_pg_language];
|
1998-08-19 04:04:17 +02:00
|
|
|
Relation rel;
|
1997-10-28 16:11:45 +01:00
|
|
|
HeapTuple tup;
|
|
|
|
TupleDesc tupDesc;
|
|
|
|
int i;
|
|
|
|
|
2001-03-22 07:16:21 +01:00
|
|
|
/*
|
1997-10-28 16:11:45 +01:00
|
|
|
* Check permission
|
|
|
|
*/
|
|
|
|
if (!superuser())
|
1998-01-05 17:40:20 +01:00
|
|
|
elog(ERROR, "Only users with Postgres superuser privilege are "
|
1997-10-28 16:11:45 +01:00
|
|
|
"permitted to create procedural languages");
|
|
|
|
|
2001-03-22 07:16:21 +01:00
|
|
|
/*
|
|
|
|
* Translate the language name and check that this language doesn't
|
|
|
|
* already exist
|
1997-10-28 16:11:45 +01:00
|
|
|
*/
|
|
|
|
case_translate_language_name(stmt->plname, languageName);
|
|
|
|
|
2000-11-16 23:30:52 +01:00
|
|
|
if (SearchSysCacheExists(LANGNAME,
|
|
|
|
PointerGetDatum(languageName),
|
|
|
|
0, 0, 0))
|
1998-01-05 17:40:20 +01:00
|
|
|
elog(ERROR, "Language %s already exists", languageName);
|
1997-10-28 16:11:45 +01:00
|
|
|
|
2001-03-22 07:16:21 +01:00
|
|
|
/*
|
|
|
|
* Lookup the PL handler function and check that it is of return type
|
|
|
|
* Opaque
|
1997-10-28 16:11:45 +01:00
|
|
|
*/
|
2002-04-09 22:35:55 +02:00
|
|
|
MemSet(typev, 0, sizeof(typev));
|
|
|
|
procOid = LookupFuncName(stmt->plhandler, 0, typev);
|
|
|
|
if (!OidIsValid(procOid))
|
1998-01-05 17:40:20 +01:00
|
|
|
elog(ERROR, "PL handler function %s() doesn't exist",
|
2002-04-09 22:35:55 +02:00
|
|
|
NameListToString(stmt->plhandler));
|
|
|
|
if (get_func_rettype(procOid) != InvalidOid)
|
2002-05-22 19:21:02 +02:00
|
|
|
elog(ERROR, "PL handler function %s() does not return type \"opaque\"",
|
2002-04-09 22:35:55 +02:00
|
|
|
NameListToString(stmt->plhandler));
|
1997-10-28 16:11:45 +01:00
|
|
|
|
2002-05-22 19:21:02 +02:00
|
|
|
/* validate the validator function */
|
|
|
|
if (stmt->plvalidator)
|
|
|
|
{
|
|
|
|
typev[0] = OIDOID;
|
|
|
|
valProcOid = LookupFuncName(stmt->plvalidator, 1, typev);
|
|
|
|
if (!OidIsValid(valProcOid))
|
|
|
|
elog(ERROR, "PL validator function %s(oid) doesn't exist",
|
|
|
|
NameListToString(stmt->plvalidator));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
valProcOid = 0;
|
|
|
|
|
2001-03-22 07:16:21 +01:00
|
|
|
/*
|
1997-10-28 16:11:45 +01:00
|
|
|
* 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);
|
2001-03-22 05:01:46 +01:00
|
|
|
values[i++] = BoolGetDatum(true); /* lanispl */
|
2000-07-06 01:12:09 +02:00
|
|
|
values[i++] = BoolGetDatum(stmt->pltrusted);
|
2002-04-09 22:35:55 +02:00
|
|
|
values[i++] = ObjectIdGetDatum(procOid);
|
2002-05-22 19:21:02 +02:00
|
|
|
values[i++] = ObjectIdGetDatum(valProcOid);
|
2000-07-06 01:12:09 +02:00
|
|
|
values[i++] = DirectFunctionCall1(textin,
|
|
|
|
CStringGetDatum(stmt->plcompiler));
|
2002-02-19 00:11:58 +01:00
|
|
|
nulls[i] = 'n'; /* lanacl */
|
1997-10-28 16:11:45 +01:00
|
|
|
|
1999-09-18 21:08:25 +02:00
|
|
|
rel = heap_openr(LanguageRelationName, RowExclusiveLock);
|
1997-10-28 16:11:45 +01:00
|
|
|
|
1998-08-19 04:04:17 +02:00
|
|
|
tupDesc = rel->rd_att;
|
1997-10-28 16:11:45 +01:00
|
|
|
tup = heap_formtuple(tupDesc, values, nulls);
|
|
|
|
|
2002-05-22 00:05:55 +02:00
|
|
|
simple_heap_insert(rel, tup);
|
1997-10-28 16:11:45 +01:00
|
|
|
|
1999-11-22 18:56:41 +01:00
|
|
|
if (RelationGetForm(rel)->relhasindex)
|
|
|
|
{
|
|
|
|
Relation idescs[Num_pg_language_indices];
|
|
|
|
|
|
|
|
CatalogOpenIndices(Num_pg_language_indices, Name_pg_language_indices, idescs);
|
|
|
|
CatalogIndexInsert(idescs, Num_pg_language_indices, rel, tup);
|
|
|
|
CatalogCloseIndices(Num_pg_language_indices, idescs);
|
|
|
|
}
|
2000-01-10 18:14:46 +01:00
|
|
|
|
1999-09-18 21:08:25 +02:00
|
|
|
heap_close(rel, RowExclusiveLock);
|
1997-10-28 16:11:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------
|
|
|
|
* DROP PROCEDURAL LANGUAGE
|
|
|
|
* ---------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
void
|
1998-02-26 05:46:47 +01:00
|
|
|
DropProceduralLanguage(DropPLangStmt *stmt)
|
1997-10-28 16:11:45 +01:00
|
|
|
{
|
|
|
|
char languageName[NAMEDATALEN];
|
|
|
|
HeapTuple langTup;
|
1998-08-19 04:04:17 +02:00
|
|
|
Relation rel;
|
1997-10-28 16:11:45 +01:00
|
|
|
|
2001-03-22 07:16:21 +01:00
|
|
|
/*
|
1997-10-28 16:11:45 +01:00
|
|
|
* Check permission
|
|
|
|
*/
|
|
|
|
if (!superuser())
|
1998-01-05 17:40:20 +01:00
|
|
|
elog(ERROR, "Only users with Postgres superuser privilege are "
|
1997-10-28 16:11:45 +01:00
|
|
|
"permitted to drop procedural languages");
|
|
|
|
|
2001-03-22 07:16:21 +01:00
|
|
|
/*
|
|
|
|
* Translate the language name, check that this language exist and is
|
|
|
|
* a PL
|
1997-10-28 16:11:45 +01:00
|
|
|
*/
|
|
|
|
case_translate_language_name(stmt->plname, languageName);
|
|
|
|
|
1999-09-18 21:08:25 +02:00
|
|
|
rel = heap_openr(LanguageRelationName, RowExclusiveLock);
|
|
|
|
|
2000-11-16 23:30:52 +01:00
|
|
|
langTup = SearchSysCacheCopy(LANGNAME,
|
|
|
|
PointerGetDatum(languageName),
|
|
|
|
0, 0, 0);
|
1997-10-28 16:11:45 +01:00
|
|
|
if (!HeapTupleIsValid(langTup))
|
1998-01-05 17:40:20 +01:00
|
|
|
elog(ERROR, "Language %s doesn't exist", languageName);
|
1997-10-28 16:11:45 +01:00
|
|
|
|
|
|
|
if (!((Form_pg_language) GETSTRUCT(langTup))->lanispl)
|
1998-01-05 17:40:20 +01:00
|
|
|
elog(ERROR, "Language %s isn't a created procedural language",
|
1997-10-28 16:11:45 +01:00
|
|
|
languageName);
|
|
|
|
|
2001-01-23 05:32:23 +01:00
|
|
|
simple_heap_delete(rel, &langTup->t_self);
|
1997-10-28 16:11:45 +01:00
|
|
|
|
1999-12-16 23:20:03 +01:00
|
|
|
heap_freetuple(langTup);
|
1999-09-18 21:08:25 +02:00
|
|
|
heap_close(rel, RowExclusiveLock);
|
1997-10-28 16:11:45 +01:00
|
|
|
}
|