PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
proclang.c File Reference
#include "postgres.h"
#include "access/genam.h"
#include "access/heapam.h"
#include "access/htup_details.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_language.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_pltemplate.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_proc_fn.h"
#include "catalog/pg_type.h"
#include "commands/dbcommands.h"
#include "commands/defrem.h"
#include "commands/proclang.h"
#include "miscadmin.h"
#include "parser/parse_func.h"
#include "parser/parser.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
#include "utils/syscache.h"
#include "utils/tqual.h"
Include dependency graph for proclang.c:

Go to the source code of this file.

Data Structures

struct  PLTemplate
 

Functions

static ObjectAddress create_proc_lang (const char *languageName, bool replace, Oid languageOwner, Oid handlerOid, Oid inlineOid, Oid valOid, bool trusted)
 
static PLTemplatefind_language_template (const char *languageName)
 
ObjectAddress CreateProceduralLanguage (CreatePLangStmt *stmt)
 
bool PLTemplateExists (const char *languageName)
 
void DropProceduralLanguageById (Oid langOid)
 
Oid get_language_oid (const char *langname, bool missing_ok)
 

Function Documentation

static ObjectAddress create_proc_lang ( const char *  languageName,
bool  replace,
Oid  languageOwner,
Oid  handlerOid,
Oid  inlineOid,
Oid  valOid,
bool  trusted 
)
static

Definition at line 324 of file proclang.c.

References ACL_KIND_LANGUAGE, aclcheck_error(), ACLCHECK_NOT_OWNER, Anum_pg_language_lanacl, Anum_pg_language_laninline, Anum_pg_language_lanispl, Anum_pg_language_lanname, Anum_pg_language_lanowner, Anum_pg_language_lanplcallfoid, Anum_pg_language_lanpltrusted, Anum_pg_language_lanvalidator, BoolGetDatum, CatalogTupleInsert(), CatalogTupleUpdate(), ObjectAddress::classId, deleteDependencyRecordsFor(), DEPENDENCY_NORMAL, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errmsg(), ERROR, heap_close, heap_form_tuple(), heap_modify_tuple(), heap_open(), HeapTupleGetOid, HeapTupleIsValid, InvokeObjectPostCreateHook, LANGNAME, LanguageRelationId, NameGetDatum, namestrcpy(), Natts_pg_language, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, OidIsValid, pg_language_ownercheck(), PointerGetDatum, ProcedureRelationId, recordDependencyOn(), recordDependencyOnCurrentExtension(), recordDependencyOnOwner(), RelationGetDescr, ReleaseSysCache(), RowExclusiveLock, SearchSysCache1, HeapTupleData::t_self, and values.

Referenced by CreateProceduralLanguage().

