Files
postgres/contrib/plpgsql/src/pl_handler.c
T
Bruce Momjian 863a62064c As proposed, here is the current version of PL/pgSQL. The
test isn't that complete up to now,  but  I  think  it  shows
    enough of the capabilities of the module.

    The  Makefile  assumes  it  is  located  in a directory under
    pgsql/src/pl.   Since   it   includes   Makefile.global   and
    Makefile.port  and doesn't use any own compiler/linker calls,
    it should build on most of our supported  platforms  (I  only
    tested  under Linux up to now).  It requires flex and bison I
    think. Maybe we should ship prepared gram.c etc. like for the
    main parser too?


Jan
1998-08-22 12:38:39 +00:00

194 lines
5.2 KiB
C

/**********************************************************************
* pl_handler.c - Handler for the PL/pgSQL
* procedural language
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/contrib/plpgsql/src/Attic/pl_handler.c,v 1.1 1998/08/22 12:38:32 momjian Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
* The author hereby grants permission to use, copy, modify,
* distribute, and license this software and its documentation
* for any purpose, provided that existing copyright notices are
* retained in all copies and that this notice is included
* verbatim in any distributions. No written agreement, license,
* or royalty fee is required for any of the authorized uses.
* Modifications to this software may be copyrighted by their
* author and need not follow the licensing terms described
* here, provided that the new terms are clearly indicated on
* the first page of each file where they apply.
*
* IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTORS BE LIABLE TO ANY
* PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS
* SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN
* IF THE AUTHOR HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE AUTHOR AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON
* AN "AS IS" BASIS, AND THE AUTHOR AND DISTRIBUTORS HAVE NO
* OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
* ENHANCEMENTS, OR MODIFICATIONS.
*
**********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include "plpgsql.h"
#include "pl.tab.h"
#include "executor/spi.h"
#include "commands/trigger.h"
#include "utils/elog.h"
#include "utils/builtins.h"
#include "fmgr.h"
#include "access/heapam.h"
#include "utils/syscache.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
static PLpgSQL_function *compiled_functions = NULL;
Datum plpgsql_call_handler(FmgrInfo *proinfo,
FmgrValues *proargs, bool *isNull);
static Datum plpgsql_func_handler(FmgrInfo *proinfo,
FmgrValues *proargs, bool *isNull);
static HeapTuple plpgsql_trigger_handler(FmgrInfo *proinfo);
/* ----------
* plpgsql_call_handler - This is the only visible function
* of the PL interpreter. The PostgreSQL
* function manager and trigger manager
* call this function for execution of
* PL/pgSQL procedures.
* ----------
*/
Datum
plpgsql_call_handler(FmgrInfo *proinfo,
FmgrValues *proargs,
bool *isNull)
{
Datum retval;
/* ----------
* Connect to SPI manager
* ----------
*/
if (SPI_connect() != SPI_OK_CONNECT) {
elog(ERROR, "plpgsql: cannot connect to SPI manager");
}
/* ----------
* Determine if called as function or trigger and
* call appropriate subhandler
* ----------
*/
if (CurrentTriggerData == NULL) {
retval = plpgsql_func_handler(proinfo, proargs, isNull);
} else {
retval = (Datum)plpgsql_trigger_handler(proinfo);
}
/* ----------
* Disconnect from SPI manager
* ----------
*/
if (SPI_finish() != SPI_OK_FINISH) {
elog(ERROR, "plpgsql: SPI_finish() failed");
}
return retval;
}
/* ----------
* plpgsql_func_handler() - Handler for regular function calls
* ----------
*/
static Datum
plpgsql_func_handler(FmgrInfo *proinfo,
FmgrValues *proargs,
bool *isNull)
{
PLpgSQL_function *func;
/* ----------
* Check if we already compiled this function
* ----------
*/
for (func = compiled_functions; func != NULL; func = func->next) {
if (proinfo->fn_oid == func->fn_oid)
break;
}
/* ----------
* If not, do so and add it to the compiled ones
* ----------
*/
if (func == NULL) {
func = plpgsql_compile(proinfo->fn_oid, T_FUNCTION);
func->next = compiled_functions;
compiled_functions = func;
}
return plpgsql_exec_function(func, proargs, isNull);
}
/* ----------
* plpgsql_trigger_handler() - Handler for trigger calls
* ----------
*/
static HeapTuple
plpgsql_trigger_handler(FmgrInfo *proinfo)
{
TriggerData *trigdata;
PLpgSQL_function *func;
/* ----------
* Save the current trigger data local
* ----------
*/
trigdata = CurrentTriggerData;
CurrentTriggerData = NULL;
/* ----------
* Check if we already compiled this trigger procedure
* ----------
*/
for (func = compiled_functions; func != NULL; func = func->next) {
if (proinfo->fn_oid == func->fn_oid)
break;
}
/* ----------
* If not, do so and add it to the compiled ones
* ----------
*/
if (func == NULL) {
func = plpgsql_compile(proinfo->fn_oid, T_TRIGGER);
func->next = compiled_functions;
compiled_functions = func;
}
return plpgsql_exec_trigger(func, trigdata);
}