PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
proclang.h File Reference
Include dependency graph for proclang.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

ObjectAddress CreateProceduralLanguage (CreatePLangStmt *stmt)
 
void DropProceduralLanguageById (Oid langOid)
 
bool PLTemplateExists (const char *languageName)
 
Oid get_language_oid (const char *langname, bool missing_ok)
 

Function Documentation

ObjectAddress 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(), INTERNALOID, InvalidOid, LANGUAGE_HANDLEROID, LookupFuncName(), MyDatabaseId, NameListToString(), NIL, NOTICE, NULL, ObjectAddress::objectId, OidIsValid, OIDOID, OPAQUEOID, PG_CATALOG_NAMESPACE, pg_database_ownercheck(), CreatePLangStmt::plhandler, CreatePLangStmt::plinline, CreatePLangStmt::plname, CreatePLangStmt::pltrusted, CreatePLangStmt::plvalidator, PointerGetDatum, ProcedureCreate(), PROPARALLEL_UNSAFE, 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().

65 {
66  PLTemplate *pltemplate;
67  ObjectAddress tmpAddr;
68  Oid handlerOid,
69  inlineOid,
70  valOid;
71  Oid funcrettype;
72  Oid funcargtypes[1];
73 
74  /*
75  * If we have template information for the language, ignore the supplied
76  * parameters (if any) and use the template information.
77  */
78  if ((pltemplate = find_language_template(stmt->plname)) != NULL)
79  {
80  List *funcname;
81 
82  /*
83  * Give a notice if we are ignoring supplied parameters.
84  */
85  if (stmt->plhandler)
87  (errmsg("using pg_pltemplate information instead of CREATE LANGUAGE parameters")));
88 
89  /*
90  * Check permission
91  */
92  if (!superuser())
93  {
94  if (!pltemplate->tmpldbacreate)
95  ereport(ERROR,
96  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
97  errmsg("must be superuser to create procedural language \"%s\"",
98  stmt->plname)));
102  }
103 
104  /*
105  * Find or create the handler function, which we force to be in the
106  * pg_catalog schema. If already present, it must have the correct
107  * return type.
108  */
109  funcname = SystemFuncName(pltemplate->tmplhandler);
110  handlerOid = LookupFuncName(funcname, 0, funcargtypes, true);
111  if (OidIsValid(handlerOid))
112  {
113  funcrettype = get_func_rettype(handlerOid);
114  if (funcrettype != LANGUAGE_HANDLEROID)
115  ereport(ERROR,
116  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
117  errmsg("function %s must return type %s",
118  NameListToString(funcname), "language_handler")));
119  }
120  else
121  {
122  tmpAddr = ProcedureCreate(pltemplate->tmplhandler,
124  false, /* replace */
125  false, /* returnsSet */
128  ClanguageId,
129  F_FMGR_C_VALIDATOR,
130  pltemplate->tmplhandler,
131  pltemplate->tmpllibrary,
132  false, /* isAgg */
133  false, /* isWindowFunc */
134  false, /* security_definer */
135  false, /* isLeakProof */
136  false, /* isStrict */
139  buildoidvector(funcargtypes, 0),
143  NIL,
146  1,
147  0);
148  handlerOid = tmpAddr.objectId;
149  }
150 
151  /*
152  * Likewise for the anonymous block handler, if required; but we don't
153  * care about its return type.
154  */
155  if (pltemplate->tmplinline)
156  {
157  funcname = SystemFuncName(pltemplate->tmplinline);
158  funcargtypes[0] = INTERNALOID;
159  inlineOid = LookupFuncName(funcname, 1, funcargtypes, true);
160  if (!OidIsValid(inlineOid))
161  {
162  tmpAddr = ProcedureCreate(pltemplate->tmplinline,
164  false, /* replace */
165  false, /* returnsSet */
166  VOIDOID,
168  ClanguageId,
169  F_FMGR_C_VALIDATOR,
170  pltemplate->tmplinline,
171  pltemplate->tmpllibrary,
172  false, /* isAgg */
173  false, /* isWindowFunc */
174  false, /* security_definer */
175  false, /* isLeakProof */
176  true, /* isStrict */
179  buildoidvector(funcargtypes, 1),
183  NIL,
186  1,
187  0);
188  inlineOid = tmpAddr.objectId;
189  }
190  }
191  else
192  inlineOid = InvalidOid;
193 
194  /*
195  * Likewise for the validator, if required; but we don't care about
196  * its return type.
197  */
198  if (pltemplate->tmplvalidator)
199  {
200  funcname = SystemFuncName(pltemplate->tmplvalidator);
201  funcargtypes[0] = OIDOID;
202  valOid = LookupFuncName(funcname, 1, funcargtypes, true);
203  if (!OidIsValid(valOid))
204  {
205  tmpAddr = ProcedureCreate(pltemplate->tmplvalidator,
207  false, /* replace */
208  false, /* returnsSet */
209  VOIDOID,
211  ClanguageId,
212  F_FMGR_C_VALIDATOR,
213  pltemplate->tmplvalidator,
214  pltemplate->tmpllibrary,
215  false, /* isAgg */
216  false, /* isWindowFunc */
217  false, /* security_definer */
218  false, /* isLeakProof */
219  true, /* isStrict */
222  buildoidvector(funcargtypes, 1),
226  NIL,
229  1,
230  0);
231  valOid = tmpAddr.objectId;
232  }
233  }
234  else
235  valOid = InvalidOid;
236 
237  /* ok, create it */
238  return create_proc_lang(stmt->plname, stmt->replace, GetUserId(),
239  handlerOid, inlineOid,
240  valOid, pltemplate->tmpltrusted);
241  }
242  else
243  {
244  /*
245  * No template, so use the provided information. If there's no
246  * handler clause, the user is trying to rely on a template that we
247  * don't have, so complain accordingly.
248  */
249  if (!stmt->plhandler)
250  ereport(ERROR,
251  (errcode(ERRCODE_UNDEFINED_OBJECT),
252  errmsg("unsupported language \"%s\"",
253  stmt->plname),
254  errhint("The supported languages are listed in the pg_pltemplate system catalog.")));
255 
256  /*
257  * Check permission
258  */
259  if (!superuser())
260  ereport(ERROR,
261  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
262  errmsg("must be superuser to create custom procedural language")));
263 
264  /*
265  * Lookup the PL handler function and check that it is of the expected
266  * return type
267  */
268  handlerOid = LookupFuncName(stmt->plhandler, 0, funcargtypes, false);
269  funcrettype = get_func_rettype(handlerOid);
270  if (funcrettype != LANGUAGE_HANDLEROID)
271  {
272  /*
273  * We allow OPAQUE just so we can load old dump files. When we
274  * see a handler function declared OPAQUE, change it to
275  * LANGUAGE_HANDLER. (This is probably obsolete and removable?)
276  */
277  if (funcrettype == OPAQUEOID)
278  {
280  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
281  errmsg("changing return type of function %s from %s to %s",
283  "opaque", "language_handler")));
285  }
286  else
287  ereport(ERROR,
288  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
289  errmsg("function %s must return type %s",
290  NameListToString(stmt->plhandler), "language_handler")));
291  }
292 
293  /* validate the inline function */
294  if (stmt->plinline)
295  {
296  funcargtypes[0] = INTERNALOID;
297  inlineOid = LookupFuncName(stmt->plinline, 1, funcargtypes, false);
298  /* return value is ignored, so we don't check the type */
299  }
300  else
301  inlineOid = InvalidOid;
302 
303  /* validate the validator function */
304  if (stmt->plvalidator)
305  {
306  funcargtypes[0] = OIDOID;
307  valOid = LookupFuncName(stmt->plvalidator, 1, funcargtypes, false);
308  /* return value is ignored, so we don't check the type */
309  }
310  else
311  valOid = InvalidOid;
312 
313  /* ok, create it */
314  return create_proc_lang(stmt->plname, stmt->replace, GetUserId(),
315  handlerOid, inlineOid,
316  valOid, stmt->pltrusted);
317  }
318 }
#define NIL
Definition: pg_list.h:69
List * SystemFuncName(char *name)
int errhint(const char *fmt,...)
Definition: elog.c:987
char * tmpllibrary
Definition: proclang.c:51
Oid GetUserId(void)
Definition: miscinit.c:283
#define OIDOID
Definition: pg_type.h:328
#define PointerGetDatum(X)
Definition: postgres.h:564
bool tmpltrusted
Definition: proclang.c:46
#define ClanguageId
Definition: pg_language.h:77
int errcode(int sqlerrcode)
Definition: elog.c:575
bool superuser(void)
Definition: superuser.c:47
unsigned int Oid
Definition: postgres_ext.h:31
static ObjectAddress create_proc_lang(const char *languageName, bool replace, Oid languageOwner, Oid handlerOid, Oid inlineOid, Oid valOid, bool trusted)
Definition: proclang.c:324
#define OidIsValid(objectId)
Definition: c.h:534
#define LANGUAGE_HANDLEROID
Definition: pg_type.h:684
Oid get_func_rettype(Oid funcid)
Definition: lsyscache.c:1427
char * tmplinline
Definition: proclang.c:49
#define VOIDOID
Definition: pg_type.h:678
#define OPAQUEOID
Definition: pg_type.h:688
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2049
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3378
#define PG_CATALOG_NAMESPACE
Definition: pg_namespace.h:71
#define ereport(elevel, rest)
Definition: elog.h:122
bool pg_database_ownercheck(Oid db_oid, Oid roleid)
Definition: aclchk.c:4939
List * plvalidator
Definition: parsenodes.h:2298
#define PROPARALLEL_UNSAFE
Definition: pg_proc.h:5383
#define PROVOLATILE_VOLATILE
Definition: pg_proc.h:5374
bool tmpldbacreate
Definition: proclang.c:47
#define WARNING
Definition: elog.h:40
char * NameListToString(List *names)
Definition: namespace.c:2897
Oid MyDatabaseId
Definition: globals.c:76
void SetFunctionReturnType(Oid funcOid, Oid newRetType)
ObjectAddress ProcedureCreate(const char *procedureName, Oid procNamespace, bool replace, bool returnsSet, Oid returnType, Oid proowner, Oid languageObjectId, Oid languageValidator, const char *prosrc, const char *probin, bool isAgg, bool isWindowFunc, bool security_definer, bool isLeakProof, bool isStrict, char volatility, char parallel, oidvector *parameterTypes, Datum allParameterTypes, Datum parameterModes, Datum parameterNames, List *parameterDefaults, Datum trftypes, Datum proconfig, float4 procost, float4 prorows)
Definition: pg_proc.c:67
#define InvalidOid
Definition: postgres_ext.h:36
#define INTERNALOID
Definition: pg_type.h:686
#define NOTICE
Definition: elog.h:37
#define NULL
Definition: c.h:226
oidvector * buildoidvector(const Oid *oids, int n)
Definition: oid.c:167
#define BOOTSTRAP_SUPERUSERID
Definition: pg_authid.h:104
Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError)
Definition: parse_func.c:1908
int errmsg(const char *fmt,...)
Definition: elog.c:797
char * tmplhandler
Definition: proclang.c:48
static PLTemplate * find_language_template(const char *languageName)
Definition: proclang.c:451
Definition: pg_list.h:45
char * tmplvalidator
Definition: proclang.c:50
void DropProceduralLanguageById ( Oid  langOid)