327 {
328  Relation rel;
329  TupleDesc tupDesc;
331  bool nulls[Natts_pg_language];
332  bool replaces[Natts_pg_language];
333  NameData langname;
334  HeapTuple oldtup;
335  HeapTuple tup;
336  bool is_update;
337  ObjectAddress myself,
338  referenced;
339 
341  tupDesc = RelationGetDescr(rel);
342 
343  /* Prepare data to be inserted */
344  memset(values, 0, sizeof(values));
345  memset(nulls, false, sizeof(nulls));
346  memset(replaces, true, sizeof(replaces));
347 
348  namestrcpy(&langname, languageName);
349  values[Anum_pg_language_lanname - 1] = NameGetDatum(&langname);
350  values[Anum_pg_language_lanowner - 1] = ObjectIdGetDatum(languageOwner);
351  values[Anum_pg_language_lanispl - 1] = BoolGetDatum(true);
352  values[Anum_pg_language_lanpltrusted - 1] = BoolGetDatum(trusted);
353  values[Anum_pg_language_lanplcallfoid - 1] = ObjectIdGetDatum(handlerOid);
354  values[Anum_pg_language_laninline - 1] = ObjectIdGetDatum(inlineOid);
355  values[Anum_pg_language_lanvalidator - 1] = ObjectIdGetDatum(valOid);
356  nulls[Anum_pg_language_lanacl - 1] = true;
357 
358  /* Check for pre-existing definition */
359  oldtup = SearchSysCache1(LANGNAME, PointerGetDatum(languageName));
360 
361  if (HeapTupleIsValid(oldtup))
362  {
363  /* There is one; okay to replace it? */
364  if (!replace)
365  ereport(ERROR,
367  errmsg("language \"%s\" already exists", languageName)));
368  if (!pg_language_ownercheck(HeapTupleGetOid(oldtup), languageOwner))
370  languageName);
371 
372  /*
373  * Do not change existing ownership or permissions. Note
374  * dependency-update code below has to agree with this decision.
375  */
376  replaces[Anum_pg_language_lanowner - 1] = false;
377  replaces[Anum_pg_language_lanacl - 1] = false;
378 
379  /* Okay, do it... */
380  tup = heap_modify_tuple(oldtup, tupDesc, values, nulls, replaces);
381  CatalogTupleUpdate(rel, &tup->t_self, tup);
382 
383  ReleaseSysCache(oldtup);
384  is_update = true;
385  }
386  else
387  {
388  /* Creating a new language */
389  tup = heap_form_tuple(tupDesc, values, nulls);
390  CatalogTupleInsert(rel, tup);
391  is_update = false;
392  }
393 
394  /*
395  * Create dependencies for the new language. If we are updating an
396  * existing language, first delete any existing pg_depend entries.
397  * (However, since we are not changing ownership or permissions, the
398  * shared dependencies do *not* need to change, and we leave them alone.)
399  */
400  myself.classId = LanguageRelationId;
401  myself.objectId = HeapTupleGetOid(tup);
402  myself.objectSubId = 0;
403 
404  if (is_update)
405  deleteDependencyRecordsFor(myself.classId, myself.objectId, true);
406 
407  /* dependency on owner of language */
408  if (!is_update)
410  languageOwner);
411 
412  /* dependency on extension */
413  recordDependencyOnCurrentExtension(&myself, is_update);
414 
415  /* dependency on the PL handler function */
416  referenced.classId = ProcedureRelationId;
417  referenced.objectId = handlerOid;
418  referenced.objectSubId = 0;
419  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
420 
421  /* dependency on the inline handler function, if any */
422  if (OidIsValid(inlineOid))
423  {
424  referenced.classId = ProcedureRelationId;
425  referenced.objectId = inlineOid;
426  referenced.objectSubId = 0;
427  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
428  }
429 
430  /* dependency on the validator function, if any */
431  if (OidIsValid(valOid))
432  {
433  referenced.classId = ProcedureRelationId;
434  referenced.objectId = valOid;
435  referenced.objectSubId = 0;
436  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
437  }
438 
439  /* Post creation hook for new procedural language */
441 
443 
444  return myself;
445 }
#define Anum_pg_language_lanvalidator
Definition: pg_language.h:64
#define NameGetDatum(X)
Definition: postgres.h:601
#define InvokeObjectPostCreateHook(classId, objectId, subId)
Definition: objectaccess.h:145
#define RelationGetDescr(relation)
Definition: rel.h:429
bool pg_language_ownercheck(Oid lan_oid, Oid roleid)
Definition: aclchk.c:4650
#define PointerGetDatum(X)
Definition: postgres.h:562
#define ProcedureRelationId
Definition: pg_proc.h:33
#define Anum_pg_language_lanacl
Definition: pg_language.h:65
long deleteDependencyRecordsFor(Oid classId, Oid objectId, bool skipExtensionDeps)
Definition: pg_depend.c:191
int errcode(int sqlerrcode)
Definition: elog.c:575
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:44
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:692
#define heap_close(r, l)
Definition: heapam.h:97
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
Definition: pg_shdepend.c:159
int namestrcpy(Name name, const char *str)
Definition: name.c:217
#define OidIsValid(objectId)
Definition: c.h:538
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:156
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
ItemPointerData t_self
Definition: htup.h:65
#define Anum_pg_language_lanowner
Definition: pg_language.h:59
Definition: c.h:493
#define Anum_pg_language_lanplcallfoid
Definition: pg_language.h:62
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3399
#define RowExclusiveLock
Definition: lockdefs.h:38
#define Anum_pg_language_lanpltrusted
Definition: pg_language.h:61
#define ereport(elevel, rest)
Definition: elog.h:122
#define Anum_pg_language_lanname
Definition: pg_language.h:58
uintptr_t Datum
Definition: postgres.h:372
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1117
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define BoolGetDatum(X)
Definition: postgres.h:408
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
Definition: pg_depend.c:139
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
#define Natts_pg_language
Definition: pg_language.h:57
static Datum values[MAXATTR]
Definition: bootstrap.c:163
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define LanguageRelationId
Definition: pg_language.h:29
#define Anum_pg_language_laninline
Definition: pg_language.h:63
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:791
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:31
#define Anum_pg_language_lanispl
Definition: pg_language.h:60
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:562
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:538
#define LANGUAGE_HANDLEROID
Definition: pg_type.h:696
Oid get_func_rettype(Oid funcid)
Definition: lsyscache.c:1459
char * tmplinline
Definition: proclang.c:49
#define VOIDOID
Definition: pg_type.h:690
#define OPAQUEOID
Definition: pg_type.h:700
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2056
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3399
#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:4964
List * plvalidator
Definition: parsenodes.h:2375
#define PROPARALLEL_UNSAFE
Definition: pg_proc.h:5494
#define PROVOLATILE_VOLATILE
Definition: pg_proc.h:5485
bool tmpldbacreate
Definition: proclang.c:47
#define WARNING
Definition: elog.h:40
char * NameListToString(List *names)
Definition: namespace.c:3020
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:698
#define NOTICE
Definition: elog.h:37
#define NULL
Definition: c.h:229
oidvector * buildoidvector(const Oid *oids, int n)
Definition: oid.c:167
#define BOOTSTRAP_SUPERUSERID
Definition: pg_authid.h:102
Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError)
Definition: parse_func.c:1910
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:156
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#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:1117
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define LanguageRelationId
Definition: pg_language.h:29
#define elog
Definition: elog.h:219
static PLTemplate * find_language_template ( const char *  languageName)
static

