proclang.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:4k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * proclang.c
  4.  *   PostgreSQL PROCEDURAL LANGUAGE support code.
  5.  *
  6.  *-------------------------------------------------------------------------
  7.  */
  8. #include <ctype.h>
  9. #include "postgres.h"
  10. #include "access/heapam.h"
  11. #include "catalog/catname.h"
  12. #include "catalog/pg_language.h"
  13. #include "catalog/pg_proc.h"
  14. #include "catalog/pg_shadow.h"
  15. #include "commands/proclang.h"
  16. #include "fmgr.h"
  17. #include "utils/syscache.h"
  18. static void
  19. case_translate_language_name(const char *input, char *output)
  20. {
  21. /*-------------------------------------------------------------------------
  22.   Translate the input language name to lower case, except if it's C,
  23.   translate to upper case.
  24. --------------------------------------------------------------------------*/
  25. int i;
  26. for (i = 0; i < NAMEDATALEN && input[i]; ++i)
  27. output[i] = tolower(input[i]);
  28. output[i] = '';
  29. if (strcmp(output, "c") == 0)
  30. output[0] = 'C';
  31. }
  32. /* ---------------------------------------------------------------------
  33.  * CREATE PROCEDURAL LANGUAGE
  34.  * ---------------------------------------------------------------------
  35.  */
  36. void
  37. CreateProceduralLanguage(CreatePLangStmt *stmt)
  38. {
  39. char languageName[NAMEDATALEN];
  40. HeapTuple langTup;
  41. HeapTuple procTup;
  42. Oid typev[8];
  43. char nulls[Natts_pg_language];
  44. Datum values[Natts_pg_language];
  45. Relation rel;
  46. HeapTuple tup;
  47. TupleDesc tupDesc;
  48. int i;
  49. /* ----------------
  50.  * Check permission
  51.  * ----------------
  52.  */
  53. if (!superuser())
  54. {
  55. elog(ERROR, "Only users with Postgres superuser privilege are "
  56.  "permitted to create procedural languages");
  57. }
  58. /* ----------------
  59.  * Translate the language name and check that
  60.  * this language doesn't already exist
  61.  * ----------------
  62.  */
  63. case_translate_language_name(stmt->plname, languageName);
  64. langTup = SearchSysCacheTuple(LANNAME,
  65.   PointerGetDatum(languageName),
  66.   0, 0, 0);
  67. if (HeapTupleIsValid(langTup))
  68. elog(ERROR, "Language %s already exists", languageName);
  69. /* ----------------
  70.  * Lookup the PL handler function and check that it is
  71.  * of return type Opaque
  72.  * ----------------
  73.  */
  74. memset(typev, 0, sizeof(typev));
  75. procTup = SearchSysCacheTuple(PRONAME,
  76.   PointerGetDatum(stmt->plhandler),
  77.   Int32GetDatum(0),
  78.   PointerGetDatum(typev),
  79.   0);
  80. if (!HeapTupleIsValid(procTup))
  81. {
  82. elog(ERROR, "PL handler function %s() doesn't exist",
  83.  stmt->plhandler);
  84. }
  85. if (((Form_pg_proc) GETSTRUCT(procTup))->prorettype != InvalidOid)
  86. {
  87. elog(ERROR, "PL handler function %s() isn't of return type Opaque",
  88.  stmt->plhandler);
  89. }
  90. /* ----------------
  91.  * Insert the new language into pg_language
  92.  * ----------------
  93.  */
  94. for (i = 0; i < Natts_pg_language; i++)
  95. {
  96. nulls[i] = ' ';
  97. values[i] = (Datum) NULL;
  98. }
  99. i = 0;
  100. values[i++] = PointerGetDatum(languageName);
  101. values[i++] = Int8GetDatum((bool) 1);
  102. values[i++] = Int8GetDatum(stmt->pltrusted);
  103. values[i++] = ObjectIdGetDatum(procTup->t_data->t_oid);
  104. values[i++] = (Datum) fmgr(F_TEXTIN, stmt->plcompiler);
  105. rel = heap_openr(LanguageRelationName);
  106. tupDesc = rel->rd_att;
  107. tup = heap_formtuple(tupDesc, values, nulls);
  108. heap_insert(rel, tup);
  109. heap_close(rel);
  110. return;
  111. }
  112. /* ---------------------------------------------------------------------
  113.  * DROP PROCEDURAL LANGUAGE
  114.  * ---------------------------------------------------------------------
  115.  */
  116. void
  117. DropProceduralLanguage(DropPLangStmt *stmt)
  118. {
  119. char languageName[NAMEDATALEN];
  120. HeapTuple langTup;
  121. Relation rel;
  122. /* ----------------
  123.  * Check permission
  124.  * ----------------
  125.  */
  126. if (!superuser())
  127. {
  128. elog(ERROR, "Only users with Postgres superuser privilege are "
  129.  "permitted to drop procedural languages");
  130. }
  131. /* ----------------
  132.  * Translate the language name, check that
  133.  * this language exist and is a PL
  134.  * ----------------
  135.  */
  136. case_translate_language_name(stmt->plname, languageName);
  137. langTup = SearchSysCacheTupleCopy(LANNAME,
  138.   PointerGetDatum(languageName),
  139.   0, 0, 0);
  140. if (!HeapTupleIsValid(langTup))
  141. elog(ERROR, "Language %s doesn't exist", languageName);
  142. if (!((Form_pg_language) GETSTRUCT(langTup))->lanispl)
  143. {
  144. elog(ERROR, "Language %s isn't a created procedural language",
  145.  languageName);
  146. }
  147. rel = heap_openr(LanguageRelationName);
  148. heap_delete(rel, &langTup->t_self, NULL);
  149. pfree(langTup);
  150. heap_close(rel);
  151. }