Definition at line 528 of file proclang.c.

References CatalogTupleDelete(), elog, ERROR, heap_close, heap_open(), HeapTupleIsValid, LANGOID, LanguageRelationId, ObjectIdGetDatum, ReleaseSysCache(), RowExclusiveLock, SearchSysCache1, and HeapTupleData::t_self.

Referenced by doDeletion().

529 {
530  Relation rel;
531  HeapTuple langTup;
532 
534 
535  langTup = SearchSysCache1(LANGOID, ObjectIdGetDatum(langOid));
536  if (!HeapTupleIsValid(langTup)) /* should not happen */
537  elog(ERROR, "cache lookup failed for language %u", langOid);
538 
539  CatalogTupleDelete(rel, &langTup->t_self);
540 
541  ReleaseSysCache(langTup);
542 
544 }
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define heap_close(r, l)
Definition: heapam.h:97
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define LanguageRelationId
Definition: pg_language.h:29
#define elog
Definition: elog.h:219
Oid get_language_oid ( const char *  langname,
bool  missing_ok 
)

Definition at line 553 of file proclang.c.

References CStringGetDatum, ereport, errcode(), errmsg(), ERROR, GetSysCacheOid1, LANGNAME, and OidIsValid.

Referenced by convert_language_name(), CreateTransform(), get_object_address(), get_object_address_unqualified(), and objectNamesToOids().

554 {
555  Oid oid;
556 
557  oid = GetSysCacheOid1(LANGNAME, CStringGetDatum(langname));
558  if (!OidIsValid(oid) && !missing_ok)
559  ereport(ERROR,
560  (errcode(ERRCODE_UNDEFINED_OBJECT),
561  errmsg("language \"%s\" does not exist", langname)));
562  return oid;
563 }
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:534
#define GetSysCacheOid1(cacheId, key1)
Definition: syscache.h:176
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:586
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797
bool PLTemplateExists ( const char *  languageName)

Definition at line 519 of file proclang.c.

References find_language_template(), and NULL.

Referenced by CreateFunction(), and ExecuteDoStmt().

520 {
521  return (find_language_template(languageName) != NULL);
522 }
#define NULL
Definition: c.h:226
static PLTemplate * find_language_template(const char *languageName)
Definition: proclang.c:451