Definition at line 451 of file proclang.c.

References AccessShareLock, Anum_pg_pltemplate_tmplhandler, Anum_pg_pltemplate_tmplinline, Anum_pg_pltemplate_tmpllibrary, Anum_pg_pltemplate_tmplname, Anum_pg_pltemplate_tmplvalidator, BTEqualStrategyNumber, CStringGetDatum, GETSTRUCT, heap_close, heap_getattr, heap_open(), HeapTupleIsValid, NULL, palloc0(), PLTemplateNameIndexId, PLTemplateRelationId, RelationGetDescr, result, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), TextDatumGetCString, PLTemplate::tmpldbacreate, PLTemplate::tmplhandler, PLTemplate::tmplinline, PLTemplate::tmpllibrary, PLTemplate::tmpltrusted, and PLTemplate::tmplvalidator.

Referenced by CreateProceduralLanguage(), and PLTemplateExists().

452 {
454  Relation rel;
455  SysScanDesc scan;
456  ScanKeyData key;
457  HeapTuple tup;
458 
460 
461  ScanKeyInit(&key,
463  BTEqualStrategyNumber, F_NAMEEQ,
464  CStringGetDatum(languageName));
465  scan = systable_beginscan(rel, PLTemplateNameIndexId, true,
466  NULL, 1, &key);
467 
468  tup = systable_getnext(scan);
469  if (HeapTupleIsValid(tup))
470  {
472  Datum datum;
473  bool isnull;
474 
475  result = (PLTemplate *) palloc0(sizeof(PLTemplate));
476  result->tmpltrusted = tmpl->tmpltrusted;
477  result->tmpldbacreate = tmpl->tmpldbacreate;
478 
479  /* Remaining fields are variable-width so we need heap_getattr */
481  RelationGetDescr(rel), &isnull);
482  if (!isnull)
483  result->tmplhandler = TextDatumGetCString(datum);
484 
486  RelationGetDescr(rel), &isnull);
487  if (!isnull)
488  result->tmplinline = TextDatumGetCString(datum);
489 
491  RelationGetDescr(rel), &isnull);
492  if (!isnull)
493  result->tmplvalidator = TextDatumGetCString(datum);
494 
496  RelationGetDescr(rel), &isnull);
497  if (!isnull)
498  result->tmpllibrary = TextDatumGetCString(datum);
499 
500  /* Ignore template if handler or library info is missing */
501  if (!result->tmplhandler || !result->tmpllibrary)
502  result = NULL;
503  }
504  else
505  result = NULL;
506 
507  systable_endscan(scan);
508 
510 
511  return result;
512 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
char * tmpllibrary
Definition: proclang.c:51
#define Anum_pg_pltemplate_tmplname
Definition: pg_pltemplate.h:59
#define RelationGetDescr(relation)
Definition: rel.h:429
#define Anum_pg_pltemplate_tmplhandler
Definition: pg_pltemplate.h:62
#define Anum_pg_pltemplate_tmplinline
Definition: pg_pltemplate.h:63
bool tmpltrusted
Definition: proclang.c:46
#define AccessShareLock
Definition: lockdefs.h:36
return result
Definition: formatting.c:1632
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
char * tmplinline
Definition: proclang.c:49
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
FormData_pg_pltemplate * Form_pg_pltemplate
Definition: pg_pltemplate.h:52
#define CStringGetDatum(X)
Definition: postgres.h:584
#define Anum_pg_pltemplate_tmplvalidator
Definition: pg_pltemplate.h:64
bool tmpldbacreate
Definition: proclang.c:47
#define Anum_pg_pltemplate_tmpllibrary
Definition: pg_pltemplate.h:65
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:769
#define TextDatumGetCString(d)
Definition: builtins.h:92
void * palloc0(Size size)
Definition: mcxt.c:878
uintptr_t Datum
Definition: postgres.h:372
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define PLTemplateNameIndexId
Definition: indexing.h:213
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
#define PLTemplateRelationId
Definition: pg_pltemplate.h:29
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
char * tmplhandler
Definition: proclang.c:48
char * tmplvalidator
Definition: proclang.c:50
#define BTEqualStrategyNumber
Definition: stratnum.h:31
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:538
#define GetSysCacheOid1(cacheId, key1)
Definition: syscache.h:183
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:584
#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:229
static PLTemplate * find_language_template(const char *languageName)
Definition: proclang.c:451