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

数据库系统

开发平台:

Unix_Linux

  1. /**********************************************************************
  2.  * pl_handler.c - Handler for the PL/pgSQL
  3.  *   procedural language
  4.  *
  5.  * IDENTIFICATION
  6.  *   $Header: /usr/local/cvsroot/pgsql/src/pl/plpgsql/src/pl_handler.c,v 1.2 1998/09/01 04:40:25 momjian Exp $
  7.  *
  8.  *   This software is copyrighted by Jan Wieck - Hamburg.
  9.  *
  10.  *   The author hereby grants permission  to  use,  copy, modify,
  11.  *   distribute,  and license this software and its documentation
  12.  *   for any purpose, provided that existing copyright notices are
  13.  *   retained in all  copies  and  that this notice is included
  14.  *   verbatim in any distributions. No written agreement, license,
  15.  *   or  royalty  fee is required for any of the authorized uses.
  16.  *   Modifications to this software may be  copyrighted  by  their
  17.  *   author  and  need  not  follow  the licensing terms described
  18.  *   here, provided that the new terms are  clearly  indicated  on
  19.  *   the first page of each file where they apply.
  20.  *
  21.  *   IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTORS BE LIABLE TO ANY
  22.  *   PARTY  FOR  DIRECT, INDIRECT, SPECIAL,   INCIDENTAL,  OR
  23.  *   CONSEQUENTIAL   DAMAGES  ARISING OUT  OF  THE  USE  OF  THIS
  24.  *   SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN
  25.  *   IF  THE  AUTHOR  HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
  26.  *   DAMAGE.
  27.  *
  28.  *   THE  AUTHOR  AND DISTRIBUTORS  SPECIFICALLY  DISCLAIM ANY
  29.  *   WARRANTIES,  INCLUDING,  BUT NOT  LIMITED  TO,  THE IMPLIED
  30.  *   WARRANTIES  OF  MERCHANTABILITY, FITNESS  FOR  A  PARTICULAR
  31.  *   PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON
  32.  *   AN "AS IS" BASIS, AND THE AUTHOR AND  DISTRIBUTORS  HAVE  NO
  33.  *   OBLIGATION   TO PROVIDE   MAINTENANCE,  SUPPORT,  UPDATES,
  34.  *   ENHANCEMENTS, OR MODIFICATIONS.
  35.  *
  36.  **********************************************************************/
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <stdarg.h>
  40. #include <unistd.h>
  41. #include <fcntl.h>
  42. #include <string.h>
  43. #include "plpgsql.h"
  44. #include "pl.tab.h"
  45. #include "executor/spi.h"
  46. #include "commands/trigger.h"
  47. #include "utils/elog.h"
  48. #include "utils/builtins.h"
  49. #include "fmgr.h"
  50. #include "access/heapam.h"
  51. #include "utils/syscache.h"
  52. #include "catalog/pg_proc.h"
  53. #include "catalog/pg_type.h"
  54. static PLpgSQL_function *compiled_functions = NULL;
  55. Datum plpgsql_call_handler(FmgrInfo *proinfo,
  56.  FmgrValues *proargs, bool *isNull);
  57. static Datum plpgsql_func_handler(FmgrInfo *proinfo,
  58.  FmgrValues *proargs, bool *isNull);
  59. static HeapTuple plpgsql_trigger_handler(FmgrInfo *proinfo);
  60. /* ----------
  61.  * plpgsql_call_handler - This is the only visible function
  62.  *   of the PL interpreter. The PostgreSQL
  63.  *   function manager and trigger manager
  64.  *   call this function for execution of
  65.  *   PL/pgSQL procedures.
  66.  * ----------
  67.  */
  68. Datum
  69. plpgsql_call_handler(FmgrInfo *proinfo,
  70.  FmgrValues *proargs,
  71.  bool *isNull)
  72. {
  73. Datum retval;
  74. /* ----------
  75.  * Connect to SPI manager
  76.  * ----------
  77.  */
  78. if (SPI_connect() != SPI_OK_CONNECT)
  79. elog(ERROR, "plpgsql: cannot connect to SPI manager");
  80. /* ----------
  81.  * Determine if called as function or trigger and
  82.  * call appropriate subhandler
  83.  * ----------
  84.  */
  85. if (CurrentTriggerData == NULL)
  86. retval = plpgsql_func_handler(proinfo, proargs, isNull);
  87. else
  88. retval = (Datum) plpgsql_trigger_handler(proinfo);
  89. /* ----------
  90.  * Disconnect from SPI manager
  91.  * ----------
  92.  */
  93. if (SPI_finish() != SPI_OK_FINISH)
  94. elog(ERROR, "plpgsql: SPI_finish() failed");
  95. return retval;
  96. }
  97. /* ----------
  98.  * plpgsql_func_handler() - Handler for regular function calls
  99.  * ----------
  100.  */
  101. static Datum
  102. plpgsql_func_handler(FmgrInfo *proinfo,
  103.  FmgrValues *proargs,
  104.  bool *isNull)
  105. {
  106. PLpgSQL_function *func;
  107. /* ----------
  108.  * Check if we already compiled this function
  109.  * ----------
  110.  */
  111. for (func = compiled_functions; func != NULL; func = func->next)
  112. {
  113. if (proinfo->fn_oid == func->fn_oid)
  114. break;
  115. }
  116. /* ----------
  117.  * If not, do so and add it to the compiled ones
  118.  * ----------
  119.  */
  120. if (func == NULL)
  121. {
  122. func = plpgsql_compile(proinfo->fn_oid, T_FUNCTION);
  123. func->next = compiled_functions;
  124. compiled_functions = func;
  125. }
  126. return plpgsql_exec_function(func, proargs, isNull);
  127. }
  128. /* ----------
  129.  * plpgsql_trigger_handler() - Handler for trigger calls
  130.  * ----------
  131.  */
  132. static HeapTuple
  133. plpgsql_trigger_handler(FmgrInfo *proinfo)
  134. {
  135. TriggerData *trigdata;
  136. PLpgSQL_function *func;
  137. /* ----------
  138.  * Save the current trigger data local
  139.  * ----------
  140.  */
  141. trigdata = CurrentTriggerData;
  142. CurrentTriggerData = NULL;
  143. /* ----------
  144.  * Check if we already compiled this trigger procedure
  145.  * ----------
  146.  */
  147. for (func = compiled_functions; func != NULL; func = func->next)
  148. {
  149. if (proinfo->fn_oid == func->fn_oid)
  150. break;
  151. }
  152. /* ----------
  153.  * If not, do so and add it to the compiled ones
  154.  * ----------
  155.  */
  156. if (func == NULL)
  157. {
  158. func = plpgsql_compile(proinfo->fn_oid, T_TRIGGER);
  159. func->next = compiled_functions;
  160. compiled_functions = func;
  161. }
  162. return plpgsql_exec_trigger(func, trigdata);
  163. }