#include "nodes/parsenodes.h"

Go to the source code of this file.
Functions | |
| Oid | CreateProceduralLanguage (CreatePLangStmt *stmt) |
| void | DropProceduralLanguageById (Oid langOid) |
| bool | PLTemplateExists (const char *languageName) |
| Oid | get_language_oid (const char *langname, bool missing_ok) |
| Oid CreateProceduralLanguage | ( | CreatePLangStmt * | stmt | ) |
Definition at line 64 of file proclang.c.
References ACL_KIND_DATABASE, aclcheck_error(), ACLCHECK_NOT_OWNER, BOOTSTRAP_SUPERUSERID, buildoidvector(), ClanguageId, create_proc_lang(), ereport, errcode(), errhint(), errmsg(), ERROR, find_language_template(), get_database_name(), get_func_rettype(), GetUserId(), LANGUAGE_HANDLEROID, LookupFuncName(), MyDatabaseId, NameListToString(), NIL, NOTICE, NULL, OidIsValid, OPAQUEOID, PG_CATALOG_NAMESPACE, pg_database_ownercheck(), CreatePLangStmt::plhandler, CreatePLangStmt::plinline, CreatePLangStmt::plname, CreatePLangStmt::pltrusted, CreatePLangStmt::plvalidator, PointerGetDatum, ProcedureCreate(), PROVOLATILE_VOLATILE, CreatePLangStmt::replace, SetFunctionReturnType(), superuser(), SystemFuncName(), PLTemplate::tmpldbacreate, PLTemplate::tmplhandler, PLTemplate::tmplinline, PLTemplate::tmpllibrary, PLTemplate::tmpltrusted, PLTemplate::tmplvalidator, VOIDOID, and WARNING.
Referenced by ProcessUtilitySlow().
{
PLTemplate *pltemplate;
Oid handlerOid,
inlineOid,
valOid;
Oid funcrettype;
Oid funcargtypes[1];
/*
* If we have template information for the language, ignore the supplied
* parameters (if any) and use the template information.
*/
if ((pltemplate = find_language_template(stmt->plname)) != NULL)
{
List *funcname;
/*
* Give a notice if we are ignoring supplied parameters.
*/
if (stmt->plhandler)
ereport(NOTICE,
(errmsg("using pg_pltemplate information instead of CREATE LANGUAGE parameters")));
/*
* Check permission
*/
if (!superuser())
{
if (!pltemplate->tmpldbacreate)
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to create procedural language \"%s\"",
stmt->plname)));
if (!pg_database_ownercheck(MyDatabaseId, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE,
get_database_name(MyDatabaseId));
}
/*
* Find or create the handler function, which we force to be in the
* pg_catalog schema. If already present, it must have the correct
* return type.
*/
funcname = SystemFuncName(pltemplate->tmplhandler);
handlerOid = LookupFuncName(funcname, 0, funcargtypes, true);
if (OidIsValid(handlerOid))
{
funcrettype = get_func_rettype(handlerOid);
if (funcrettype != LANGUAGE_HANDLEROID)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("function %s must return type \"language_handler\"",
NameListToString(funcname))));
}
else
{
handlerOid = ProcedureCreate(pltemplate->tmplhandler,
PG_CATALOG_NAMESPACE,
false, /* replace */
false, /* returnsSet */
LANGUAGE_HANDLEROID,
BOOTSTRAP_SUPERUSERID,
ClanguageId,
F_FMGR_C_VALIDATOR,
pltemplate->tmplhandler,
pltemplate->tmpllibrary,
false, /* isAgg */
false, /* isWindowFunc */
false, /* security_definer */
false, /* isLeakProof */
false, /* isStrict */
PROVOLATILE_VOLATILE,
buildoidvector(funcargtypes, 0),
PointerGetDatum(NULL),
PointerGetDatum(NULL),
PointerGetDatum(NULL),
NIL,
PointerGetDatum(NULL),
1,
0);
}
/*
* Likewise for the anonymous block handler, if required; but we don't
* care about its return type.
*/
if (pltemplate->tmplinline)
{
funcname = SystemFuncName(pltemplate->tmplinline);
funcargtypes[0] = INTERNALOID;
inlineOid = LookupFuncName(funcname, 1, funcargtypes, true);
if (!OidIsValid(inlineOid))
{
inlineOid = ProcedureCreate(pltemplate->tmplinline,
PG_CATALOG_NAMESPACE,
false, /* replace */
false, /* returnsSet */
VOIDOID,
BOOTSTRAP_SUPERUSERID,
ClanguageId,
F_FMGR_C_VALIDATOR,
pltemplate->tmplinline,
pltemplate->tmpllibrary,
false, /* isAgg */
false, /* isWindowFunc */
false, /* security_definer */
false, /* isLeakProof */
true, /* isStrict */
PROVOLATILE_VOLATILE,
buildoidvector(funcargtypes, 1),
PointerGetDatum(NULL),
PointerGetDatum(NULL),
PointerGetDatum(NULL),
NIL,
PointerGetDatum(NULL),
1,
0);
}
}
else
inlineOid = InvalidOid;
/*
* Likewise for the validator, if required; but we don't care about
* its return type.
*/
if (pltemplate->tmplvalidator)
{
funcname = SystemFuncName(pltemplate->tmplvalidator);
funcargtypes[0] = OIDOID;
valOid = LookupFuncName(funcname, 1, funcargtypes, true);
if (!OidIsValid(valOid))
{
valOid = ProcedureCreate(pltemplate->tmplvalidator,
PG_CATALOG_NAMESPACE,
false, /* replace */
false, /* returnsSet */
VOIDOID,
BOOTSTRAP_SUPERUSERID,
ClanguageId,
F_FMGR_C_VALIDATOR,
pltemplate->tmplvalidator,
pltemplate->tmpllibrary,
false, /* isAgg */
false, /* isWindowFunc */
false, /* security_definer */
false, /* isLeakProof */
true, /* isStrict */
PROVOLATILE_VOLATILE,
buildoidvector(funcargtypes, 1),
PointerGetDatum(NULL),
PointerGetDatum(NULL),
PointerGetDatum(NULL),
NIL,
PointerGetDatum(NULL),
1,
0);
}
}
else
valOid = InvalidOid;
/* ok, create it */
return create_proc_lang(stmt->plname, stmt->replace, GetUserId(),
handlerOid, inlineOid,
valOid, pltemplate->tmpltrusted);
}
else
{
/*
* No template, so use the provided information. If there's no
* handler clause, the user is trying to rely on a template that we
* don't have, so complain accordingly.
*/
if (!stmt->plhandler)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("unsupported language \"%s\"",
stmt->plname),
errhint("The supported languages are listed in the pg_pltemplate system catalog.")));
/*
* Check permission
*/
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to create custom procedural language")));
/*
* Lookup the PL handler function and check that it is of the expected
* return type
*/
handlerOid = LookupFuncName(stmt->plhandler, 0, funcargtypes, false);
funcrettype = get_func_rettype(handlerOid);
if (funcrettype != LANGUAGE_HANDLEROID)
{
/*
* We allow OPAQUE just so we can load old dump files. When we
* see a handler function declared OPAQUE, change it to
* LANGUAGE_HANDLER. (This is probably obsolete and removable?)
*/
if (funcrettype == OPAQUEOID)
{
ereport(WARNING,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("changing return type of function %s from \"opaque\" to \"language_handler\"",
NameListToString(stmt->plhandler))));
SetFunctionReturnType(handlerOid, LANGUAGE_HANDLEROID);
}
else
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("function %s must return type \"language_handler\"",
NameListToString(stmt->plhandler))));
}
/* validate the inline function */
if (stmt->plinline)
{
funcargtypes[0] = INTERNALOID;
inlineOid = LookupFuncName(stmt->plinline, 1, funcargtypes, false);
/* return value is ignored, so we don't check the type */
}
else
inlineOid = InvalidOid;
/* validate the validator function */
if (stmt->plvalidator)
{
funcargtypes[0] = OIDOID;
valOid = LookupFuncName(stmt->plvalidator, 1, funcargtypes, false);
/* return value is ignored, so we don't check the type */
}
else
valOid = InvalidOid;
/* ok, create it */
return create_proc_lang(stmt->plname, stmt->replace, GetUserId(),
handlerOid, inlineOid,
valOid, stmt->pltrusted);
}
}
| void DropProceduralLanguageById | ( | Oid | langOid | ) |
Definition at line 520 of file proclang.c.
References elog, ERROR, heap_close, heap_open(), HeapTupleIsValid, LANGOID, LanguageRelationId, ObjectIdGetDatum, ReleaseSysCache(), RowExclusiveLock, SearchSysCache1, simple_heap_delete(), and HeapTupleData::t_self.
Referenced by doDeletion().
{
Relation rel;
HeapTuple langTup;
rel = heap_open(LanguageRelationId, RowExclusiveLock);
langTup = SearchSysCache1(LANGOID, ObjectIdGetDatum(langOid));
if (!HeapTupleIsValid(langTup)) /* should not happen */
elog(ERROR, "cache lookup failed for language %u", langOid);
simple_heap_delete(rel, &langTup->t_self);
ReleaseSysCache(langTup);
heap_close(rel, RowExclusiveLock);
}
Definition at line 545 of file proclang.c.
References CStringGetDatum, ereport, errcode(), errmsg(), ERROR, GetSysCacheOid1, LANGNAME, and OidIsValid.
Referenced by convert_language_name(), get_object_address_unqualified(), and objectNamesToOids().
{
Oid oid;
oid = GetSysCacheOid1(LANGNAME, CStringGetDatum(langname));
if (!OidIsValid(oid) && !missing_ok)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("language \"%s\" does not exist", langname)));
return oid;
}
| bool PLTemplateExists | ( | const char * | languageName | ) |
Definition at line 511 of file proclang.c.
References find_language_template(), and NULL.
Referenced by CreateFunction(), and ExecuteDoStmt().
{
return (find_language_template(languageName) != NULL);
}
1.7.1