diff options
Diffstat (limited to 'src/pl')
-rw-r--r-- | src/pl/plperl/plperl.c | 173 | ||||
-rw-r--r-- | src/pl/plperl/ppport.h | 555 | ||||
-rw-r--r-- | src/pl/plperl/spi_internal.c | 49 | ||||
-rw-r--r-- | src/pl/plperl/spi_internal.h | 4 | ||||
-rw-r--r-- | src/pl/plpgsql/src/pl_comp.c | 231 | ||||
-rw-r--r-- | src/pl/plpgsql/src/pl_exec.c | 943 | ||||
-rw-r--r-- | src/pl/plpgsql/src/pl_funcs.c | 8 | ||||
-rw-r--r-- | src/pl/plpgsql/src/plerrcodes.h | 881 | ||||
-rw-r--r-- | src/pl/plpgsql/src/plpgsql.h | 23 | ||||
-rw-r--r-- | src/pl/plpython/plpython.c | 981 | ||||
-rw-r--r-- | src/pl/tcl/pltcl.c | 582 |
11 files changed, 2485 insertions, 1945 deletions
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 2d368a68ef9..4ccb7ec6e34 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -33,7 +33,7 @@ * ENHANCEMENTS, OR MODIFICATIONS. * * IDENTIFICATION - * $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.48 2004/07/31 00:45:44 tgl Exp $ + * $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.49 2004/08/29 05:07:01 momjian Exp $ * **********************************************************************/ @@ -79,7 +79,7 @@ typedef struct plperl_proc_desc CommandId fn_cmin; bool lanpltrusted; bool fn_retistuple; /* true, if function returns tuple */ - bool fn_retisset; /*true, if function returns set*/ + bool fn_retisset; /* true, if function returns set */ Oid ret_oid; /* Oid of returning type */ FmgrInfo result_in_func; Oid result_typioparam; @@ -98,10 +98,10 @@ static int plperl_firstcall = 1; static bool plperl_safe_init_done = false; static PerlInterpreter *plperl_interp = NULL; static HV *plperl_proc_hash = NULL; -static AV *g_row_keys = NULL; -static AV *g_column_keys = NULL; -static SV *srf_perlret=NULL; /*keep returned value*/ -static int g_attr_num = 0; +static AV *g_row_keys = NULL; +static AV *g_column_keys = NULL; +static SV *srf_perlret = NULL; /* keep returned value */ +static int g_attr_num = 0; /********************************************************************** * Forward declarations @@ -214,8 +214,8 @@ plperl_init_interp(void) "", "-e", /* - * no commas between the next lines please. They are supposed to be - * one string + * no commas between the next lines please. They are supposed to + * be one string */ "SPI::bootstrap(); use vars qw(%_SHARED);" "sub ::mkunsafefunc {return eval(qq[ sub { $_[0] $_[1] } ]); }" @@ -240,33 +240,33 @@ plperl_init_interp(void) static void plperl_safe_init(void) { - static char *safe_module = - "require Safe; $Safe::VERSION"; + static char *safe_module = + "require Safe; $Safe::VERSION"; - static char * safe_ok = - "use vars qw($PLContainer); $PLContainer = new Safe('PLPerl');" - "$PLContainer->permit_only(':default');$PLContainer->permit(':base_math');" - "$PLContainer->share(qw[&elog &spi_exec_query &DEBUG &LOG &INFO &NOTICE &WARNING &ERROR %SHARED ]);" - "sub ::mksafefunc { return $PLContainer->reval(qq[sub { $_[0] $_[1]}]); }" - ; + static char *safe_ok = + "use vars qw($PLContainer); $PLContainer = new Safe('PLPerl');" + "$PLContainer->permit_only(':default');$PLContainer->permit(':base_math');" + "$PLContainer->share(qw[&elog &spi_exec_query &DEBUG &LOG &INFO &NOTICE &WARNING &ERROR %SHARED ]);" + "sub ::mksafefunc { return $PLContainer->reval(qq[sub { $_[0] $_[1]}]); }" + ; - static char * safe_bad = - "use vars qw($PLContainer); $PLContainer = new Safe('PLPerl');" - "$PLContainer->permit_only(':default');$PLContainer->permit(':base_math');" - "$PLContainer->share(qw[&elog &DEBUG &LOG &INFO &NOTICE &WARNING &ERROR %SHARED ]);" - "sub ::mksafefunc { return $PLContainer->reval(qq[sub { " - "elog(ERROR,'trusted perl functions disabled - please upgrade perl Safe module to at least 2.09');}]); }" - ; + static char *safe_bad = + "use vars qw($PLContainer); $PLContainer = new Safe('PLPerl');" + "$PLContainer->permit_only(':default');$PLContainer->permit(':base_math');" + "$PLContainer->share(qw[&elog &DEBUG &LOG &INFO &NOTICE &WARNING &ERROR %SHARED ]);" + "sub ::mksafefunc { return $PLContainer->reval(qq[sub { " + "elog(ERROR,'trusted perl functions disabled - please upgrade perl Safe module to at least 2.09');}]); }" + ; - SV * res; + SV *res; - float safe_version; + float safe_version; - res = eval_pv(safe_module,FALSE); /* TRUE = croak if failure */ + res = eval_pv(safe_module, FALSE); /* TRUE = croak if failure */ safe_version = SvNV(res); - eval_pv((safe_version < 2.09 ? safe_bad : safe_ok),FALSE); + eval_pv((safe_version < 2.09 ? safe_bad : safe_ok), FALSE); plperl_safe_init_done = true; } @@ -431,7 +431,7 @@ plperl_is_set(SV * sv) /********************************************************************** * extract a list of keys from a hash **********************************************************************/ -static AV * +static AV * plperl_get_keys(HV * hv) { AV *ret; @@ -523,9 +523,9 @@ plperl_modify_tuple(HV * hvTD, TriggerData *tdata, HeapTuple otup, Oid fn_oid) elog(ERROR, "plperl: $_TD->{new} is not a hash"); plkeys = plperl_get_keys(hvNew); - natts = av_len(plkeys)+1; - if (natts != tupdesc->natts) - elog(ERROR, "plperl: $_TD->{new} has an incorrect number of keys."); + natts = av_len(plkeys) + 1; + if (natts != tupdesc->natts) + elog(ERROR, "plperl: $_TD->{new} has an incorrect number of keys."); modattrs = palloc0(natts * sizeof(int)); modvalues = palloc0(natts * sizeof(Datum)); @@ -558,7 +558,7 @@ plperl_modify_tuple(HV * hvTD, TriggerData *tdata, HeapTuple otup, Oid fn_oid) modvalues[i] = FunctionCall3(&finfo, CStringGetDatum(plval), ObjectIdGetDatum(typelem), - Int32GetDatum(tupdesc->attrs[atti]->atttypmod)); + Int32GetDatum(tupdesc->attrs[atti]->atttypmod)); modnulls[i] = ' '; } else @@ -629,7 +629,7 @@ plperl_create_sub(char *s, bool trusted) SV *subref; int count; - if(trusted && !plperl_safe_init_done) + if (trusted && !plperl_safe_init_done) plperl_safe_init(); ENTER; @@ -770,7 +770,7 @@ plperl_call_perl_func(plperl_proc_desc * desc, FunctionCallInfo fcinfo) tmp = DatumGetCString(FunctionCall3(&(desc->arg_out_func[i]), fcinfo->arg[i], - ObjectIdGetDatum(desc->arg_typioparam[i]), + ObjectIdGetDatum(desc->arg_typioparam[i]), Int32GetDatum(-1))); XPUSHs(sv_2mortal(newSVpv(tmp, 0))); pfree(tmp); @@ -877,21 +877,21 @@ plperl_func_handler(PG_FUNCTION_ARGS) /************************************************************ * Call the Perl function if not returning set ************************************************************/ - if (!prodesc->fn_retisset) - perlret = plperl_call_perl_func(prodesc, fcinfo); - else + if (!prodesc->fn_retisset) + perlret = plperl_call_perl_func(prodesc, fcinfo); + else { - if (SRF_IS_FIRSTCALL()) /*call function only once*/ + if (SRF_IS_FIRSTCALL()) /* call function only once */ srf_perlret = plperl_call_perl_func(prodesc, fcinfo); perlret = srf_perlret; - } + } - if (prodesc->fn_retisset && SRF_IS_FIRSTCALL()) - { + if (prodesc->fn_retisset && SRF_IS_FIRSTCALL()) + { if (prodesc->fn_retistuple) g_column_keys = newAV(); if (SvTYPE(perlret) != SVt_RV) - elog(ERROR, "plperl: set-returning function must return reference"); + elog(ERROR, "plperl: set-returning function must return reference"); } /************************************************************ @@ -903,7 +903,7 @@ plperl_func_handler(PG_FUNCTION_ARGS) if (SPI_finish() != SPI_OK_FINISH) elog(ERROR, "SPI_finish() failed"); - if (!(perlret && SvOK(perlret) && SvTYPE(perlret)!=SVt_NULL )) + if (!(perlret && SvOK(perlret) && SvTYPE(perlret) != SVt_NULL)) { /* return NULL if Perl code returned undef */ retval = (Datum) 0; @@ -916,7 +916,7 @@ plperl_func_handler(PG_FUNCTION_ARGS) if (prodesc->fn_retistuple && perlret && SvTYPE(perlret) != SVt_RV) elog(ERROR, "plperl: composite-returning function must return a reference"); - if (prodesc->fn_retistuple && fcinfo->resultinfo ) /* set of tuples */ + if (prodesc->fn_retistuple && fcinfo->resultinfo) /* set of tuples */ { /* SRF support */ HV *ret_hv; @@ -930,13 +930,13 @@ plperl_func_handler(PG_FUNCTION_ARGS) AttInMetadata *attinmeta; bool isset = 0; char **values = NULL; - ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; + ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; if (prodesc->fn_retisset && !rsinfo) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("returning a composite type is not allowed in this context"), - errhint("This function is intended for use in the FROM clause."))); + errmsg("returning a composite type is not allowed in this context"), + errhint("This function is intended for use in the FROM clause."))); isset = plperl_is_set(perlret); @@ -1020,8 +1020,8 @@ plperl_func_handler(PG_FUNCTION_ARGS) values[i] = NULL; } } - else - { + else + { int i; values = (char **) palloc(g_attr_num * sizeof(char *)); @@ -1045,38 +1045,38 @@ plperl_func_handler(PG_FUNCTION_ARGS) SRF_RETURN_DONE(funcctx); } } - else if (prodesc->fn_retisset) /* set of non-tuples */ + else if (prodesc->fn_retisset) /* set of non-tuples */ { - FuncCallContext *funcctx; - + FuncCallContext *funcctx; + if (SRF_IS_FIRSTCALL()) { MemoryContext oldcontext; - int i; + int i; funcctx = SRF_FIRSTCALL_INIT(); oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); funcctx->max_calls = av_len((AV *) SvRV(perlret)) + 1; } - + funcctx = SRF_PERCALL_SETUP(); - + if (funcctx->call_cntr < funcctx->max_calls) { Datum result; - AV* array; - SV** svp; - int i; + AV *array; + SV **svp; + int i; - array = (AV*)SvRV(perlret); + array = (AV *) SvRV(perlret); svp = av_fetch(array, funcctx->call_cntr, FALSE); if (SvTYPE(*svp) != SVt_NULL) result = FunctionCall3(&prodesc->result_in_func, - PointerGetDatum(SvPV(*svp, PL_na)), - ObjectIdGetDatum(prodesc->result_typioparam), - Int32GetDatum(-1)); + PointerGetDatum(SvPV(*svp, PL_na)), + ObjectIdGetDatum(prodesc->result_typioparam), + Int32GetDatum(-1)); else { fcinfo->isnull = true; @@ -1084,27 +1084,28 @@ plperl_func_handler(PG_FUNCTION_ARGS) } SRF_RETURN_NEXT(funcctx, result); fcinfo->isnull = false; - } + } else { if (perlret) SvREFCNT_dec(perlret); SRF_RETURN_DONE(funcctx); } - } - else if (!fcinfo->isnull) /* non-null singleton */ + } + else if (!fcinfo->isnull) /* non-null singleton */ { - if (prodesc->fn_retistuple) /* singleton perl hash to Datum */ + if (prodesc->fn_retistuple) /* singleton perl hash to Datum */ { - TupleDesc td = lookup_rowtype_tupdesc(prodesc->ret_oid,(int32)-1); - HV * perlhash = (HV *) SvRV(perlret); - int i; - char **values; - char * key, *val; + TupleDesc td = lookup_rowtype_tupdesc(prodesc->ret_oid, (int32) -1); + HV *perlhash = (HV *) SvRV(perlret); + int i; + char **values; + char *key, + *val; AttInMetadata *attinmeta; - HeapTuple tup; + HeapTuple tup; if (!td) ereport(ERROR, @@ -1115,7 +1116,7 @@ plperl_func_handler(PG_FUNCTION_ARGS) for (i = 0; i < td->natts; i++) { - key = SPI_fname(td,i+1); + key = SPI_fname(td, i + 1); val = plperl_get_elem(perlhash, key); if (val) values[i] = val; @@ -1125,14 +1126,15 @@ plperl_func_handler(PG_FUNCTION_ARGS) attinmeta = TupleDescGetAttInMetadata(td); tup = BuildTupleFromCStrings(attinmeta, values); retval = HeapTupleGetDatum(tup); - + } - else /* perl string to Datum */ + else +/* perl string to Datum */ - retval = FunctionCall3(&prodesc->result_in_func, - PointerGetDatum(SvPV(perlret, PL_na)), - ObjectIdGetDatum(prodesc->result_typioparam), - Int32GetDatum(-1)); + retval = FunctionCall3(&prodesc->result_in_func, + PointerGetDatum(SvPV(perlret, PL_na)), + ObjectIdGetDatum(prodesc->result_typioparam), + Int32GetDatum(-1)); } @@ -1159,9 +1161,10 @@ plperl_trigger_handler(PG_FUNCTION_ARGS) /************************************************************ * Call the Perl function ************************************************************/ + /* - * call perl trigger function and build TD hash - */ + * call perl trigger function and build TD hash + */ svTD = plperl_trigger_build_args(fcinfo); perlret = plperl_call_perl_trigger_func(prodesc, fcinfo, svTD); @@ -1386,9 +1389,9 @@ compile_plperl_function(Oid fn_oid, bool is_trigger) if (typeStruct->typtype == 'c' || procStruct->prorettype == RECORDOID) { prodesc->fn_retistuple = true; - prodesc->ret_oid = - procStruct->prorettype == RECORDOID ? - typeStruct->typrelid : + prodesc->ret_oid = + procStruct->prorettype == RECORDOID ? + typeStruct->typrelid : procStruct->prorettype; } @@ -1547,7 +1550,7 @@ plperl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc) ************************************************************/ outputstr = DatumGetCString(OidFunctionCall3(typoutput, attr, - ObjectIdGetDatum(typioparam), + ObjectIdGetDatum(typioparam), Int32GetDatum(tupdesc->attrs[i]->atttypmod))); sv_catpvf(output, "'%s' => '%s',", attname, outputstr); pfree(outputstr); diff --git a/src/pl/plperl/ppport.h b/src/pl/plperl/ppport.h index 0b949b5f77c..5e1d0846ba3 100644 --- a/src/pl/plperl/ppport.h +++ b/src/pl/plperl/ppport.h @@ -1,7 +1,7 @@ -/* ppport.h -- Perl/Pollution/Portability Version 2.011 +/* ppport.h -- Perl/Pollution/Portability Version 2.011 * - * Automatically Created by Devel::PPPort on Sun Jul 4 09:11:52 2004 + * Automatically Created by Devel::PPPort on Sun Jul 4 09:11:52 2004 * * Do NOT edit this file directly! -- Edit PPPort.pm instead. * @@ -9,7 +9,7 @@ * Version 1.x, Copyright (C) 1999, Kenneth Albanowski. * This code may be used and distributed under the same license as any * version of Perl. - * + * * This version of ppport.h is designed to support operation with Perl * installations back to 5.004, and has been tested up to 5.8.1. * @@ -22,20 +22,20 @@ * * Include all following information: * - * 1. The complete output from running "perl -V" + * 1. The complete output from running "perl -V" * - * 2. This file. + * 2. This file. * - * 3. The name & version of the module you were trying to build. + * 3. The name & version of the module you were trying to build. * - * 4. A full log of the build that failed. + * 4. A full log of the build that failed. * - * 5. Any other information that you think could be relevant. + * 5. Any other information that you think could be relevant. * * * For the latest version of this code, please retreive the Devel::PPPort * module from CPAN. - * + * */ /* @@ -53,29 +53,29 @@ * for a static include, or use the GLOBAL request in a single module to * produce a global definition that can be referenced from the other * modules. - * - * Function: Static define: Extern define: - * newCONSTSUB() NEED_newCONSTSUB NEED_newCONSTSUB_GLOBAL + * + * Function: Static define: Extern define: + * newCONSTSUB() NEED_newCONSTSUB NEED_newCONSTSUB_GLOBAL * */ - + /* To verify whether ppport.h is needed for your module, and whether any * special defines should be used, ppport.h can be run through Perl to check * your source code. Simply say: - * - * perl -x ppport.h *.c *.h *.xs foo/bar*.c [etc] - * + * + * perl -x ppport.h *.c *.h *.xs foo/bar*.c [etc] + * * The result will be a list of patches suggesting changes that should at * least be acceptable, if not necessarily the most efficient solution, or a * fix for all possible problems. It won't catch where dTHR is needed, and * doesn't attempt to account for global macro or function definitions, * nested includes, typemaps, etc. - * + * * In order to test for the need of dTHR, please try your module under a * recent version of Perl that has threading compiled-in. * - */ + */ /* @@ -133,11 +133,11 @@ foreach $filename (map(glob($_),@ARGV)) { $need_include = 1; } } - + if (scalar(keys %add_func) or $need_include != $has_include) { if (!$has_include) { $inc = join('',map("#define NEED_$_\n", sort keys %add_func)). - "#include \"ppport.h\"\n"; + "#include \"ppport.h\"\n"; $c = "$inc$c" unless $c =~ s/#.*include.*XSUB.*\n/$&$inc/m; } elsif (keys %add_func) { $inc = join('',map("#define NEED_$_\n", sort keys %add_func)); @@ -149,7 +149,7 @@ foreach $filename (map(glob($_),@ARGV)) { } $changes++; } - + if ($changes) { open(OUT,">/tmp/ppport.h.$$"); print OUT $c; @@ -169,192 +169,194 @@ __DATA__ #define _P_P_PORTABILITY_H_ #ifndef PERL_REVISION -# ifndef __PATCHLEVEL_H_INCLUDED__ -# define PERL_PATCHLEVEL_H_IMPLICIT -# include <patchlevel.h> -# endif -# if !(defined(PERL_VERSION) || (defined(SUBVERSION) && defined(PATCHLEVEL))) -# include <could_not_find_Perl_patchlevel.h> -# endif -# ifndef PERL_REVISION -# define PERL_REVISION (5) - /* Replace: 1 */ -# define PERL_VERSION PATCHLEVEL -# define PERL_SUBVERSION SUBVERSION - /* Replace PERL_PATCHLEVEL with PERL_VERSION */ - /* Replace: 0 */ -# endif +#ifndef __PATCHLEVEL_H_INCLUDED__ +#define PERL_PATCHLEVEL_H_IMPLICIT +#include <patchlevel.h> +#endif +#if !(defined(PERL_VERSION) || (defined(SUBVERSION) && defined(PATCHLEVEL))) +#include <could_not_find_Perl_patchlevel.h> +#endif +#ifndef PERL_REVISION +#define PERL_REVISION (5) + /* Replace: 1 */ +#define PERL_VERSION PATCHLEVEL +#define PERL_SUBVERSION SUBVERSION + /* Replace PERL_PATCHLEVEL with PERL_VERSION */ + /* Replace: 0 */ +#endif #endif #define PERL_BCDVERSION ((PERL_REVISION * 0x1000000L) + (PERL_VERSION * 0x1000L) + PERL_SUBVERSION) -/* It is very unlikely that anyone will try to use this with Perl 6 +/* It is very unlikely that anyone will try to use this with Perl 6 (or greater), but who knows. */ #if PERL_REVISION != 5 -# error ppport.h only works with Perl version 5 -#endif /* PERL_REVISION != 5 */ +#error ppport.h only works with Perl version 5 +#endif /* PERL_REVISION != 5 */ #ifndef ERRSV -# define ERRSV perl_get_sv("@",FALSE) +#define ERRSV perl_get_sv("@",FALSE) #endif #if (PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION <= 5)) /* Replace: 1 */ -# define PL_Sv Sv -# define PL_compiling compiling -# define PL_copline copline -# define PL_curcop curcop -# define PL_curstash curstash -# define PL_defgv defgv -# define PL_dirty dirty -# define PL_dowarn dowarn -# define PL_hints hints -# define PL_na na -# define PL_perldb perldb -# define PL_rsfp_filters rsfp_filters -# define PL_rsfpv rsfp -# define PL_stdingv stdingv -# define PL_sv_no sv_no -# define PL_sv_undef sv_undef -# define PL_sv_yes sv_yes +#define PL_Sv Sv +#define PL_compiling compiling +#define PL_copline copline +#define PL_curcop curcop +#define PL_curstash curstash +#define PL_defgv defgv +#define PL_dirty dirty +#define PL_dowarn dowarn +#define PL_hints hints +#define PL_na na +#define PL_perldb perldb +#define PL_rsfp_filters rsfp_filters +#define PL_rsfpv rsfp +#define PL_stdingv stdingv +#define PL_sv_no sv_no +#define PL_sv_undef sv_undef +#define PL_sv_yes sv_yes /* Replace: 0 */ #endif #ifdef HASATTRIBUTE -# if (defined(__GNUC__) && defined(__cplusplus)) || defined(__INTEL_COMPILER) -# define PERL_UNUSED_DECL -# else -# define PERL_UNUSED_DECL __attribute__((unused)) -# endif +#if (defined(__GNUC__) && defined(__cplusplus)) || defined(__INTEL_COMPILER) +#define PERL_UNUSED_DECL +#else +#define PERL_UNUSED_DECL __attribute__((unused)) +#endif #else -# define PERL_UNUSED_DECL +#define PERL_UNUSED_DECL #endif #ifndef dNOOP -# define NOOP (void)0 -# define dNOOP extern int Perl___notused PERL_UNUSED_DECL +#define NOOP (void)0 +#define dNOOP extern int Perl___notused PERL_UNUSED_DECL #endif #ifndef dTHR -# define dTHR dNOOP +#define dTHR dNOOP #endif #ifndef dTHX -# define dTHX dNOOP -# define dTHXa(x) dNOOP -# define dTHXoa(x) dNOOP +#define dTHX dNOOP +#define dTHXa(x) dNOOP +#define dTHXoa(x) dNOOP #endif #ifndef pTHX -# define pTHX void -# define pTHX_ -# define aTHX -# define aTHX_ -#endif +#define pTHX void +#define pTHX_ +#define aTHX +#define aTHX_ +#endif #ifndef dAX -# define dAX I32 ax = MARK - PL_stack_base + 1 +#define dAX I32 ax = MARK - PL_stack_base + 1 #endif #ifndef dITEMS -# define dITEMS I32 items = SP - MARK +#define dITEMS I32 items = SP - MARK #endif /* IV could also be a quad (say, a long long), but Perls * capable of those should have IVSIZE already. */ #if !defined(IVSIZE) && defined(LONGSIZE) -# define IVSIZE LONGSIZE +#define IVSIZE LONGSIZE #endif #ifndef IVSIZE -# define IVSIZE 4 /* A bold guess, but the best we can make. */ +#define IVSIZE 4 /* A bold guess, but the best we can make. */ #endif #ifndef UVSIZE -# define UVSIZE IVSIZE +#define UVSIZE IVSIZE #endif #ifndef NVTYPE -# if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE) -# define NVTYPE long double -# else -# define NVTYPE double -# endif +#if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE) +#define NVTYPE long double +#else +#define NVTYPE double +#endif typedef NVTYPE NV; #endif #ifndef INT2PTR #if (IVSIZE == PTRSIZE) && (UVSIZE == PTRSIZE) -# define PTRV UV -# define INT2PTR(any,d) (any)(d) +#define PTRV UV +#define INT2PTR(any,d) (any)(d) #else -# if PTRSIZE == LONGSIZE -# define PTRV unsigned long -# else -# define PTRV unsigned -# endif -# define INT2PTR(any,d) (any)(PTRV)(d) -#endif -#define NUM2PTR(any,d) (any)(PTRV)(d) -#define PTR2IV(p) INT2PTR(IV,p) -#define PTR2UV(p) INT2PTR(UV,p) -#define PTR2NV(p) NUM2PTR(NV,p) #if PTRSIZE == LONGSIZE -# define PTR2ul(p) (unsigned long)(p) +#define PTRV unsigned long #else -# define PTR2ul(p) INT2PTR(unsigned long,p) +#define PTRV unsigned #endif - -#endif /* !INT2PTR */ +#define INT2PTR(any,d) (any)(PTRV)(d) +#endif +#define NUM2PTR(any,d) (any)(PTRV)(d) +#define PTR2IV(p) INT2PTR(IV,p) +#define PTR2UV(p) INT2PTR(UV,p) +#define PTR2NV(p) NUM2PTR(NV,p) +#if PTRSIZE == LONGSIZE +#define PTR2ul(p) (unsigned long)(p) +#else +#define PTR2ul(p) INT2PTR(unsigned long,p) +#endif +#endif /* !INT2PTR */ #ifndef boolSV -# define boolSV(b) ((b) ? &PL_sv_yes : &PL_sv_no) +#define boolSV(b) ((b) ? &PL_sv_yes : &PL_sv_no) #endif #ifndef gv_stashpvn -# define gv_stashpvn(str,len,flags) gv_stashpv(str,flags) +#define gv_stashpvn(str,len,flags) gv_stashpv(str,flags) #endif #ifndef newSVpvn -# define newSVpvn(data,len) ((len) ? newSVpv ((data), (len)) : newSVpv ("", 0)) +#define newSVpvn(data,len) ((len) ? newSVpv ((data), (len)) : newSVpv ("", 0)) #endif #ifndef newRV_inc /* Replace: 1 */ -# define newRV_inc(sv) newRV(sv) +#define newRV_inc(sv) newRV(sv) /* Replace: 0 */ #endif /* DEFSV appears first in 5.004_56 */ #ifndef DEFSV -# define DEFSV GvSV(PL_defgv) +#define DEFSV GvSV(PL_defgv) #endif #ifndef SAVE_DEFSV -# define SAVE_DEFSV SAVESPTR(GvSV(PL_defgv)) +#define SAVE_DEFSV SAVESPTR(GvSV(PL_defgv)) #endif #ifndef newRV_noinc -# ifdef __GNUC__ -# define newRV_noinc(sv) \ - ({ \ - SV *nsv = (SV*)newRV(sv); \ - SvREFCNT_dec(sv); \ - nsv; \ - }) -# else -# if defined(USE_THREADS) -static SV * newRV_noinc (SV * sv) +#ifdef __GNUC__ +#define newRV_noinc(sv) \ + ({ \ + SV *nsv = (SV*)newRV(sv); \ + SvREFCNT_dec(sv); \ + nsv; \ + }) +#else +#if defined(USE_THREADS) +static SV * +newRV_noinc(SV * sv) { - SV *nsv = (SV*)newRV(sv); - SvREFCNT_dec(sv); - return nsv; + SV *nsv = (SV *) newRV(sv); + + SvREFCNT_dec(sv); + return nsv; } -# else -# define newRV_noinc(sv) \ - (PL_Sv=(SV*)newRV(sv), SvREFCNT_dec(sv), (SV*)PL_Sv) -# endif -# endif + +#else +#define newRV_noinc(sv) \ + (PL_Sv=(SV*)newRV(sv), SvREFCNT_dec(sv), (SV*)PL_Sv) +#endif +#endif #endif /* Provide: newCONSTSUB */ @@ -365,20 +367,21 @@ static SV * newRV_noinc (SV * sv) #if defined(NEED_newCONSTSUB) static #else -extern void newCONSTSUB(HV * stash, char * name, SV *sv); +extern void newCONSTSUB(HV * stash, char *name, SV * sv); #endif #if defined(NEED_newCONSTSUB) || defined(NEED_newCONSTSUB_GLOBAL) void -newCONSTSUB(stash,name,sv) -HV *stash; -char *name; -SV *sv; +newCONSTSUB(stash, name, sv) +HV *stash; +char *name; +SV *sv; { - U32 oldhints = PL_hints; - HV *old_cop_stash = PL_curcop->cop_stash; - HV *old_curstash = PL_curstash; - line_t oldline = PL_curcop->cop_line; + U32 oldhints = PL_hints; + HV *old_cop_stash = PL_curcop->cop_stash; + HV *old_curstash = PL_curstash; + line_t oldline = PL_curcop->cop_line; + PL_curcop->cop_line = PL_copline; PL_hints &= ~HINT_BLOCK_SCOPE; @@ -388,22 +391,23 @@ SV *sv; newSUB( #if (PERL_VERSION < 3) || ((PERL_VERSION == 3) && (PERL_SUBVERSION < 22)) - /* before 5.003_22 */ - start_subparse(), + /* before 5.003_22 */ + start_subparse(), #else -# if (PERL_VERSION == 3) && (PERL_SUBVERSION == 22) - /* 5.003_22 */ - start_subparse(0), -# else - /* 5.003_23 onwards */ - start_subparse(FALSE, 0), -# endif +#if (PERL_VERSION == 3) && (PERL_SUBVERSION == 22) + /* 5.003_22 */ + start_subparse(0), +#else + /* 5.003_23 onwards */ + start_subparse(FALSE, 0), +#endif #endif - newSVOP(OP_CONST, 0, newSVpv(name,0)), - newSVOP(OP_CONST, 0, &PL_sv_no), /* SvPV(&PL_sv_no) == "" -- GMB */ - newSTATEOP(0, Nullch, newSVOP(OP_CONST, 0, sv)) - ); + newSVOP(OP_CONST, 0, newSVpv(name, 0)), + newSVOP(OP_CONST, 0, &PL_sv_no), /* SvPV(&PL_sv_no) == "" + * -- GMB */ + newSTATEOP(0, Nullch, newSVOP(OP_CONST, 0, sv)) + ); PL_hints = oldhints; PL_curcop->cop_stash = old_cop_stash; @@ -411,8 +415,7 @@ SV *sv; PL_curcop->cop_line = oldline; } #endif - -#endif /* newCONSTSUB */ +#endif /* newCONSTSUB */ #ifndef START_MY_CXT @@ -425,18 +428,18 @@ SV *sv; * Code that uses these macros is responsible for the following: * 1. #define MY_CXT_KEY to a unique string, e.g. "DynaLoader_guts" * 2. Declare a typedef named my_cxt_t that is a structure that contains - * all the data that needs to be interpreter-local. + * all the data that needs to be interpreter-local. * 3. Use the START_MY_CXT macro after the declaration of my_cxt_t. * 4. Use the MY_CXT_INIT macro such that it is called exactly once - * (typically put in the BOOT: section). + * (typically put in the BOOT: section). * 5. Use the members of the my_cxt_t structure everywhere as - * MY_CXT.member. + * MY_CXT.member. * 6. Use the dMY_CXT macro (a declaration) in all the functions that - * access MY_CXT. + * access MY_CXT. */ #if defined(MULTIPLICITY) || defined(PERL_OBJECT) || \ - defined(PERL_CAPI) || defined(PERL_IMPLICIT_CONTEXT) + defined(PERL_CAPI) || defined(PERL_IMPLICIT_CONTEXT) /* This must appear in all extensions that define a my_cxt_t structure, * right after the definition (i.e. at file scope). The non-threads @@ -447,15 +450,15 @@ SV *sv; /* Fetches the SV that keeps the per-interpreter data. */ #define dMY_CXT_SV \ SV *my_cxt_sv = perl_get_sv(MY_CXT_KEY, FALSE) -#else /* >= perl5.004_68 */ +#else /* >= perl5.004_68 */ #define dMY_CXT_SV \ SV *my_cxt_sv = *hv_fetch(PL_modglobal, MY_CXT_KEY, \ sizeof(MY_CXT_KEY)-1, TRUE) -#endif /* < perl5.004_68 */ +#endif /* < perl5.004_68 */ /* This declaration should be used within all functions that use the * interpreter-local data. */ -#define dMY_CXT \ +#define dMY_CXT \ dMY_CXT_SV; \ my_cxt_t *my_cxtp = INT2PTR(my_cxt_t*,SvUV(my_cxt_sv)) @@ -482,12 +485,12 @@ SV *sv; #define aMY_CXT_ aMY_CXT, #define _aMY_CXT ,aMY_CXT -#else /* single interpreter */ +#else /* single interpreter */ #define START_MY_CXT static my_cxt_t my_cxt; #define dMY_CXT_SV dNOOP #define dMY_CXT dNOOP -#define MY_CXT_INIT NOOP +#define MY_CXT_INIT NOOP #define MY_CXT my_cxt #define pMY_CXT void @@ -496,130 +499,129 @@ SV *sv; #define aMY_CXT #define aMY_CXT_ #define _aMY_CXT - -#endif - -#endif /* START_MY_CXT */ +#endif +#endif /* START_MY_CXT */ #ifndef IVdf -# if IVSIZE == LONGSIZE -# define IVdf "ld" -# define UVuf "lu" -# define UVof "lo" -# define UVxf "lx" -# define UVXf "lX" -# else -# if IVSIZE == INTSIZE -# define IVdf "d" -# define UVuf "u" -# define UVof "o" -# define UVxf "x" -# define UVXf "X" -# endif -# endif +#if IVSIZE == LONGSIZE +#define IVdf "ld" +#define UVuf "lu" +#define UVof "lo" +#define UVxf "lx" +#define UVXf "lX" +#else +#if IVSIZE == INTSIZE +#define IVdf "d" +#define UVuf "u" +#define UVof "o" +#define UVxf "x" +#define UVXf "X" +#endif +#endif #endif #ifndef NVef -# if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE) && \ - defined(PERL_PRIfldbl) /* Not very likely, but let's try anyway. */ -# define NVef PERL_PRIeldbl -# define NVff PERL_PRIfldbl -# define NVgf PERL_PRIgldbl -# else -# define NVef "e" -# define NVff "f" -# define NVgf "g" -# endif +#if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE) && \ + defined(PERL_PRIfldbl) /* Not very likely, but let's try anyway. */ +#define NVef PERL_PRIeldbl +#define NVff PERL_PRIfldbl +#define NVgf PERL_PRIgldbl +#else +#define NVef "e" +#define NVff "f" +#define NVgf "g" +#endif #endif -#ifndef AvFILLp /* Older perls (<=5.003) lack AvFILLp */ -# define AvFILLp AvFILL +#ifndef AvFILLp /* Older perls (<=5.003) lack AvFILLp */ +#define AvFILLp AvFILL #endif #ifdef SvPVbyte -# if PERL_REVISION == 5 && PERL_VERSION < 7 - /* SvPVbyte does not work in perl-5.6.1, borrowed version for 5.7.3 */ -# undef SvPVbyte -# define SvPVbyte(sv, lp) \ - ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK) \ - ? ((lp = SvCUR(sv)), SvPVX(sv)) : my_sv_2pvbyte(aTHX_ sv, &lp)) - static char * - my_sv_2pvbyte(pTHX_ register SV *sv, STRLEN *lp) - { - sv_utf8_downgrade(sv,0); - return SvPV(sv,*lp); - } -# endif +#if PERL_REVISION == 5 && PERL_VERSION < 7 + /* SvPVbyte does not work in perl-5.6.1, borrowed version for 5.7.3 */ +#undef SvPVbyte +#define SvPVbyte(sv, lp) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK) \ + ? ((lp = SvCUR(sv)), SvPVX(sv)) : my_sv_2pvbyte(aTHX_ sv, &lp)) +static char * +my_sv_2pvbyte(pTHX_ register SV * sv, STRLEN * lp) +{ + sv_utf8_downgrade(sv, 0); + return SvPV(sv, *lp); +} +#endif #else -# define SvPVbyte SvPV +#define SvPVbyte SvPV #endif #ifndef SvPV_nolen -# define SvPV_nolen(sv) \ - ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ - ? SvPVX(sv) : sv_2pv_nolen(sv)) - static char * - sv_2pv_nolen(pTHX_ register SV *sv) - { - STRLEN n_a; - return sv_2pv(sv, &n_a); - } +#define SvPV_nolen(sv) \ + ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + ? SvPVX(sv) : sv_2pv_nolen(sv)) +static char * +sv_2pv_nolen(pTHX_ register SV * sv) +{ + STRLEN n_a; + + return sv_2pv(sv, &n_a); +} #endif #ifndef get_cv -# define get_cv(name,create) perl_get_cv(name,create) +#define get_cv(name,create) perl_get_cv(name,create) #endif #ifndef get_sv -# define get_sv(name,create) perl_get_sv(name,create) +#define get_sv(name,create) perl_get_sv(name,create) #endif #ifndef get_av -# define get_av(name,create) perl_get_av(name,create) +#define get_av(name,create) perl_get_av(name,create) #endif #ifndef get_hv -# define get_hv(name,create) perl_get_hv(name,create) +#define get_hv(name,create) perl_get_hv(name,create) #endif #ifndef call_argv -# define call_argv perl_call_argv +#define call_argv perl_call_argv #endif #ifndef call_method -# define call_method perl_call_method +#define call_method perl_call_method #endif #ifndef call_pv -# define call_pv perl_call_pv +#define call_pv perl_call_pv #endif #ifndef call_sv -# define call_sv perl_call_sv +#define call_sv perl_call_sv #endif #ifndef eval_pv -# define eval_pv perl_eval_pv +#define eval_pv perl_eval_pv #endif #ifndef eval_sv -# define eval_sv perl_eval_sv +#define eval_sv perl_eval_sv #endif #ifndef PERL_SCAN_GREATER_THAN_UV_MAX -# define PERL_SCAN_GREATER_THAN_UV_MAX 0x02 +#define PERL_SCAN_GREATER_THAN_UV_MAX 0x02 #endif #ifndef PERL_SCAN_SILENT_ILLDIGIT -# define PERL_SCAN_SILENT_ILLDIGIT 0x04 +#define PERL_SCAN_SILENT_ILLDIGIT 0x04 #endif #ifndef PERL_SCAN_ALLOW_UNDERSCORES -# define PERL_SCAN_ALLOW_UNDERSCORES 0x01 +#define PERL_SCAN_ALLOW_UNDERSCORES 0x01 #endif #ifndef PERL_SCAN_DISALLOW_PREFIX -# define PERL_SCAN_DISALLOW_PREFIX 0x02 +#define PERL_SCAN_DISALLOW_PREFIX 0x02 #endif #if (PERL_VERSION > 6) || ((PERL_VERSION == 6) && (PERL_SUBVERSION >= 1)) @@ -630,184 +632,183 @@ SV *sv; #ifndef IN_LOCALE -# define IN_LOCALE \ +#define IN_LOCALE \ (PL_curcop == &PL_compiling ? IN_LOCALE_COMPILETIME : IN_LOCALE_RUNTIME) #endif #ifndef IN_LOCALE_RUNTIME -# define IN_LOCALE_RUNTIME (PL_curcop->op_private & HINT_LOCALE) +#define IN_LOCALE_RUNTIME (PL_curcop->op_private & HINT_LOCALE) #endif #ifndef IN_LOCALE_COMPILETIME -# define IN_LOCALE_COMPILETIME (PL_hints & HINT_LOCALE) +#define IN_LOCALE_COMPILETIME (PL_hints & HINT_LOCALE) #endif #ifndef IS_NUMBER_IN_UV -# define IS_NUMBER_IN_UV 0x01 -# define IS_NUMBER_GREATER_THAN_UV_MAX 0x02 -# define IS_NUMBER_NOT_INT 0x04 -# define IS_NUMBER_NEG 0x08 -# define IS_NUMBER_INFINITY 0x10 -# define IS_NUMBER_NAN 0x20 +#define IS_NUMBER_IN_UV 0x01 +#define IS_NUMBER_GREATER_THAN_UV_MAX 0x02 +#define IS_NUMBER_NOT_INT 0x04 +#define IS_NUMBER_NEG 0x08 +#define IS_NUMBER_INFINITY 0x10 +#define IS_NUMBER_NAN 0x20 #endif #ifndef PERL_MAGIC_sv -# define PERL_MAGIC_sv '\0' +#define PERL_MAGIC_sv '\0' #endif #ifndef PERL_MAGIC_overload -# define PERL_MAGIC_overload 'A' +#define PERL_MAGIC_overload 'A' #endif #ifndef PERL_MAGIC_overload_elem -# define PERL_MAGIC_overload_elem 'a' +#define PERL_MAGIC_overload_elem 'a' #endif #ifndef PERL_MAGIC_overload_table -# define PERL_MAGIC_overload_table 'c' +#define PERL_MAGIC_overload_table 'c' #endif #ifndef PERL_MAGIC_bm -# define PERL_MAGIC_bm 'B' +#define PERL_MAGIC_bm 'B' #endif #ifndef PERL_MAGIC_regdata -# define PERL_MAGIC_regdata 'D' +#define PERL_MAGIC_regdata 'D' #endif #ifndef PERL_MAGIC_regdatum -# define PERL_MAGIC_regdatum 'd' +#define PERL_MAGIC_regdatum 'd' #endif #ifndef PERL_MAGIC_env -# define PERL_MAGIC_env 'E' +#define PERL_MAGIC_env 'E' #endif #ifndef PERL_MAGIC_envelem -# define PERL_MAGIC_envelem 'e' +#define PERL_MAGIC_envelem 'e' #endif #ifndef PERL_MAGIC_fm -# define PERL_MAGIC_fm 'f' +#define PERL_MAGIC_fm 'f' #endif #ifndef PERL_MAGIC_regex_global -# define PERL_MAGIC_regex_global 'g' +#define PERL_MAGIC_regex_global 'g' #endif #ifndef PERL_MAGIC_isa -# define PERL_MAGIC_isa 'I' +#define PERL_MAGIC_isa 'I' #endif #ifndef PERL_MAGIC_isaelem -# define PERL_MAGIC_isaelem 'i' +#define PERL_MAGIC_isaelem 'i' #endif #ifndef PERL_MAGIC_nkeys -# define PERL_MAGIC_nkeys 'k' +#define PERL_MAGIC_nkeys 'k' #endif #ifndef PERL_MAGIC_dbfile -# define PERL_MAGIC_dbfile 'L' +#define PERL_MAGIC_dbfile 'L' #endif #ifndef PERL_MAGIC_dbline -# define PERL_MAGIC_dbline 'l' +#define PERL_MAGIC_dbline 'l' #endif #ifndef PERL_MAGIC_mutex -# define PERL_MAGIC_mutex 'm' +#define PERL_MAGIC_mutex 'm' #endif #ifndef PERL_MAGIC_shared -# define PERL_MAGIC_shared 'N' +#define PERL_MAGIC_shared 'N' #endif #ifndef PERL_MAGIC_shared_scalar -# define PERL_MAGIC_shared_scalar 'n' +#define PERL_MAGIC_shared_scalar 'n' #endif #ifndef PERL_MAGIC_collxfrm -# define PERL_MAGIC_collxfrm 'o' +#define PERL_MAGIC_collxfrm 'o' #endif #ifndef PERL_MAGIC_tied -# define PERL_MAGIC_tied 'P' +#define PERL_MAGIC_tied 'P' #endif #ifndef PERL_MAGIC_tiedelem -# define PERL_MAGIC_tiedelem 'p' +#define PERL_MAGIC_tiedelem 'p' #endif #ifndef PERL_MAGIC_tiedscalar -# define PERL_MAGIC_tiedscalar 'q' +#define PERL_MAGIC_tiedscalar 'q' #endif #ifndef PERL_MAGIC_qr -# define PERL_MAGIC_qr 'r' +#define PERL_MAGIC_qr 'r' #endif #ifndef PERL_MAGIC_sig -# define PERL_MAGIC_sig 'S' +#define PERL_MAGIC_sig 'S' #endif #ifndef PERL_MAGIC_sigelem -# define PERL_MAGIC_sigelem 's' +#define PERL_MAGIC_sigelem 's' #endif #ifndef PERL_MAGIC_taint -# define PERL_MAGIC_taint 't' +#define PERL_MAGIC_taint 't' #endif #ifndef PERL_MAGIC_uvar -# define PERL_MAGIC_uvar 'U' +#define PERL_MAGIC_uvar 'U' #endif #ifndef PERL_MAGIC_uvar_elem -# define PERL_MAGIC_uvar_elem 'u' +#define PERL_MAGIC_uvar_elem 'u' #endif #ifndef PERL_MAGIC_vstring -# define PERL_MAGIC_vstring 'V' +#define PERL_MAGIC_vstring 'V' #endif #ifndef PERL_MAGIC_vec -# define PERL_MAGIC_vec 'v' +#define PERL_MAGIC_vec 'v' #endif #ifndef PERL_MAGIC_utf8 -# define PERL_MAGIC_utf8 'w' +#define PERL_MAGIC_utf8 'w' #endif #ifndef PERL_MAGIC_substr -# define PERL_MAGIC_substr 'x' +#define PERL_MAGIC_substr 'x' #endif #ifndef PERL_MAGIC_defelem -# define PERL_MAGIC_defelem 'y' +#define PERL_MAGIC_defelem 'y' #endif #ifndef PERL_MAGIC_glob -# define PERL_MAGIC_glob '*' +#define PERL_MAGIC_glob '*' #endif #ifndef PERL_MAGIC_arylen -# define PERL_MAGIC_arylen '#' +#define PERL_MAGIC_arylen '#' #endif #ifndef PERL_MAGIC_pos -# define PERL_MAGIC_pos '.' +#define PERL_MAGIC_pos '.' #endif #ifndef PERL_MAGIC_backref -# define PERL_MAGIC_backref '<' +#define PERL_MAGIC_backref '<' #endif #ifndef PERL_MAGIC_ext -# define PERL_MAGIC_ext '~' +#define PERL_MAGIC_ext '~' #endif - -#endif /* _P_P_PORTABILITY_H_ */ +#endif /* _P_P_PORTABILITY_H_ */ /* End of File ppport.h */ diff --git a/src/pl/plperl/spi_internal.c b/src/pl/plperl/spi_internal.c index 8d17af5b542..5c3bb38a534 100644 --- a/src/pl/plperl/spi_internal.c +++ b/src/pl/plperl/spi_internal.c @@ -9,7 +9,7 @@ #include "spi_internal.h" -static HV* plperl_spi_execute_fetch_result(SPITupleTable*, int, int ); +static HV *plperl_spi_execute_fetch_result(SPITupleTable *, int, int); int @@ -48,30 +48,31 @@ spi_ERROR(void) return ERROR; } -HV* -plperl_spi_exec(char* query, int limit) +HV * +plperl_spi_exec(char *query, int limit) { - HV *ret_hv; - int spi_rv; + HV *ret_hv; + int spi_rv; spi_rv = SPI_exec(query, limit); - ret_hv=plperl_spi_execute_fetch_result(SPI_tuptable, SPI_processed, spi_rv); + ret_hv = plperl_spi_execute_fetch_result(SPI_tuptable, SPI_processed, spi_rv); return ret_hv; } -static HV* +static HV * plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc) { - int i; - char *attname; - char *attdata; + int i; + char *attname; + char *attdata; - HV *array; + HV *array; array = newHV(); - for (i = 0; i < tupdesc->natts; i++) { + for (i = 0; i < tupdesc->natts; i++) + { /************************************************************ * Get the attribute name ************************************************************/ @@ -80,24 +81,24 @@ plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc) /************************************************************ * Get the attributes value ************************************************************/ - attdata = SPI_getvalue(tuple, tupdesc, i+1); - if(attdata) - hv_store(array, attname, strlen(attname), newSVpv(attdata,0), 0); + attdata = SPI_getvalue(tuple, tupdesc, i + 1); + if (attdata) + hv_store(array, attname, strlen(attname), newSVpv(attdata, 0), 0); else - hv_store(array, attname, strlen(attname), newSVpv("undef",0), 0); + hv_store(array, attname, strlen(attname), newSVpv("undef", 0), 0); } return array; } -static HV* +static HV * plperl_spi_execute_fetch_result(SPITupleTable *tuptable, int processed, int status) { - HV *result; + HV *result; result = newHV(); hv_store(result, "status", strlen("status"), - newSVpv((char*)SPI_result_code_string(status),0), 0); + newSVpv((char *) SPI_result_code_string(status), 0), 0); hv_store(result, "processed", strlen("processed"), newSViv(processed), 0); @@ -105,18 +106,18 @@ plperl_spi_execute_fetch_result(SPITupleTable *tuptable, int processed, int stat { if (processed) { - AV *rows; - HV *row; - int i; + AV *rows; + HV *row; + int i; rows = newAV(); for (i = 0; i < processed; i++) { row = plperl_hash_from_tuple(tuptable->vals[i], tuptable->tupdesc); - av_store(rows, i, newRV_noinc((SV*)row)); + av_store(rows, i, newRV_noinc((SV *) row)); } hv_store(result, "rows", strlen("rows"), - newRV_noinc((SV*)rows), 0); + newRV_noinc((SV *) rows), 0); } } diff --git a/src/pl/plperl/spi_internal.h b/src/pl/plperl/spi_internal.h index 5b5143d6588..1f1984a1570 100644 --- a/src/pl/plperl/spi_internal.h +++ b/src/pl/plperl/spi_internal.h @@ -15,6 +15,4 @@ int spi_WARNING(void); int spi_ERROR(void); -HV* plperl_spi_exec(char*, int); - - +HV *plperl_spi_exec(char *, int); diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c index 2c9ae832860..61c4474908c 100644 --- a/src/pl/plpgsql/src/pl_comp.c +++ b/src/pl/plpgsql/src/pl_comp.c @@ -3,7 +3,7 @@ * procedural language * * IDENTIFICATION - * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.79 2004/08/20 22:00:14 tgl Exp $ + * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.80 2004/08/29 05:07:01 momjian Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -98,14 +98,15 @@ typedef struct plpgsql_hashent * Lookup table for EXCEPTION condition names * ---------- */ -typedef struct { +typedef struct +{ const char *label; int sqlerrstate; -} ExceptionLabelMap; +} ExceptionLabelMap; static const ExceptionLabelMap exception_label_map[] = { #include "plerrcodes.h" - { NULL, 0 } + {NULL, 0} }; @@ -115,7 +116,7 @@ static const ExceptionLabelMap exception_label_map[] = { */ static PLpgSQL_function *do_compile(FunctionCallInfo fcinfo, HeapTuple procTup, - PLpgSQL_func_hashkey *hashkey, + PLpgSQL_func_hashkey * hashkey, bool forValidator); static void plpgsql_compile_error_callback(void *arg); static char **fetchArgNames(HeapTuple procTup, int nargs); @@ -123,12 +124,12 @@ static PLpgSQL_row *build_row_var(Oid classOid); static PLpgSQL_type *build_datatype(HeapTuple typeTup, int32 typmod); static void compute_function_hashkey(FunctionCallInfo fcinfo, Form_pg_proc procStruct, - PLpgSQL_func_hashkey *hashkey, + PLpgSQL_func_hashkey * hashkey, bool forValidator); -static PLpgSQL_function *plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key); -static void plpgsql_HashTableInsert(PLpgSQL_function *function, - PLpgSQL_func_hashkey *func_key); -static void plpgsql_HashTableDelete(PLpgSQL_function *function); +static PLpgSQL_function *plpgsql_HashTableLookup(PLpgSQL_func_hashkey * func_key); +static void plpgsql_HashTableInsert(PLpgSQL_function * function, + PLpgSQL_func_hashkey * func_key); +static void plpgsql_HashTableDelete(PLpgSQL_function * function); /* * This routine is a crock, and so is everyplace that calls it. The problem @@ -253,7 +254,7 @@ plpgsql_compile(FunctionCallInfo fcinfo, bool forValidator) static PLpgSQL_function * do_compile(FunctionCallInfo fcinfo, HeapTuple procTup, - PLpgSQL_func_hashkey *hashkey, + PLpgSQL_func_hashkey * hashkey, bool forValidator) { Form_pg_proc procStruct = (Form_pg_proc) GETSTRUCT(procTup); @@ -407,7 +408,7 @@ do_compile(FunctionCallInfo fcinfo, procStruct->prorettype == ANYELEMENTOID) { (void) plpgsql_build_variable(strdup("$0"), 0, - build_datatype(typeTup, -1), + build_datatype(typeTup, -1), true); } } @@ -444,8 +445,8 @@ do_compile(FunctionCallInfo fcinfo, argdtype->ttype != PLPGSQL_TTYPE_ROW) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("plpgsql functions cannot take type %s", - format_type_be(argtypeid)))); + errmsg("plpgsql functions cannot take type %s", + format_type_be(argtypeid)))); /* Build variable and add to datum list */ argvariable = plpgsql_build_variable(strdup(buf), 0, @@ -518,7 +519,7 @@ do_compile(FunctionCallInfo fcinfo, * Add the variable tg_name */ var = plpgsql_build_variable(strdup("tg_name"), 0, - plpgsql_build_datatype(NAMEOID, -1), + plpgsql_build_datatype(NAMEOID, -1), true); function->tg_name_varno = var->dno; @@ -526,7 +527,7 @@ do_compile(FunctionCallInfo fcinfo, * Add the variable tg_when */ var = plpgsql_build_variable(strdup("tg_when"), 0, - plpgsql_build_datatype(TEXTOID, -1), + plpgsql_build_datatype(TEXTOID, -1), true); function->tg_when_varno = var->dno; @@ -534,7 +535,7 @@ do_compile(FunctionCallInfo fcinfo, * Add the variable tg_level */ var = plpgsql_build_variable(strdup("tg_level"), 0, - plpgsql_build_datatype(TEXTOID, -1), + plpgsql_build_datatype(TEXTOID, -1), true); function->tg_level_varno = var->dno; @@ -542,7 +543,7 @@ do_compile(FunctionCallInfo fcinfo, * Add the variable tg_op */ var = plpgsql_build_variable(strdup("tg_op"), 0, - plpgsql_build_datatype(TEXTOID, -1), + plpgsql_build_datatype(TEXTOID, -1), true); function->tg_op_varno = var->dno; @@ -550,7 +551,7 @@ do_compile(FunctionCallInfo fcinfo, * Add the variable tg_relid */ var = plpgsql_build_variable(strdup("tg_relid"), 0, - plpgsql_build_datatype(OIDOID, -1), + plpgsql_build_datatype(OIDOID, -1), true); function->tg_relid_varno = var->dno; @@ -558,7 +559,7 @@ do_compile(FunctionCallInfo fcinfo, * Add the variable tg_relname */ var = plpgsql_build_variable(strdup("tg_relname"), 0, - plpgsql_build_datatype(NAMEOID, -1), + plpgsql_build_datatype(NAMEOID, -1), true); function->tg_relname_varno = var->dno; @@ -566,7 +567,7 @@ do_compile(FunctionCallInfo fcinfo, * Add the variable tg_nargs */ var = plpgsql_build_variable(strdup("tg_nargs"), 0, - plpgsql_build_datatype(INT4OID, -1), + plpgsql_build_datatype(INT4OID, -1), true); function->tg_nargs_varno = var->dno; @@ -648,9 +649,10 @@ plpgsql_compile_error_callback(void *arg) */ if (function_parse_error_transpose((const char *) arg)) return; + /* - * Done if a syntax error position was reported; otherwise we - * have to fall back to a "near line N" report. + * Done if a syntax error position was reported; otherwise we have + * to fall back to a "near line N" report. */ } @@ -691,7 +693,7 @@ fetchArgNames(HeapTuple procTup, int nargs) result = (char **) palloc(sizeof(char *) * nargs); - for (i=0; i < nargs; i++) + for (i = 0; i < nargs; i++) result[i] = DatumGetCString(DirectFunctionCall1(textout, elems[i])); return result; @@ -1049,7 +1051,7 @@ plpgsql_parse_wordtype(char *word) plpgsql_yylval.dtype = ((PLpgSQL_var *) (plpgsql_Datums[nse->itemno]))->datatype; return T_DTYPE; - /* XXX perhaps allow REC here? */ + /* XXX perhaps allow REC here? */ default: return T_ERROR; @@ -1435,88 +1437,91 @@ plpgsql_parse_dblwordrowtype(char *word) * to the current datum array, and optionally to the current namespace. */ PLpgSQL_variable * -plpgsql_build_variable(char *refname, int lineno, PLpgSQL_type *dtype, - bool add2namespace) +plpgsql_build_variable(char *refname, int lineno, PLpgSQL_type * dtype, + bool add2namespace) { PLpgSQL_variable *result; switch (dtype->ttype) { case PLPGSQL_TTYPE_SCALAR: - { - /* Ordinary scalar datatype */ - PLpgSQL_var *var; - - var = malloc(sizeof(PLpgSQL_var)); - memset(var, 0, sizeof(PLpgSQL_var)); - - var->dtype = PLPGSQL_DTYPE_VAR; - var->refname = refname; - var->lineno = lineno; - var->datatype = dtype; - /* other fields might be filled by caller */ - - /* preset to NULL */ - var->value = 0; - var->isnull = true; - var->freeval = false; - - plpgsql_adddatum((PLpgSQL_datum *) var); - if (add2namespace) - plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, - var->varno, - refname); - result = (PLpgSQL_variable *) var; - break; - } + { + /* Ordinary scalar datatype */ + PLpgSQL_var *var; + + var = malloc(sizeof(PLpgSQL_var)); + memset(var, 0, sizeof(PLpgSQL_var)); + + var->dtype = PLPGSQL_DTYPE_VAR; + var->refname = refname; + var->lineno = lineno; + var->datatype = dtype; + /* other fields might be filled by caller */ + + /* preset to NULL */ + var->value = 0; + var->isnull = true; + var->freeval = false; + + plpgsql_adddatum((PLpgSQL_datum *) var); + if (add2namespace) + plpgsql_ns_additem(PLPGSQL_NSTYPE_VAR, + var->varno, + refname); + result = (PLpgSQL_variable *) var; + break; + } case PLPGSQL_TTYPE_ROW: - { - /* Composite type -- build a row variable */ - PLpgSQL_row *row; + { + /* Composite type -- build a row variable */ + PLpgSQL_row *row; - row = build_row_var(dtype->typrelid); + row = build_row_var(dtype->typrelid); - row->dtype = PLPGSQL_DTYPE_ROW; - row->refname = refname; - row->lineno = lineno; + row->dtype = PLPGSQL_DTYPE_ROW; + row->refname = refname; + row->lineno = lineno; - plpgsql_adddatum((PLpgSQL_datum *) row); - if (add2namespace) - plpgsql_ns_additem(PLPGSQL_NSTYPE_ROW, - row->rowno, - refname); - result = (PLpgSQL_variable *) row; - break; - } + plpgsql_adddatum((PLpgSQL_datum *) row); + if (add2namespace) + plpgsql_ns_additem(PLPGSQL_NSTYPE_ROW, + row->rowno, + refname); + result = (PLpgSQL_variable *) row; + break; + } case PLPGSQL_TTYPE_REC: - { - /* "record" type -- build a variable-contents record variable */ - PLpgSQL_rec *rec; + { + /* + * "record" type -- build a variable-contents record + * variable + */ + PLpgSQL_rec *rec; - rec = malloc(sizeof(PLpgSQL_rec)); - memset(rec, 0, sizeof(PLpgSQL_rec)); + rec = malloc(sizeof(PLpgSQL_rec)); + memset(rec, 0, sizeof(PLpgSQL_rec)); - rec->dtype = PLPGSQL_DTYPE_REC; - rec->refname = refname; - rec->lineno = lineno; + rec->dtype = PLPGSQL_DTYPE_REC; + rec->refname = refname; + rec->lineno = lineno; - plpgsql_adddatum((PLpgSQL_datum *) rec); - if (add2namespace) - plpgsql_ns_additem(PLPGSQL_NSTYPE_REC, - rec->recno, - refname); - result = (PLpgSQL_variable *) rec; - break; - } + plpgsql_adddatum((PLpgSQL_datum *) rec); + if (add2namespace) + plpgsql_ns_additem(PLPGSQL_NSTYPE_REC, + rec->recno, + refname); + result = (PLpgSQL_variable *) rec; + break; + } case PLPGSQL_TTYPE_PSEUDO: - { - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("variable \"%s\" has pseudo-type %s", - refname, format_type_be(dtype->typoid)))); - result = NULL; /* keep compiler quiet */ - break; - } + { + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("variable \"%s\" has pseudo-type %s", + refname, format_type_be(dtype->typoid)))); + result = NULL; /* keep compiler quiet */ + break; + } default: elog(ERROR, "unrecognized ttype: %d", dtype->ttype); result = NULL; /* keep compiler quiet */ @@ -1589,7 +1594,7 @@ build_row_var(Oid classOid) if (!attrStruct->attisdropped) { const char *attname; - char *refname; + char *refname; PLpgSQL_variable *var; attname = NameStr(attrStruct->attname); @@ -1603,14 +1608,14 @@ build_row_var(Oid classOid) * * We know if the table definitions contain a default value or if * the field is declared in the table as NOT NULL. But it's - * possible to create a table field as NOT NULL without a default - * value and that would lead to problems later when initializing - * the variables due to entering a block at execution time. Thus - * we ignore this information for now. + * possible to create a table field as NOT NULL without a + * default value and that would lead to problems later when + * initializing the variables due to entering a block at + * execution time. Thus we ignore this information for now. */ var = plpgsql_build_variable(refname, 0, - plpgsql_build_datatype(attrStruct->atttypid, - attrStruct->atttypmod), + plpgsql_build_datatype(attrStruct->atttypid, + attrStruct->atttypmod), false); /* @@ -1735,17 +1740,17 @@ PLpgSQL_condition * plpgsql_parse_err_condition(char *condname) { int i; - PLpgSQL_condition *new; - PLpgSQL_condition *prev; + PLpgSQL_condition *new; + PLpgSQL_condition *prev; /* - * XXX Eventually we will want to look for user-defined exception names - * here. + * XXX Eventually we will want to look for user-defined exception + * names here. */ /* - * OTHERS is represented as code 0 (which would map to '00000', but - * we have no need to represent that as an exception condition). + * OTHERS is represented as code 0 (which would map to '00000', but we + * have no need to represent that as an exception condition). */ if (strcmp(condname, "others") == 0) { @@ -1860,7 +1865,7 @@ plpgsql_add_initdatums(int **varnos) static void compute_function_hashkey(FunctionCallInfo fcinfo, Form_pg_proc procStruct, - PLpgSQL_func_hashkey *hashkey, + PLpgSQL_func_hashkey * hashkey, bool forValidator) { int i; @@ -1872,9 +1877,9 @@ compute_function_hashkey(FunctionCallInfo fcinfo, hashkey->funcOid = fcinfo->flinfo->fn_oid; /* - * if trigger, get relation OID. In validation mode we do not know what - * relation is intended to be used, so we leave trigrelOid zero; the - * hash entry built in this case will never really be used. + * if trigger, get relation OID. In validation mode we do not know + * what relation is intended to be used, so we leave trigrelOid zero; + * the hash entry built in this case will never really be used. */ if (CALLED_AS_TRIGGER(fcinfo) && !forValidator) { @@ -1939,7 +1944,7 @@ plpgsql_HashTableInit(void) } static PLpgSQL_function * -plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key) +plpgsql_HashTableLookup(PLpgSQL_func_hashkey * func_key) { plpgsql_HashEnt *hentry; @@ -1954,8 +1959,8 @@ plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key) } static void -plpgsql_HashTableInsert(PLpgSQL_function *function, - PLpgSQL_func_hashkey *func_key) +plpgsql_HashTableInsert(PLpgSQL_function * function, + PLpgSQL_func_hashkey * func_key) { plpgsql_HashEnt *hentry; bool found; @@ -1977,7 +1982,7 @@ plpgsql_HashTableInsert(PLpgSQL_function *function, } static void -plpgsql_HashTableDelete(PLpgSQL_function *function) +plpgsql_HashTableDelete(PLpgSQL_function * function) { plpgsql_HashEnt *hentry; diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index 48148c90cbe..bad50b40305 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -3,7 +3,7 @@ * procedural language * * IDENTIFICATION - * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.116 2004/08/20 22:00:14 tgl Exp $ + * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.117 2004/08/29 05:07:01 momjian Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -61,7 +61,7 @@ static const char *const raise_skip_msg = "RAISE"; * All plpgsql function executions within a single transaction share * the same executor EState for evaluating "simple" expressions. Each * function call creates its own "eval_econtext" ExprContext within this - * estate. We destroy the estate at transaction shutdown to ensure there + * estate. We destroy the estate at transaction shutdown to ensure there * is no permanent leakage of memory (especially for xact abort case). * * If a simple PLpgSQL_expr has been used in the current xact, it is @@ -149,11 +149,11 @@ static void exec_eval_datum(PLpgSQL_execstate * estate, Datum *value, bool *isnull); static int exec_eval_integer(PLpgSQL_execstate * estate, - PLpgSQL_expr * expr, - bool *isNull); + PLpgSQL_expr * expr, + bool *isNull); static bool exec_eval_boolean(PLpgSQL_execstate * estate, - PLpgSQL_expr * expr, - bool *isNull); + PLpgSQL_expr * expr, + bool *isNull); static Datum exec_eval_expr(PLpgSQL_execstate * estate, PLpgSQL_expr * expr, bool *isNull, @@ -165,8 +165,8 @@ static void exec_move_row(PLpgSQL_execstate * estate, PLpgSQL_row * row, HeapTuple tup, TupleDesc tupdesc); static HeapTuple make_tuple_from_row(PLpgSQL_execstate * estate, - PLpgSQL_row * row, - TupleDesc tupdesc); + PLpgSQL_row * row, + TupleDesc tupdesc); static char *convert_value_to_string(Datum value, Oid valtype); static Datum exec_cast_value(Datum value, Oid valtype, Oid reqtype, @@ -786,15 +786,15 @@ copy_rec(PLpgSQL_rec * rec) static bool -exception_matches_conditions(ErrorData *edata, PLpgSQL_condition *cond) +exception_matches_conditions(ErrorData *edata, PLpgSQL_condition * cond) { for (; cond != NULL; cond = cond->next) { int sqlerrstate = cond->sqlerrstate; /* - * OTHERS matches everything *except* query-canceled; - * if you're foolish enough, you can match that explicitly. + * OTHERS matches everything *except* query-canceled; if you're + * foolish enough, you can match that explicitly. */ if (sqlerrstate == 0) { @@ -893,11 +893,12 @@ exec_stmt_block(PLpgSQL_execstate * estate, PLpgSQL_stmt_block * block) if (block->exceptions) { /* - * Execute the statements in the block's body inside a sub-transaction + * Execute the statements in the block's body inside a + * sub-transaction */ - MemoryContext oldcontext = CurrentMemoryContext; - volatile bool caught = false; - int xrc; + MemoryContext oldcontext = CurrentMemoryContext; + volatile bool caught = false; + int xrc; /* * Start a subtransaction, and re-connect to SPI within it @@ -911,12 +912,10 @@ exec_stmt_block(PLpgSQL_execstate * estate, PLpgSQL_stmt_block * block) SPI_result_code_string(xrc)); PG_TRY(); - { rc = exec_stmts(estate, block->body); - } PG_CATCH(); { - ErrorData *edata; + ErrorData *edata; PLpgSQL_exceptions *exceptions; int j; @@ -1723,11 +1722,11 @@ exec_stmt_return(PLpgSQL_execstate * estate, PLpgSQL_stmt_return * stmt) { PLpgSQL_row *row = (PLpgSQL_row *) (estate->datums[stmt->retrowno]); - if (row->rowtupdesc) /* should always be true here */ + if (row->rowtupdesc) /* should always be true here */ { estate->retval = (Datum) make_tuple_from_row(estate, row, - row->rowtupdesc); - if (estate->retval == (Datum) NULL) /* should not happen */ + row->rowtupdesc); + if (estate->retval == (Datum) NULL) /* should not happen */ elog(ERROR, "row not compatible with its own tupdesc"); estate->rettupdesc = row->rowtupdesc; estate->retisnull = false; @@ -1815,7 +1814,7 @@ exec_stmt_return_next(PLpgSQL_execstate * estate, if (tuple == NULL) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("wrong record type supplied in RETURN NEXT"))); + errmsg("wrong record type supplied in RETURN NEXT"))); free_tuple = true; } else if (stmt->expr) @@ -1957,8 +1956,8 @@ exec_stmt_raise(PLpgSQL_execstate * estate, PLpgSQL_stmt_raise * stmt) estate->err_text = raise_skip_msg; /* suppress traceback of raise */ ereport(stmt->elog_level, - ((stmt->elog_level >= ERROR) ? errcode(ERRCODE_RAISE_EXCEPTION) : 0, - errmsg_internal("%s", plpgsql_dstring_get(&ds)))); + ((stmt->elog_level >= ERROR) ? errcode(ERRCODE_RAISE_EXCEPTION) : 0, + errmsg_internal("%s", plpgsql_dstring_get(&ds)))); estate->err_text = NULL; /* un-suppress... */ @@ -2072,16 +2071,16 @@ exec_prepare_plan(PLpgSQL_execstate * estate, case SPI_ERROR_COPY: ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot COPY to/from client in PL/pgSQL"))); + errmsg("cannot COPY to/from client in PL/pgSQL"))); case SPI_ERROR_CURSOR: ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot manipulate cursors directly in PL/pgSQL"), - errhint("Use PL/pgSQL's cursor features instead."))); + errmsg("cannot manipulate cursors directly in PL/pgSQL"), + errhint("Use PL/pgSQL's cursor features instead."))); case SPI_ERROR_TRANSACTION: ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot begin/end transactions in PL/pgSQL"), + errmsg("cannot begin/end transactions in PL/pgSQL"), errhint("Use a BEGIN block with an EXCEPTION clause instead."))); default: elog(ERROR, "SPI_prepare failed for \"%s\": %s", @@ -2268,7 +2267,7 @@ exec_stmt_dynexecute(PLpgSQL_execstate * estate, break; } - /* Some SPI errors deserve specific error messages */ + /* Some SPI errors deserve specific error messages */ case SPI_ERROR_COPY: ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -2276,7 +2275,7 @@ exec_stmt_dynexecute(PLpgSQL_execstate * estate, case SPI_ERROR_CURSOR: ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot manipulate cursors directly in PL/pgSQL"), + errmsg("cannot manipulate cursors directly in PL/pgSQL"), errhint("Use PL/pgSQL's cursor features instead."))); case SPI_ERROR_TRANSACTION: ereport(ERROR, @@ -2812,367 +2811,370 @@ exec_assign_value(PLpgSQL_execstate * estate, switch (target->dtype) { case PLPGSQL_DTYPE_VAR: - { - /* - * Target is a variable - */ - PLpgSQL_var *var = (PLpgSQL_var *) target; - Datum newvalue; + { + /* + * Target is a variable + */ + PLpgSQL_var *var = (PLpgSQL_var *) target; + Datum newvalue; - newvalue = exec_cast_value(value, valtype, var->datatype->typoid, - &(var->datatype->typinput), - var->datatype->typioparam, - var->datatype->atttypmod, - isNull); + newvalue = exec_cast_value(value, valtype, var->datatype->typoid, + &(var->datatype->typinput), + var->datatype->typioparam, + var->datatype->atttypmod, + isNull); - if (*isNull && var->notnull) - ereport(ERROR, - (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), - errmsg("NULL cannot be assigned to variable \"%s\" declared NOT NULL", - var->refname))); + if (*isNull && var->notnull) + ereport(ERROR, + (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), + errmsg("NULL cannot be assigned to variable \"%s\" declared NOT NULL", + var->refname))); - if (var->freeval) - { - pfree(DatumGetPointer(var->value)); - var->freeval = false; - } + if (var->freeval) + { + pfree(DatumGetPointer(var->value)); + var->freeval = false; + } - /* - * If type is by-reference, make sure we have a freshly - * palloc'd copy; the originally passed value may not live as - * long as the variable! But we don't need to re-copy if - * exec_cast_value performed a conversion; its output must - * already be palloc'd. - */ - if (!var->datatype->typbyval && !*isNull) - { - if (newvalue == value) - var->value = datumCopy(newvalue, - false, - var->datatype->typlen); + /* + * If type is by-reference, make sure we have a freshly + * palloc'd copy; the originally passed value may not live + * as long as the variable! But we don't need to re-copy + * if exec_cast_value performed a conversion; its output + * must already be palloc'd. + */ + if (!var->datatype->typbyval && !*isNull) + { + if (newvalue == value) + var->value = datumCopy(newvalue, + false, + var->datatype->typlen); + else + var->value = newvalue; + var->freeval = true; + } else var->value = newvalue; - var->freeval = true; + var->isnull = *isNull; + break; } - else - var->value = newvalue; - var->isnull = *isNull; - break; - } case PLPGSQL_DTYPE_ROW: - { - /* - * Target is a row variable - */ - PLpgSQL_row *row = (PLpgSQL_row *) target; - - /* Source must be of RECORD or composite type */ - if (!(valtype == RECORDOID || - get_typtype(valtype) == 'c')) - ereport(ERROR, - (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("cannot assign non-composite value to a row variable"))); - if (*isNull) - { - /* If source is null, just assign nulls to the row */ - exec_move_row(estate, NULL, row, NULL, NULL); - } - else { - HeapTupleHeader td; - Oid tupType; - int32 tupTypmod; - TupleDesc tupdesc; - HeapTupleData tmptup; - - /* Else source is a tuple Datum, safe to do this: */ - td = DatumGetHeapTupleHeader(value); - /* Extract rowtype info and find a tupdesc */ - tupType = HeapTupleHeaderGetTypeId(td); - tupTypmod = HeapTupleHeaderGetTypMod(td); - tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod); - /* Build a temporary HeapTuple control structure */ - tmptup.t_len = HeapTupleHeaderGetDatumLength(td); - ItemPointerSetInvalid(&(tmptup.t_self)); - tmptup.t_tableOid = InvalidOid; - tmptup.t_data = td; - exec_move_row(estate, NULL, row, &tmptup, tupdesc); + /* + * Target is a row variable + */ + PLpgSQL_row *row = (PLpgSQL_row *) target; + + /* Source must be of RECORD or composite type */ + if (!(valtype == RECORDOID || + get_typtype(valtype) == 'c')) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("cannot assign non-composite value to a row variable"))); + if (*isNull) + { + /* If source is null, just assign nulls to the row */ + exec_move_row(estate, NULL, row, NULL, NULL); + } + else + { + HeapTupleHeader td; + Oid tupType; + int32 tupTypmod; + TupleDesc tupdesc; + HeapTupleData tmptup; + + /* Else source is a tuple Datum, safe to do this: */ + td = DatumGetHeapTupleHeader(value); + /* Extract rowtype info and find a tupdesc */ + tupType = HeapTupleHeaderGetTypeId(td); + tupTypmod = HeapTupleHeaderGetTypMod(td); + tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod); + /* Build a temporary HeapTuple control structure */ + tmptup.t_len = HeapTupleHeaderGetDatumLength(td); + ItemPointerSetInvalid(&(tmptup.t_self)); + tmptup.t_tableOid = InvalidOid; + tmptup.t_data = td; + exec_move_row(estate, NULL, row, &tmptup, tupdesc); + } + break; } - break; - } case PLPGSQL_DTYPE_REC: - { - /* - * Target is a record variable - */ - PLpgSQL_rec *rec = (PLpgSQL_rec *) target; - - /* Source must be of RECORD or composite type */ - if (!(valtype == RECORDOID || - get_typtype(valtype) == 'c')) - ereport(ERROR, - (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("cannot assign non-composite value to a record variable"))); - if (*isNull) { - /* If source is null, just assign nulls to the record */ - exec_move_row(estate, rec, NULL, NULL, NULL); - } - else - { - HeapTupleHeader td; - Oid tupType; - int32 tupTypmod; - TupleDesc tupdesc; - HeapTupleData tmptup; - - /* Else source is a tuple Datum, safe to do this: */ - td = DatumGetHeapTupleHeader(value); - /* Extract rowtype info and find a tupdesc */ - tupType = HeapTupleHeaderGetTypeId(td); - tupTypmod = HeapTupleHeaderGetTypMod(td); - tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod); - /* Build a temporary HeapTuple control structure */ - tmptup.t_len = HeapTupleHeaderGetDatumLength(td); - ItemPointerSetInvalid(&(tmptup.t_self)); - tmptup.t_tableOid = InvalidOid; - tmptup.t_data = td; - exec_move_row(estate, rec, NULL, &tmptup, tupdesc); + /* + * Target is a record variable + */ + PLpgSQL_rec *rec = (PLpgSQL_rec *) target; + + /* Source must be of RECORD or composite type */ + if (!(valtype == RECORDOID || + get_typtype(valtype) == 'c')) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("cannot assign non-composite value to a record variable"))); + if (*isNull) + { + /* If source is null, just assign nulls to the record */ + exec_move_row(estate, rec, NULL, NULL, NULL); + } + else + { + HeapTupleHeader td; + Oid tupType; + int32 tupTypmod; + TupleDesc tupdesc; + HeapTupleData tmptup; + + /* Else source is a tuple Datum, safe to do this: */ + td = DatumGetHeapTupleHeader(value); + /* Extract rowtype info and find a tupdesc */ + tupType = HeapTupleHeaderGetTypeId(td); + tupTypmod = HeapTupleHeaderGetTypMod(td); + tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod); + /* Build a temporary HeapTuple control structure */ + tmptup.t_len = HeapTupleHeaderGetDatumLength(td); + ItemPointerSetInvalid(&(tmptup.t_self)); + tmptup.t_tableOid = InvalidOid; + tmptup.t_data = td; + exec_move_row(estate, rec, NULL, &tmptup, tupdesc); + } + break; } - break; - } case PLPGSQL_DTYPE_RECFIELD: - { - /* - * Target is a field of a record - */ - PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) target; - PLpgSQL_rec *rec; - int fno; - HeapTuple newtup; - int natts; - int i; - Datum *values; - char *nulls; - void *mustfree; - bool attisnull; - Oid atttype; - int32 atttypmod; - - rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]); + { + /* + * Target is a field of a record + */ + PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) target; + PLpgSQL_rec *rec; + int fno; + HeapTuple newtup; + int natts; + int i; + Datum *values; + char *nulls; + void *mustfree; + bool attisnull; + Oid atttype; + int32 atttypmod; + + rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]); - /* - * Check that there is already a tuple in the record. We need - * that because records don't have any predefined field - * structure. - */ - if (!HeapTupleIsValid(rec->tup)) - ereport(ERROR, + /* + * Check that there is already a tuple in the record. We + * need that because records don't have any predefined + * field structure. + */ + if (!HeapTupleIsValid(rec->tup)) + ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("record \"%s\" is not assigned yet", rec->refname), errdetail("The tuple structure of a not-yet-assigned record is indeterminate."))); - /* - * Get the number of the records field to change and the - * number of attributes in the tuple. - */ - fno = SPI_fnumber(rec->tupdesc, recfield->fieldname); - if (fno == SPI_ERROR_NOATTRIBUTE) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_COLUMN), - errmsg("record \"%s\" has no field \"%s\"", - rec->refname, recfield->fieldname))); - fno--; - natts = rec->tupdesc->natts; + /* + * Get the number of the records field to change and the + * number of attributes in the tuple. + */ + fno = SPI_fnumber(rec->tupdesc, recfield->fieldname); + if (fno == SPI_ERROR_NOATTRIBUTE) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("record \"%s\" has no field \"%s\"", + rec->refname, recfield->fieldname))); + fno--; + natts = rec->tupdesc->natts; - /* - * Set up values/datums arrays for heap_formtuple. For all - * the attributes except the one we want to replace, use the - * value that's in the old tuple. - */ - values = palloc(sizeof(Datum) * natts); - nulls = palloc(natts); + /* + * Set up values/datums arrays for heap_formtuple. For + * all the attributes except the one we want to replace, + * use the value that's in the old tuple. + */ + values = palloc(sizeof(Datum) * natts); + nulls = palloc(natts); - for (i = 0; i < natts; i++) - { - if (i == fno) - continue; - values[i] = SPI_getbinval(rec->tup, rec->tupdesc, - i + 1, &attisnull); + for (i = 0; i < natts; i++) + { + if (i == fno) + continue; + values[i] = SPI_getbinval(rec->tup, rec->tupdesc, + i + 1, &attisnull); + if (attisnull) + nulls[i] = 'n'; + else + nulls[i] = ' '; + } + + /* + * Now insert the new value, being careful to cast it to + * the right type. + */ + atttype = SPI_gettypeid(rec->tupdesc, fno + 1); + atttypmod = rec->tupdesc->attrs[fno]->atttypmod; + attisnull = *isNull; + values[fno] = exec_simple_cast_value(value, + valtype, + atttype, + atttypmod, + &attisnull); if (attisnull) - nulls[i] = 'n'; + nulls[fno] = 'n'; else - nulls[i] = ' '; - } + nulls[fno] = ' '; - /* - * Now insert the new value, being careful to cast it to the - * right type. - */ - atttype = SPI_gettypeid(rec->tupdesc, fno + 1); - atttypmod = rec->tupdesc->attrs[fno]->atttypmod; - attisnull = *isNull; - values[fno] = exec_simple_cast_value(value, - valtype, - atttype, - atttypmod, - &attisnull); - if (attisnull) - nulls[fno] = 'n'; - else - nulls[fno] = ' '; - - /* - * Avoid leaking the result of exec_simple_cast_value, if it - * performed a conversion to a pass-by-ref type. - */ - if (!attisnull && values[fno] != value && !get_typbyval(atttype)) - mustfree = DatumGetPointer(values[fno]); - else - mustfree = NULL; + /* + * Avoid leaking the result of exec_simple_cast_value, if + * it performed a conversion to a pass-by-ref type. + */ + if (!attisnull && values[fno] != value && !get_typbyval(atttype)) + mustfree = DatumGetPointer(values[fno]); + else + mustfree = NULL; - /* - * Now call heap_formtuple() to create a new tuple that - * replaces the old one in the record. - */ - newtup = heap_formtuple(rec->tupdesc, values, nulls); + /* + * Now call heap_formtuple() to create a new tuple that + * replaces the old one in the record. + */ + newtup = heap_formtuple(rec->tupdesc, values, nulls); - if (rec->freetup) - heap_freetuple(rec->tup); + if (rec->freetup) + heap_freetuple(rec->tup); - rec->tup = newtup; - rec->freetup = true; + rec->tup = newtup; + rec->freetup = true; - pfree(values); - pfree(nulls); - if (mustfree) - pfree(mustfree); + pfree(values); + pfree(nulls); + if (mustfree) + pfree(mustfree); - break; - } + break; + } case PLPGSQL_DTYPE_ARRAYELEM: - { - int nsubscripts; - int i; - PLpgSQL_expr *subscripts[MAXDIM]; - int subscriptvals[MAXDIM]; - bool havenullsubscript, - oldarrayisnull; - Oid arraytypeid, - arrayelemtypeid; - int16 elemtyplen; - bool elemtypbyval; - char elemtypalign; - Datum oldarrayval, - coerced_value; - ArrayType *newarrayval; - - /* - * Target is an element of an array - * - * To handle constructs like x[1][2] := something, we have to be - * prepared to deal with a chain of arrayelem datums. Chase - * back to find the base array datum, and save the subscript - * expressions as we go. (We are scanning right to left here, - * but want to evaluate the subscripts left-to-right to - * minimize surprises.) - */ - nsubscripts = 0; - do { - PLpgSQL_arrayelem *arrayelem = (PLpgSQL_arrayelem *) target; + int nsubscripts; + int i; + PLpgSQL_expr *subscripts[MAXDIM]; + int subscriptvals[MAXDIM]; + bool havenullsubscript, + oldarrayisnull; + Oid arraytypeid, + arrayelemtypeid; + int16 elemtyplen; + bool elemtypbyval; + char elemtypalign; + Datum oldarrayval, + coerced_value; + ArrayType *newarrayval; - if (nsubscripts >= MAXDIM) - ereport(ERROR, - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("number of array dimensions exceeds the maximum allowed, %d", - MAXDIM))); - subscripts[nsubscripts++] = arrayelem->subscript; - target = estate->datums[arrayelem->arrayparentno]; - } while (target->dtype == PLPGSQL_DTYPE_ARRAYELEM); - - /* Fetch current value of array datum */ - exec_eval_datum(estate, target, InvalidOid, + /* + * Target is an element of an array + * + * To handle constructs like x[1][2] := something, we have to + * be prepared to deal with a chain of arrayelem datums. + * Chase back to find the base array datum, and save the + * subscript expressions as we go. (We are scanning right + * to left here, but want to evaluate the subscripts + * left-to-right to minimize surprises.) + */ + nsubscripts = 0; + do + { + PLpgSQL_arrayelem *arrayelem = (PLpgSQL_arrayelem *) target; + + if (nsubscripts >= MAXDIM) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("number of array dimensions exceeds the maximum allowed, %d", + MAXDIM))); + subscripts[nsubscripts++] = arrayelem->subscript; + target = estate->datums[arrayelem->arrayparentno]; + } while (target->dtype == PLPGSQL_DTYPE_ARRAYELEM); + + /* Fetch current value of array datum */ + exec_eval_datum(estate, target, InvalidOid, &arraytypeid, &oldarrayval, &oldarrayisnull); - arrayelemtypeid = get_element_type(arraytypeid); - if (!OidIsValid(arrayelemtypeid)) - ereport(ERROR, - (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("subscripted object is not an array"))); + arrayelemtypeid = get_element_type(arraytypeid); + if (!OidIsValid(arrayelemtypeid)) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("subscripted object is not an array"))); - /* Evaluate the subscripts, switch into left-to-right order */ - havenullsubscript = false; - for (i = 0; i < nsubscripts; i++) - { - bool subisnull; + /* + * Evaluate the subscripts, switch into left-to-right + * order + */ + havenullsubscript = false; + for (i = 0; i < nsubscripts; i++) + { + bool subisnull; - subscriptvals[i] = - exec_eval_integer(estate, - subscripts[nsubscripts - 1 - i], - &subisnull); - havenullsubscript |= subisnull; - } + subscriptvals[i] = + exec_eval_integer(estate, + subscripts[nsubscripts - 1 - i], + &subisnull); + havenullsubscript |= subisnull; + } - /* - * Skip the assignment if we have any nulls, either in the - * original array value, the subscripts, or the righthand - * side. This is pretty bogus but it corresponds to the - * current behavior of ExecEvalArrayRef(). - */ - if (oldarrayisnull || havenullsubscript || *isNull) - return; + /* + * Skip the assignment if we have any nulls, either in the + * original array value, the subscripts, or the righthand + * side. This is pretty bogus but it corresponds to the + * current behavior of ExecEvalArrayRef(). + */ + if (oldarrayisnull || havenullsubscript || *isNull) + return; - /* Coerce source value to match array element type. */ - coerced_value = exec_simple_cast_value(value, - valtype, - arrayelemtypeid, - -1, - isNull); + /* Coerce source value to match array element type. */ + coerced_value = exec_simple_cast_value(value, + valtype, + arrayelemtypeid, + -1, + isNull); - /* - * Build the modified array value. - */ - get_typlenbyvalalign(arrayelemtypeid, - &elemtyplen, - &elemtypbyval, - &elemtypalign); - - newarrayval = array_set((ArrayType *) DatumGetPointer(oldarrayval), - nsubscripts, - subscriptvals, - coerced_value, - get_typlen(arraytypeid), - elemtyplen, - elemtypbyval, - elemtypalign, - isNull); + /* + * Build the modified array value. + */ + get_typlenbyvalalign(arrayelemtypeid, + &elemtyplen, + &elemtypbyval, + &elemtypalign); + + newarrayval = array_set((ArrayType *) DatumGetPointer(oldarrayval), + nsubscripts, + subscriptvals, + coerced_value, + get_typlen(arraytypeid), + elemtyplen, + elemtypbyval, + elemtypalign, + isNull); - /* - * Assign it to the base variable. - */ - exec_assign_value(estate, target, - PointerGetDatum(newarrayval), - arraytypeid, isNull); + /* + * Assign it to the base variable. + */ + exec_assign_value(estate, target, + PointerGetDatum(newarrayval), + arraytypeid, isNull); - /* - * Avoid leaking the result of exec_simple_cast_value, if it - * performed a conversion to a pass-by-ref type. - */ - if (!*isNull && coerced_value != value && !elemtypbyval) - pfree(DatumGetPointer(coerced_value)); + /* + * Avoid leaking the result of exec_simple_cast_value, if + * it performed a conversion to a pass-by-ref type. + */ + if (!*isNull && coerced_value != value && !elemtypbyval) + pfree(DatumGetPointer(coerced_value)); - /* - * Avoid leaking the modified array value, too. - */ - pfree(newarrayval); - break; - } + /* + * Avoid leaking the modified array value, too. + */ + pfree(newarrayval); + break; + } default: elog(ERROR, "unrecognized dtype: %d", target->dtype); @@ -3203,130 +3205,132 @@ exec_eval_datum(PLpgSQL_execstate * estate, switch (datum->dtype) { case PLPGSQL_DTYPE_VAR: - { - PLpgSQL_var *var = (PLpgSQL_var *) datum; + { + PLpgSQL_var *var = (PLpgSQL_var *) datum; - *typeid = var->datatype->typoid; - *value = var->value; - *isnull = var->isnull; - if (expectedtypeid != InvalidOid && expectedtypeid != *typeid) - ereport(ERROR, - (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("type of \"%s\" does not match that when preparing the plan", - var->refname))); - break; - } + *typeid = var->datatype->typoid; + *value = var->value; + *isnull = var->isnull; + if (expectedtypeid != InvalidOid && expectedtypeid != *typeid) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("type of \"%s\" does not match that when preparing the plan", + var->refname))); + break; + } case PLPGSQL_DTYPE_ROW: - { - PLpgSQL_row *row = (PLpgSQL_row *) datum; - HeapTuple tup; - - if (!row->rowtupdesc) /* should not happen */ - elog(ERROR, "row variable has no tupdesc"); - /* Make sure we have a valid type/typmod setting */ - BlessTupleDesc(row->rowtupdesc); - tup = make_tuple_from_row(estate, row, row->rowtupdesc); - if (tup == NULL) /* should not happen */ - elog(ERROR, "row not compatible with its own tupdesc"); - *typeid = row->rowtupdesc->tdtypeid; - *value = HeapTupleGetDatum(tup); - *isnull = false; - if (expectedtypeid != InvalidOid && expectedtypeid != *typeid) - ereport(ERROR, - (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("type of \"%s\" does not match that when preparing the plan", - row->refname))); - break; - } + { + PLpgSQL_row *row = (PLpgSQL_row *) datum; + HeapTuple tup; + + if (!row->rowtupdesc) /* should not happen */ + elog(ERROR, "row variable has no tupdesc"); + /* Make sure we have a valid type/typmod setting */ + BlessTupleDesc(row->rowtupdesc); + tup = make_tuple_from_row(estate, row, row->rowtupdesc); + if (tup == NULL) /* should not happen */ + elog(ERROR, "row not compatible with its own tupdesc"); + *typeid = row->rowtupdesc->tdtypeid; + *value = HeapTupleGetDatum(tup); + *isnull = false; + if (expectedtypeid != InvalidOid && expectedtypeid != *typeid) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("type of \"%s\" does not match that when preparing the plan", + row->refname))); + break; + } case PLPGSQL_DTYPE_REC: - { - PLpgSQL_rec *rec = (PLpgSQL_rec *) datum; - HeapTupleData worktup; + { + PLpgSQL_rec *rec = (PLpgSQL_rec *) datum; + HeapTupleData worktup; - if (!HeapTupleIsValid(rec->tup)) - ereport(ERROR, - (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("record \"%s\" is not assigned yet", - rec->refname), - errdetail("The tuple structure of a not-yet-assigned record is indeterminate."))); - Assert(rec->tupdesc != NULL); - /* Make sure we have a valid type/typmod setting */ - BlessTupleDesc(rec->tupdesc); - /* - * In a trigger, the NEW and OLD parameters are likely to be - * on-disk tuples that don't have the desired Datum fields. - * Copy the tuple body and insert the right values. - */ - heap_copytuple_with_tuple(rec->tup, &worktup); - HeapTupleHeaderSetDatumLength(worktup.t_data, worktup.t_len); - HeapTupleHeaderSetTypeId(worktup.t_data, rec->tupdesc->tdtypeid); - HeapTupleHeaderSetTypMod(worktup.t_data, rec->tupdesc->tdtypmod); - *typeid = rec->tupdesc->tdtypeid; - *value = HeapTupleGetDatum(&worktup); - *isnull = false; - if (expectedtypeid != InvalidOid && expectedtypeid != *typeid) - ereport(ERROR, - (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("type of \"%s\" does not match that when preparing the plan", - rec->refname))); - break; - } + if (!HeapTupleIsValid(rec->tup)) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("record \"%s\" is not assigned yet", + rec->refname), + errdetail("The tuple structure of a not-yet-assigned record is indeterminate."))); + Assert(rec->tupdesc != NULL); + /* Make sure we have a valid type/typmod setting */ + BlessTupleDesc(rec->tupdesc); + + /* + * In a trigger, the NEW and OLD parameters are likely to + * be on-disk tuples that don't have the desired Datum + * fields. Copy the tuple body and insert the right + * values. + */ + heap_copytuple_with_tuple(rec->tup, &worktup); + HeapTupleHeaderSetDatumLength(worktup.t_data, worktup.t_len); + HeapTupleHeaderSetTypeId(worktup.t_data, rec->tupdesc->tdtypeid); + HeapTupleHeaderSetTypMod(worktup.t_data, rec->tupdesc->tdtypmod); + *typeid = rec->tupdesc->tdtypeid; + *value = HeapTupleGetDatum(&worktup); + *isnull = false; + if (expectedtypeid != InvalidOid && expectedtypeid != *typeid) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("type of \"%s\" does not match that when preparing the plan", + rec->refname))); + break; + } case PLPGSQL_DTYPE_RECFIELD: - { - PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) datum; - PLpgSQL_rec *rec; - int fno; + { + PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) datum; + PLpgSQL_rec *rec; + int fno; - rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]); - if (!HeapTupleIsValid(rec->tup)) - ereport(ERROR, + rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]); + if (!HeapTupleIsValid(rec->tup)) + ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("record \"%s\" is not assigned yet", rec->refname), errdetail("The tuple structure of a not-yet-assigned record is indeterminate."))); - fno = SPI_fnumber(rec->tupdesc, recfield->fieldname); - if (fno == SPI_ERROR_NOATTRIBUTE) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_COLUMN), - errmsg("record \"%s\" has no field \"%s\"", - rec->refname, recfield->fieldname))); - *typeid = SPI_gettypeid(rec->tupdesc, fno); - *value = SPI_getbinval(rec->tup, rec->tupdesc, fno, isnull); - if (expectedtypeid != InvalidOid && expectedtypeid != *typeid) - ereport(ERROR, - (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("type of \"%s.%s\" does not match that when preparing the plan", - rec->refname, recfield->fieldname))); - break; - } + fno = SPI_fnumber(rec->tupdesc, recfield->fieldname); + if (fno == SPI_ERROR_NOATTRIBUTE) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("record \"%s\" has no field \"%s\"", + rec->refname, recfield->fieldname))); + *typeid = SPI_gettypeid(rec->tupdesc, fno); + *value = SPI_getbinval(rec->tup, rec->tupdesc, fno, isnull); + if (expectedtypeid != InvalidOid && expectedtypeid != *typeid) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("type of \"%s.%s\" does not match that when preparing the plan", + rec->refname, recfield->fieldname))); + break; + } case PLPGSQL_DTYPE_TRIGARG: - { - PLpgSQL_trigarg *trigarg = (PLpgSQL_trigarg *) datum; - int tgargno; - - *typeid = TEXTOID; - tgargno = exec_eval_integer(estate, trigarg->argnum, isnull); - if (*isnull || tgargno < 0 || tgargno >= estate->trig_nargs) { - *value = (Datum) 0; - *isnull = true; - } - else - { - *value = estate->trig_argv[tgargno]; - *isnull = false; + PLpgSQL_trigarg *trigarg = (PLpgSQL_trigarg *) datum; + int tgargno; + + *typeid = TEXTOID; + tgargno = exec_eval_integer(estate, trigarg->argnum, isnull); + if (*isnull || tgargno < 0 || tgargno >= estate->trig_nargs) + { + *value = (Datum) 0; + *isnull = true; + } + else + { + *value = estate->trig_argv[tgargno]; + *isnull = false; + } + if (expectedtypeid != InvalidOid && expectedtypeid != *typeid) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("type of tgargv[%d] does not match that when preparing the plan", + tgargno))); + break; } - if (expectedtypeid != InvalidOid && expectedtypeid != *typeid) - ereport(ERROR, - (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("type of tgargv[%d] does not match that when preparing the plan", - tgargno))); - break; - } default: elog(ERROR, "unrecognized dtype: %d", datum->dtype); @@ -3548,7 +3552,7 @@ exec_eval_simple_expr(PLpgSQL_execstate * estate, /* * Create an EState for evaluation of simple expressions, if there's - * not one already in the current transaction. The EState is made a + * not one already in the current transaction. The EState is made a * child of TopTransactionContext so it will have the right lifespan. */ if (simple_eval_estate == NULL) @@ -3574,9 +3578,9 @@ exec_eval_simple_expr(PLpgSQL_execstate * estate, } /* - * Create an expression context for simple expressions, if there's - * not one already in the current function call. This must be a - * child of simple_eval_estate. + * Create an expression context for simple expressions, if there's not + * one already in the current function call. This must be a child of + * simple_eval_estate. */ econtext = estate->eval_econtext; if (econtext == NULL) @@ -3588,10 +3592,10 @@ exec_eval_simple_expr(PLpgSQL_execstate * estate, /* * Param list can live in econtext's temporary memory context. * - * XXX think about avoiding repeated palloc's for param lists? - * Beware however that this routine is re-entrant: exec_eval_datum() - * can call it back for subscript evaluation, and so there can be a - * need to have more than one active param list. + * XXX think about avoiding repeated palloc's for param lists? Beware + * however that this routine is re-entrant: exec_eval_datum() can call + * it back for subscript evaluation, and so there can be a need to + * have more than one active param list. */ paramLI = (ParamListInfo) MemoryContextAllocZero(econtext->ecxt_per_tuple_memory, @@ -3702,7 +3706,7 @@ exec_move_row(PLpgSQL_execstate * estate, * expected if it's from an inheritance-child table of the current * table, or it might have fewer if the table has had columns added by * ALTER TABLE. Ignore extra columns and assume NULL for missing - * columns, the same as heap_getattr would do. We also have to skip + * columns, the same as heap_getattr would do. We also have to skip * over dropped columns in either the source or destination. * * If we have no tuple data at all, we'll assign NULL to all columns of @@ -3787,7 +3791,7 @@ make_tuple_from_row(PLpgSQL_execstate * estate, PLpgSQL_var *var; if (tupdesc->attrs[i]->attisdropped) - continue; /* leave the column as null */ + continue; /* leave the column as null */ if (row->varnos[i] < 0) /* should not happen */ elog(ERROR, "dropped rowtype entry for non-dropped column"); @@ -4000,7 +4004,7 @@ exec_simple_check_node(Node *node) case T_FieldStore: { - FieldStore *expr = (FieldStore *) node; + FieldStore *expr = (FieldStore *) node; if (!exec_simple_check_node((Node *) expr->arg)) return FALSE; @@ -4054,7 +4058,7 @@ exec_simple_check_node(Node *node) case T_RowExpr: { - RowExpr *expr = (RowExpr *) node; + RowExpr *expr = (RowExpr *) node; if (!exec_simple_check_node((Node *) expr->args)) return FALSE; @@ -4237,8 +4241,8 @@ plpgsql_xact_cb(XactEvent event, TransactionId parentXid, void *arg) /* * Nothing to do at subtransaction events * - * XXX really? Maybe subtransactions need to have their own - * simple_eval_estate? It would get a lot messier, so for now + * XXX really? Maybe subtransactions need to have their own + * simple_eval_estate? It would get a lot messier, so for now * let's assume we don't need that. */ case XACT_EVENT_START_SUB: @@ -4256,11 +4260,12 @@ plpgsql_xact_cb(XactEvent event, TransactionId parentXid, void *arg) expr->expr_simple_next = NULL; } active_simple_exprs = NULL; + /* - * If we are doing a clean transaction shutdown, free the EState - * (so that any remaining resources will be released correctly). - * In an abort, we expect the regular abort recovery procedures to - * release everything of interest. + * If we are doing a clean transaction shutdown, free the + * EState (so that any remaining resources will be released + * correctly). In an abort, we expect the regular abort + * recovery procedures to release everything of interest. */ if (event == XACT_EVENT_COMMIT && simple_eval_estate) FreeExecutorState(simple_eval_estate); diff --git a/src/pl/plpgsql/src/pl_funcs.c b/src/pl/plpgsql/src/pl_funcs.c index 028bc3836cb..3de37a3ad14 100644 --- a/src/pl/plpgsql/src/pl_funcs.c +++ b/src/pl/plpgsql/src/pl_funcs.c @@ -3,7 +3,7 @@ * procedural language * * IDENTIFICATION - * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_funcs.c,v 1.34 2004/07/31 23:04:56 tgl Exp $ + * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_funcs.c,v 1.35 2004/08/29 05:07:01 momjian Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -355,7 +355,7 @@ plpgsql_convert_ident(const char *s, char **output, int numidents) { /* Quoted identifier: copy, collapsing out doubled quotes */ - curident = palloc(strlen(s) + 1); /* surely enough room */ + curident = palloc(strlen(s) + 1); /* surely enough room */ cp = curident; s++; while (*s) @@ -375,7 +375,7 @@ plpgsql_convert_ident(const char *s, char **output, int numidents) s++; *cp = '\0'; /* Truncate to NAMEDATALEN */ - truncate_identifier(curident, cp-curident, false); + truncate_identifier(curident, cp - curident, false); } else { @@ -385,7 +385,7 @@ plpgsql_convert_ident(const char *s, char **output, int numidents) while (*s && *s != '.' && !isspace((unsigned char) *s)) s++; /* Downcase and truncate to NAMEDATALEN */ - curident = downcase_truncate_identifier(thisstart, s-thisstart, + curident = downcase_truncate_identifier(thisstart, s - thisstart, false); } diff --git a/src/pl/plpgsql/src/plerrcodes.h b/src/pl/plpgsql/src/plerrcodes.h index 18a2bc81edf..5ad86ed07ed 100644 --- a/src/pl/plpgsql/src/plerrcodes.h +++ b/src/pl/plpgsql/src/plerrcodes.h @@ -9,185 +9,712 @@ * * Copyright (c) 2003, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/pl/plpgsql/src/plerrcodes.h,v 1.3 2004/08/02 17:03:48 tgl Exp $ + * $PostgreSQL: pgsql/src/pl/plpgsql/src/plerrcodes.h,v 1.4 2004/08/29 05:07:01 momjian Exp $ * *------------------------------------------------------------------------- */ /* Success and warnings can't be caught, so omit them from table */ -{ "sql_statement_not_yet_complete", ERRCODE_SQL_STATEMENT_NOT_YET_COMPLETE }, -{ "connection_exception", ERRCODE_CONNECTION_EXCEPTION }, -{ "connection_does_not_exist", ERRCODE_CONNECTION_DOES_NOT_EXIST }, -{ "connection_failure", ERRCODE_CONNECTION_FAILURE }, -{ "sqlclient_unable_to_establish_sqlconnection", ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION }, -{ "sqlserver_rejected_establishment_of_sqlconnection", ERRCODE_SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION }, -{ "transaction_resolution_unknown", ERRCODE_TRANSACTION_RESOLUTION_UNKNOWN }, -{ "protocol_violation", ERRCODE_PROTOCOL_VIOLATION }, -{ "triggered_action_exception", ERRCODE_TRIGGERED_ACTION_EXCEPTION }, -{ "feature_not_supported", ERRCODE_FEATURE_NOT_SUPPORTED }, -{ "invalid_transaction_initiation", ERRCODE_INVALID_TRANSACTION_INITIATION }, -{ "locator_exception", ERRCODE_LOCATOR_EXCEPTION }, -{ "invalid_locator_specification", ERRCODE_L_E_INVALID_SPECIFICATION }, -{ "invalid_grantor", ERRCODE_INVALID_GRANTOR }, -{ "invalid_grant_operation", ERRCODE_INVALID_GRANT_OPERATION }, -{ "invalid_role_specification", ERRCODE_INVALID_ROLE_SPECIFICATION }, -{ "cardinality_violation", ERRCODE_CARDINALITY_VIOLATION }, -{ "data_exception", ERRCODE_DATA_EXCEPTION }, -{ "array_element_error", ERRCODE_ARRAY_ELEMENT_ERROR }, -{ "array_subscript_error", ERRCODE_ARRAY_SUBSCRIPT_ERROR }, -{ "character_not_in_repertoire", ERRCODE_CHARACTER_NOT_IN_REPERTOIRE }, -{ "datetime_field_overflow", ERRCODE_DATETIME_FIELD_OVERFLOW }, -{ "datetime_value_out_of_range", ERRCODE_DATETIME_VALUE_OUT_OF_RANGE }, -{ "division_by_zero", ERRCODE_DIVISION_BY_ZERO }, -{ "error_in_assignment", ERRCODE_ERROR_IN_ASSIGNMENT }, -{ "escape_character_conflict", ERRCODE_ESCAPE_CHARACTER_CONFLICT }, -{ "indicator_overflow", ERRCODE_INDICATOR_OVERFLOW }, -{ "interval_field_overflow", ERRCODE_INTERVAL_FIELD_OVERFLOW }, -{ "invalid_argument_for_logarithm", ERRCODE_INVALID_ARGUMENT_FOR_LOG }, -{ "invalid_argument_for_power_function", ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION }, -{ "invalid_argument_for_width_bucket_function", ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION }, -{ "invalid_character_value_for_cast", ERRCODE_INVALID_CHARACTER_VALUE_FOR_CAST }, -{ "invalid_datetime_format", ERRCODE_INVALID_DATETIME_FORMAT }, -{ "invalid_escape_character", ERRCODE_INVALID_ESCAPE_CHARACTER }, -{ "invalid_escape_octet", ERRCODE_INVALID_ESCAPE_OCTET }, -{ "invalid_escape_sequence", ERRCODE_INVALID_ESCAPE_SEQUENCE }, -{ "invalid_indicator_parameter_value", ERRCODE_INVALID_INDICATOR_PARAMETER_VALUE }, -{ "invalid_limit_value", ERRCODE_INVALID_LIMIT_VALUE }, -{ "invalid_parameter_value", ERRCODE_INVALID_PARAMETER_VALUE }, -{ "invalid_regular_expression", ERRCODE_INVALID_REGULAR_EXPRESSION }, -{ "invalid_time_zone_displacement_value", ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE }, -{ "invalid_use_of_escape_character", ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER }, -{ "most_specific_type_mismatch", ERRCODE_MOST_SPECIFIC_TYPE_MISMATCH }, -{ "null_value_not_allowed", ERRCODE_NULL_VALUE_NOT_ALLOWED }, -{ "null_value_no_indicator_parameter", ERRCODE_NULL_VALUE_NO_INDICATOR_PARAMETER }, -{ "numeric_value_out_of_range", ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE }, -{ "string_data_length_mismatch", ERRCODE_STRING_DATA_LENGTH_MISMATCH }, -{ "string_data_right_truncation", ERRCODE_STRING_DATA_RIGHT_TRUNCATION }, -{ "substring_error", ERRCODE_SUBSTRING_ERROR }, -{ "trim_error", ERRCODE_TRIM_ERROR }, -{ "unterminated_c_string", ERRCODE_UNTERMINATED_C_STRING }, -{ "zero_length_character_string", ERRCODE_ZERO_LENGTH_CHARACTER_STRING }, -{ "floating_point_exception", ERRCODE_FLOATING_POINT_EXCEPTION }, -{ "invalid_text_representation", ERRCODE_INVALID_TEXT_REPRESENTATION }, -{ "invalid_binary_representation", ERRCODE_INVALID_BINARY_REPRESENTATION }, -{ "bad_copy_file_format", ERRCODE_BAD_COPY_FILE_FORMAT }, -{ "untranslatable_character", ERRCODE_UNTRANSLATABLE_CHARACTER }, -{ "integrity_constraint_violation", ERRCODE_INTEGRITY_CONSTRAINT_VIOLATION }, -{ "restrict_violation", ERRCODE_RESTRICT_VIOLATION }, -{ "not_null_violation", ERRCODE_NOT_NULL_VIOLATION }, -{ "foreign_key_violation", ERRCODE_FOREIGN_KEY_VIOLATION }, -{ "unique_violation", ERRCODE_UNIQUE_VIOLATION }, -{ "check_violation", ERRCODE_CHECK_VIOLATION }, -{ "invalid_cursor_state", ERRCODE_INVALID_CURSOR_STATE }, -{ "invalid_transaction_state", ERRCODE_INVALID_TRANSACTION_STATE }, -{ "active_sql_transaction", ERRCODE_ACTIVE_SQL_TRANSACTION }, -{ "branch_transaction_already_active", ERRCODE_BRANCH_TRANSACTION_ALREADY_ACTIVE }, -{ "held_cursor_requires_same_isolation_level", ERRCODE_HELD_CURSOR_REQUIRES_SAME_ISOLATION_LEVEL }, -{ "inappropriate_access_mode_for_branch_transaction", ERRCODE_INAPPROPRIATE_ACCESS_MODE_FOR_BRANCH_TRANSACTION }, -{ "inappropriate_isolation_level_for_branch_transaction", ERRCODE_INAPPROPRIATE_ISOLATION_LEVEL_FOR_BRANCH_TRANSACTION }, -{ "no_active_sql_transaction_for_branch_transaction", ERRCODE_NO_ACTIVE_SQL_TRANSACTION_FOR_BRANCH_TRANSACTION }, -{ "read_only_sql_transaction", ERRCODE_READ_ONLY_SQL_TRANSACTION }, -{ "schema_and_data_statement_mixing_not_supported", ERRCODE_SCHEMA_AND_DATA_STATEMENT_MIXING_NOT_SUPPORTED }, -{ "no_active_sql_transaction", ERRCODE_NO_ACTIVE_SQL_TRANSACTION }, -{ "in_failed_sql_transaction", ERRCODE_IN_FAILED_SQL_TRANSACTION }, -{ "invalid_sql_statement_name", ERRCODE_INVALID_SQL_STATEMENT_NAME }, -{ "triggered_data_change_violation", ERRCODE_TRIGGERED_DATA_CHANGE_VIOLATION }, -{ "invalid_authorization_specification", ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION }, -{ "dependent_privilege_descriptors_still_exist", ERRCODE_DEPENDENT_PRIVILEGE_DESCRIPTORS_STILL_EXIST }, -{ "dependent_objects_still_exist", ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST }, -{ "invalid_transaction_termination", ERRCODE_INVALID_TRANSACTION_TERMINATION }, -{ "sql_routine_exception", ERRCODE_SQL_ROUTINE_EXCEPTION }, -{ "function_executed_no_return_statement", ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT }, -{ "modifying_sql_data_not_permitted", ERRCODE_S_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED }, -{ "prohibited_sql_statement_attempted", ERRCODE_S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED }, -{ "reading_sql_data_not_permitted", ERRCODE_S_R_E_READING_SQL_DATA_NOT_PERMITTED }, -{ "invalid_cursor_name", ERRCODE_INVALID_CURSOR_NAME }, -{ "external_routine_exception", ERRCODE_EXTERNAL_ROUTINE_EXCEPTION }, -{ "containing_sql_not_permitted", ERRCODE_E_R_E_CONTAINING_SQL_NOT_PERMITTED }, -{ "modifying_sql_data_not_permitted", ERRCODE_E_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED }, -{ "prohibited_sql_statement_attempted", ERRCODE_E_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED }, -{ "reading_sql_data_not_permitted", ERRCODE_E_R_E_READING_SQL_DATA_NOT_PERMITTED }, -{ "external_routine_invocation_exception", ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION }, -{ "invalid_sqlstate_returned", ERRCODE_E_R_I_E_INVALID_SQLSTATE_RETURNED }, -{ "null_value_not_allowed", ERRCODE_E_R_I_E_NULL_VALUE_NOT_ALLOWED }, -{ "trigger_protocol_violated", ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED }, -{ "srf_protocol_violated", ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED }, -{ "savepoint_exception", ERRCODE_SAVEPOINT_EXCEPTION }, -{ "invalid_savepoint_specification", ERRCODE_S_E_INVALID_SPECIFICATION }, -{ "invalid_catalog_name", ERRCODE_INVALID_CATALOG_NAME }, -{ "invalid_schema_name", ERRCODE_INVALID_SCHEMA_NAME }, -{ "transaction_rollback", ERRCODE_TRANSACTION_ROLLBACK }, -{ "transaction_integrity_constraint_violation", ERRCODE_T_R_INTEGRITY_CONSTRAINT_VIOLATION }, -{ "serialization_failure", ERRCODE_T_R_SERIALIZATION_FAILURE }, -{ "statement_completion_unknown", ERRCODE_T_R_STATEMENT_COMPLETION_UNKNOWN }, -{ "deadlock_detected", ERRCODE_T_R_DEADLOCK_DETECTED }, -{ "syntax_error_or_access_rule_violation", ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION }, -{ "syntax_error", ERRCODE_SYNTAX_ERROR }, -{ "insufficient_privilege", ERRCODE_INSUFFICIENT_PRIVILEGE }, -{ "cannot_coerce", ERRCODE_CANNOT_COERCE }, -{ "grouping_error", ERRCODE_GROUPING_ERROR }, -{ "invalid_foreign_key", ERRCODE_INVALID_FOREIGN_KEY }, -{ "invalid_name", ERRCODE_INVALID_NAME }, -{ "name_too_long", ERRCODE_NAME_TOO_LONG }, -{ "reserved_name", ERRCODE_RESERVED_NAME }, -{ "datatype_mismatch", ERRCODE_DATATYPE_MISMATCH }, -{ "indeterminate_datatype", ERRCODE_INDETERMINATE_DATATYPE }, -{ "wrong_object_type", ERRCODE_WRONG_OBJECT_TYPE }, -{ "undefined_column", ERRCODE_UNDEFINED_COLUMN }, -{ "undefined_cursor", ERRCODE_UNDEFINED_CURSOR }, -{ "undefined_database", ERRCODE_UNDEFINED_DATABASE }, -{ "undefined_function", ERRCODE_UNDEFINED_FUNCTION }, -{ "undefined_pstatement", ERRCODE_UNDEFINED_PSTATEMENT }, -{ "undefined_schema", ERRCODE_UNDEFINED_SCHEMA }, -{ "undefined_table", ERRCODE_UNDEFINED_TABLE }, -{ "undefined_parameter", ERRCODE_UNDEFINED_PARAMETER }, -{ "undefined_object", ERRCODE_UNDEFINED_OBJECT }, -{ "duplicate_column", ERRCODE_DUPLICATE_COLUMN }, -{ "duplicate_cursor", ERRCODE_DUPLICATE_CURSOR }, -{ "duplicate_database", ERRCODE_DUPLICATE_DATABASE }, -{ "duplicate_function", ERRCODE_DUPLICATE_FUNCTION }, -{ "duplicate_prepared_statement", ERRCODE_DUPLICATE_PSTATEMENT }, -{ "duplicate_schema", ERRCODE_DUPLICATE_SCHEMA }, -{ "duplicate_table", ERRCODE_DUPLICATE_TABLE }, -{ "duplicate_alias", ERRCODE_DUPLICATE_ALIAS }, -{ "duplicate_object", ERRCODE_DUPLICATE_OBJECT }, -{ "ambiguous_column", ERRCODE_AMBIGUOUS_COLUMN }, -{ "ambiguous_function", ERRCODE_AMBIGUOUS_FUNCTION }, -{ "ambiguous_parameter", ERRCODE_AMBIGUOUS_PARAMETER }, -{ "ambiguous_alias", ERRCODE_AMBIGUOUS_ALIAS }, -{ "invalid_column_reference", ERRCODE_INVALID_COLUMN_REFERENCE }, -{ "invalid_column_definition", ERRCODE_INVALID_COLUMN_DEFINITION }, -{ "invalid_cursor_definition", ERRCODE_INVALID_CURSOR_DEFINITION }, -{ "invalid_database_definition", ERRCODE_INVALID_DATABASE_DEFINITION }, -{ "invalid_function_definition", ERRCODE_INVALID_FUNCTION_DEFINITION }, -{ "invalid_prepared_statement_definition", ERRCODE_INVALID_PSTATEMENT_DEFINITION }, -{ "invalid_schema_definition", ERRCODE_INVALID_SCHEMA_DEFINITION }, -{ "invalid_table_definition", ERRCODE_INVALID_TABLE_DEFINITION }, -{ "invalid_object_definition", ERRCODE_INVALID_OBJECT_DEFINITION }, -{ "with_check_option_violation", ERRCODE_WITH_CHECK_OPTION_VIOLATION }, -{ "insufficient_resources", ERRCODE_INSUFFICIENT_RESOURCES }, -{ "disk_full", ERRCODE_DISK_FULL }, -{ "out_of_memory", ERRCODE_OUT_OF_MEMORY }, -{ "too_many_connections", ERRCODE_TOO_MANY_CONNECTIONS }, -{ "program_limit_exceeded", ERRCODE_PROGRAM_LIMIT_EXCEEDED }, -{ "statement_too_complex", ERRCODE_STATEMENT_TOO_COMPLEX }, -{ "too_many_columns", ERRCODE_TOO_MANY_COLUMNS }, -{ "too_many_arguments", ERRCODE_TOO_MANY_ARGUMENTS }, -{ "object_not_in_prerequisite_state", ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE }, -{ "object_in_use", ERRCODE_OBJECT_IN_USE }, -{ "cant_change_runtime_param", ERRCODE_CANT_CHANGE_RUNTIME_PARAM }, -{ "operator_intervention", ERRCODE_OPERATOR_INTERVENTION }, -{ "query_canceled", ERRCODE_QUERY_CANCELED }, -{ "admin_shutdown", ERRCODE_ADMIN_SHUTDOWN }, -{ "crash_shutdown", ERRCODE_CRASH_SHUTDOWN }, -{ "cannot_connect_now", ERRCODE_CANNOT_CONNECT_NOW }, -{ "io_error", ERRCODE_IO_ERROR }, -{ "undefined_file", ERRCODE_UNDEFINED_FILE }, -{ "duplicate_file", ERRCODE_DUPLICATE_FILE }, -{ "config_file_error", ERRCODE_CONFIG_FILE_ERROR }, -{ "lock_file_exists", ERRCODE_LOCK_FILE_EXISTS }, -{ "plpgsql_error", ERRCODE_PLPGSQL_ERROR }, -{ "raise_exception", ERRCODE_RAISE_EXCEPTION }, -{ "internal_error", ERRCODE_INTERNAL_ERROR }, -{ "data_corrupted", ERRCODE_DATA_CORRUPTED }, -{ "index_corrupted", ERRCODE_INDEX_CORRUPTED }, +{ + "sql_statement_not_yet_complete", ERRCODE_SQL_STATEMENT_NOT_YET_COMPLETE +}, + +{ + "connection_exception", ERRCODE_CONNECTION_EXCEPTION +}, + +{ + "connection_does_not_exist", ERRCODE_CONNECTION_DOES_NOT_EXIST +}, + +{ + "connection_failure", ERRCODE_CONNECTION_FAILURE +}, + +{ + "sqlclient_unable_to_establish_sqlconnection", ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION +}, + +{ + "sqlserver_rejected_establishment_of_sqlconnection", ERRCODE_SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION +}, + +{ + "transaction_resolution_unknown", ERRCODE_TRANSACTION_RESOLUTION_UNKNOWN +}, + +{ + "protocol_violation", ERRCODE_PROTOCOL_VIOLATION +}, + +{ + "triggered_action_exception", ERRCODE_TRIGGERED_ACTION_EXCEPTION +}, + +{ + "feature_not_supported", ERRCODE_FEATURE_NOT_SUPPORTED +}, + +{ + "invalid_transaction_initiation", ERRCODE_INVALID_TRANSACTION_INITIATION +}, + +{ + "locator_exception", ERRCODE_LOCATOR_EXCEPTION +}, + +{ + "invalid_locator_specification", ERRCODE_L_E_INVALID_SPECIFICATION +}, + +{ + "invalid_grantor", ERRCODE_INVALID_GRANTOR +}, + +{ + "invalid_grant_operation", ERRCODE_INVALID_GRANT_OPERATION +}, + +{ + "invalid_role_specification", ERRCODE_INVALID_ROLE_SPECIFICATION +}, + +{ + "cardinality_violation", ERRCODE_CARDINALITY_VIOLATION +}, + +{ + "data_exception", ERRCODE_DATA_EXCEPTION +}, + +{ + "array_element_error", ERRCODE_ARRAY_ELEMENT_ERROR +}, + +{ + "array_subscript_error", ERRCODE_ARRAY_SUBSCRIPT_ERROR +}, + +{ + "character_not_in_repertoire", ERRCODE_CHARACTER_NOT_IN_REPERTOIRE +}, + +{ + "datetime_field_overflow", ERRCODE_DATETIME_FIELD_OVERFLOW +}, + +{ + "datetime_value_out_of_range", ERRCODE_DATETIME_VALUE_OUT_OF_RANGE +}, + +{ + "division_by_zero", ERRCODE_DIVISION_BY_ZERO +}, + +{ + "error_in_assignment", ERRCODE_ERROR_IN_ASSIGNMENT +}, + +{ + "escape_character_conflict", ERRCODE_ESCAPE_CHARACTER_CONFLICT +}, + +{ + "indicator_overflow", ERRCODE_INDICATOR_OVERFLOW +}, + +{ + "interval_field_overflow", ERRCODE_INTERVAL_FIELD_OVERFLOW +}, + +{ + "invalid_argument_for_logarithm", ERRCODE_INVALID_ARGUMENT_FOR_LOG +}, + +{ + "invalid_argument_for_power_function", ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION +}, + +{ + "invalid_argument_for_width_bucket_function", ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION +}, + +{ + "invalid_character_value_for_cast", ERRCODE_INVALID_CHARACTER_VALUE_FOR_CAST +}, + +{ + "invalid_datetime_format", ERRCODE_INVALID_DATETIME_FORMAT +}, + +{ + "invalid_escape_character", ERRCODE_INVALID_ESCAPE_CHARACTER +}, + +{ + "invalid_escape_octet", ERRCODE_INVALID_ESCAPE_OCTET +}, + +{ + "invalid_escape_sequence", ERRCODE_INVALID_ESCAPE_SEQUENCE +}, + +{ + "invalid_indicator_parameter_value", ERRCODE_INVALID_INDICATOR_PARAMETER_VALUE +}, + +{ + "invalid_limit_value", ERRCODE_INVALID_LIMIT_VALUE +}, + +{ + "invalid_parameter_value", ERRCODE_INVALID_PARAMETER_VALUE +}, + +{ + "invalid_regular_expression", ERRCODE_INVALID_REGULAR_EXPRESSION +}, + +{ + "invalid_time_zone_displacement_value", ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE +}, + +{ + "invalid_use_of_escape_character", ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER +}, + +{ + "most_specific_type_mismatch", ERRCODE_MOST_SPECIFIC_TYPE_MISMATCH +}, + +{ + "null_value_not_allowed", ERRCODE_NULL_VALUE_NOT_ALLOWED +}, + +{ + "null_value_no_indicator_parameter", ERRCODE_NULL_VALUE_NO_INDICATOR_PARAMETER +}, + +{ + "numeric_value_out_of_range", ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE +}, + +{ + "string_data_length_mismatch", ERRCODE_STRING_DATA_LENGTH_MISMATCH +}, + +{ + "string_data_right_truncation", ERRCODE_STRING_DATA_RIGHT_TRUNCATION +}, + +{ + "substring_error", ERRCODE_SUBSTRING_ERROR +}, + +{ + "trim_error", ERRCODE_TRIM_ERROR +}, + +{ + "unterminated_c_string", ERRCODE_UNTERMINATED_C_STRING +}, + +{ + "zero_length_character_string", ERRCODE_ZERO_LENGTH_CHARACTER_STRING +}, + +{ + "floating_point_exception", ERRCODE_FLOATING_POINT_EXCEPTION +}, + +{ + "invalid_text_representation", ERRCODE_INVALID_TEXT_REPRESENTATION +}, + +{ + "invalid_binary_representation", ERRCODE_INVALID_BINARY_REPRESENTATION +}, + +{ + "bad_copy_file_format", ERRCODE_BAD_COPY_FILE_FORMAT +}, + +{ + "untranslatable_character", ERRCODE_UNTRANSLATABLE_CHARACTER +}, + +{ + "integrity_constraint_violation", ERRCODE_INTEGRITY_CONSTRAINT_VIOLATION +}, + +{ + "restrict_violation", ERRCODE_RESTRICT_VIOLATION +}, + +{ + "not_null_violation", ERRCODE_NOT_NULL_VIOLATION +}, + +{ + "foreign_key_violation", ERRCODE_FOREIGN_KEY_VIOLATION +}, + +{ + "unique_violation", ERRCODE_UNIQUE_VIOLATION +}, + +{ + "check_violation", ERRCODE_CHECK_VIOLATION +}, + +{ + "invalid_cursor_state", ERRCODE_INVALID_CURSOR_STATE +}, + +{ + "invalid_transaction_state", ERRCODE_INVALID_TRANSACTION_STATE +}, + +{ + "active_sql_transaction", ERRCODE_ACTIVE_SQL_TRANSACTION +}, + +{ + "branch_transaction_already_active", ERRCODE_BRANCH_TRANSACTION_ALREADY_ACTIVE +}, + +{ + "held_cursor_requires_same_isolation_level", ERRCODE_HELD_CURSOR_REQUIRES_SAME_ISOLATION_LEVEL +}, + +{ + "inappropriate_access_mode_for_branch_transaction", ERRCODE_INAPPROPRIATE_ACCESS_MODE_FOR_BRANCH_TRANSACTION +}, + +{ + "inappropriate_isolation_level_for_branch_transaction", ERRCODE_INAPPROPRIATE_ISOLATION_LEVEL_FOR_BRANCH_TRANSACTION +}, + +{ + "no_active_sql_transaction_for_branch_transaction", ERRCODE_NO_ACTIVE_SQL_TRANSACTION_FOR_BRANCH_TRANSACTION +}, + +{ + "read_only_sql_transaction", ERRCODE_READ_ONLY_SQL_TRANSACTION +}, + +{ + "schema_and_data_statement_mixing_not_supported", ERRCODE_SCHEMA_AND_DATA_STATEMENT_MIXING_NOT_SUPPORTED +}, + +{ + "no_active_sql_transaction", ERRCODE_NO_ACTIVE_SQL_TRANSACTION +}, + +{ + "in_failed_sql_transaction", ERRCODE_IN_FAILED_SQL_TRANSACTION +}, + +{ + "invalid_sql_statement_name", ERRCODE_INVALID_SQL_STATEMENT_NAME +}, + +{ + "triggered_data_change_violation", ERRCODE_TRIGGERED_DATA_CHANGE_VIOLATION +}, + +{ + "invalid_authorization_specification", ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION +}, + +{ + "dependent_privilege_descriptors_still_exist", ERRCODE_DEPENDENT_PRIVILEGE_DESCRIPTORS_STILL_EXIST +}, + +{ + "dependent_objects_still_exist", ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST +}, + +{ + "invalid_transaction_termination", ERRCODE_INVALID_TRANSACTION_TERMINATION +}, + +{ + "sql_routine_exception", ERRCODE_SQL_ROUTINE_EXCEPTION +}, + +{ + "function_executed_no_return_statement", ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT +}, + +{ + "modifying_sql_data_not_permitted", ERRCODE_S_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED +}, + +{ + "prohibited_sql_statement_attempted", ERRCODE_S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED +}, + +{ + "reading_sql_data_not_permitted", ERRCODE_S_R_E_READING_SQL_DATA_NOT_PERMITTED +}, + +{ + "invalid_cursor_name", ERRCODE_INVALID_CURSOR_NAME +}, + +{ + "external_routine_exception", ERRCODE_EXTERNAL_ROUTINE_EXCEPTION +}, + +{ + "containing_sql_not_permitted", ERRCODE_E_R_E_CONTAINING_SQL_NOT_PERMITTED +}, + +{ + "modifying_sql_data_not_permitted", ERRCODE_E_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED +}, + +{ + "prohibited_sql_statement_attempted", ERRCODE_E_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED +}, + +{ + "reading_sql_data_not_permitted", ERRCODE_E_R_E_READING_SQL_DATA_NOT_PERMITTED +}, + +{ + "external_routine_invocation_exception", ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION +}, + +{ + "invalid_sqlstate_returned", ERRCODE_E_R_I_E_INVALID_SQLSTATE_RETURNED +}, + +{ + "null_value_not_allowed", ERRCODE_E_R_I_E_NULL_VALUE_NOT_ALLOWED +}, + +{ + "trigger_protocol_violated", ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED +}, + +{ + "srf_protocol_violated", ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED +}, + +{ + "savepoint_exception", ERRCODE_SAVEPOINT_EXCEPTION +}, + +{ + "invalid_savepoint_specification", ERRCODE_S_E_INVALID_SPECIFICATION +}, + +{ + "invalid_catalog_name", ERRCODE_INVALID_CATALOG_NAME +}, + +{ + "invalid_schema_name", ERRCODE_INVALID_SCHEMA_NAME +}, + +{ + "transaction_rollback", ERRCODE_TRANSACTION_ROLLBACK +}, + +{ + "transaction_integrity_constraint_violation", ERRCODE_T_R_INTEGRITY_CONSTRAINT_VIOLATION +}, + +{ + "serialization_failure", ERRCODE_T_R_SERIALIZATION_FAILURE +}, + +{ + "statement_completion_unknown", ERRCODE_T_R_STATEMENT_COMPLETION_UNKNOWN +}, + +{ + "deadlock_detected", ERRCODE_T_R_DEADLOCK_DETECTED +}, + +{ + "syntax_error_or_access_rule_violation", ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION +}, + +{ + "syntax_error", ERRCODE_SYNTAX_ERROR +}, + +{ + "insufficient_privilege", ERRCODE_INSUFFICIENT_PRIVILEGE +}, + +{ + "cannot_coerce", ERRCODE_CANNOT_COERCE +}, + +{ + "grouping_error", ERRCODE_GROUPING_ERROR +}, + +{ + "invalid_foreign_key", ERRCODE_INVALID_FOREIGN_KEY +}, + +{ + "invalid_name", ERRCODE_INVALID_NAME +}, + +{ + "name_too_long", ERRCODE_NAME_TOO_LONG +}, + +{ + "reserved_name", ERRCODE_RESERVED_NAME +}, + +{ + "datatype_mismatch", ERRCODE_DATATYPE_MISMATCH +}, + +{ + "indeterminate_datatype", ERRCODE_INDETERMINATE_DATATYPE +}, + +{ + "wrong_object_type", ERRCODE_WRONG_OBJECT_TYPE +}, + +{ + "undefined_column", ERRCODE_UNDEFINED_COLUMN +}, + +{ + "undefined_cursor", ERRCODE_UNDEFINED_CURSOR +}, + +{ + "undefined_database", ERRCODE_UNDEFINED_DATABASE +}, + +{ + "undefined_function", ERRCODE_UNDEFINED_FUNCTION +}, + +{ + "undefined_pstatement", ERRCODE_UNDEFINED_PSTATEMENT +}, + +{ + "undefined_schema", ERRCODE_UNDEFINED_SCHEMA +}, + +{ + "undefined_table", ERRCODE_UNDEFINED_TABLE +}, + +{ + "undefined_parameter", ERRCODE_UNDEFINED_PARAMETER +}, + +{ + "undefined_object", ERRCODE_UNDEFINED_OBJECT +}, + +{ + "duplicate_column", ERRCODE_DUPLICATE_COLUMN +}, + +{ + "duplicate_cursor", ERRCODE_DUPLICATE_CURSOR +}, + +{ + "duplicate_database", ERRCODE_DUPLICATE_DATABASE +}, + +{ + "duplicate_function", ERRCODE_DUPLICATE_FUNCTION +}, + +{ + "duplicate_prepared_statement", ERRCODE_DUPLICATE_PSTATEMENT +}, + +{ + "duplicate_schema", ERRCODE_DUPLICATE_SCHEMA +}, + +{ + "duplicate_table", ERRCODE_DUPLICATE_TABLE +}, + +{ + "duplicate_alias", ERRCODE_DUPLICATE_ALIAS +}, + +{ + "duplicate_object", ERRCODE_DUPLICATE_OBJECT +}, + +{ + "ambiguous_column", ERRCODE_AMBIGUOUS_COLUMN +}, + +{ + "ambiguous_function", ERRCODE_AMBIGUOUS_FUNCTION +}, + +{ + "ambiguous_parameter", ERRCODE_AMBIGUOUS_PARAMETER +}, + +{ + "ambiguous_alias", ERRCODE_AMBIGUOUS_ALIAS +}, + +{ + "invalid_column_reference", ERRCODE_INVALID_COLUMN_REFERENCE +}, + +{ + "invalid_column_definition", ERRCODE_INVALID_COLUMN_DEFINITION +}, + +{ + "invalid_cursor_definition", ERRCODE_INVALID_CURSOR_DEFINITION +}, + +{ + "invalid_database_definition", ERRCODE_INVALID_DATABASE_DEFINITION +}, + +{ + "invalid_function_definition", ERRCODE_INVALID_FUNCTION_DEFINITION +}, + +{ + "invalid_prepared_statement_definition", ERRCODE_INVALID_PSTATEMENT_DEFINITION +}, + +{ + "invalid_schema_definition", ERRCODE_INVALID_SCHEMA_DEFINITION +}, + +{ + "invalid_table_definition", ERRCODE_INVALID_TABLE_DEFINITION +}, + +{ + "invalid_object_definition", ERRCODE_INVALID_OBJECT_DEFINITION +}, + +{ + "with_check_option_violation", ERRCODE_WITH_CHECK_OPTION_VIOLATION +}, + +{ + "insufficient_resources", ERRCODE_INSUFFICIENT_RESOURCES +}, + +{ + "disk_full", ERRCODE_DISK_FULL +}, + +{ + "out_of_memory", ERRCODE_OUT_OF_MEMORY +}, + +{ + "too_many_connections", ERRCODE_TOO_MANY_CONNECTIONS +}, + +{ + "program_limit_exceeded", ERRCODE_PROGRAM_LIMIT_EXCEEDED +}, + +{ + "statement_too_complex", ERRCODE_STATEMENT_TOO_COMPLEX +}, + +{ + "too_many_columns", ERRCODE_TOO_MANY_COLUMNS +}, + +{ + "too_many_arguments", ERRCODE_TOO_MANY_ARGUMENTS +}, + +{ + "object_not_in_prerequisite_state", ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE +}, + +{ + "object_in_use", ERRCODE_OBJECT_IN_USE +}, + +{ + "cant_change_runtime_param", ERRCODE_CANT_CHANGE_RUNTIME_PARAM +}, + +{ + "operator_intervention", ERRCODE_OPERATOR_INTERVENTION +}, + +{ + "query_canceled", ERRCODE_QUERY_CANCELED +}, + +{ + "admin_shutdown", ERRCODE_ADMIN_SHUTDOWN +}, + +{ + "crash_shutdown", ERRCODE_CRASH_SHUTDOWN +}, + +{ + "cannot_connect_now", ERRCODE_CANNOT_CONNECT_NOW +}, + +{ + "io_error", ERRCODE_IO_ERROR +}, + +{ + "undefined_file", ERRCODE_UNDEFINED_FILE +}, + +{ + "duplicate_file", ERRCODE_DUPLICATE_FILE +}, + +{ + "config_file_error", ERRCODE_CONFIG_FILE_ERROR +}, + +{ + "lock_file_exists", ERRCODE_LOCK_FILE_EXISTS +}, + +{ + "plpgsql_error", ERRCODE_PLPGSQL_ERROR +}, + +{ + "raise_exception", ERRCODE_RAISE_EXCEPTION +}, + +{ + "internal_error", ERRCODE_INTERNAL_ERROR +}, + +{ + "data_corrupted", ERRCODE_DATA_CORRUPTED +}, + +{ + "index_corrupted", ERRCODE_INDEX_CORRUPTED +}, diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h index 346f82c5c83..ce49eef9eee 100644 --- a/src/pl/plpgsql/src/plpgsql.h +++ b/src/pl/plpgsql/src/plpgsql.h @@ -3,7 +3,7 @@ * procedural language * * IDENTIFICATION - * $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.51 2004/08/20 22:00:14 tgl Exp $ + * $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.52 2004/08/29 05:07:01 momjian Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -197,7 +197,7 @@ typedef struct PLpgSQL_expr void *plan; Oid *plan_argtypes; /* fields for "simple expression" fast-path execution: */ - Expr *expr_simple_expr; /* NULL means not a simple expr */ + Expr *expr_simple_expr; /* NULL means not a simple expr */ Oid expr_simple_type; /* if expr is simple AND in use in current xact, these fields are set: */ ExprState *expr_simple_state; @@ -339,7 +339,8 @@ typedef struct typedef struct { /* List of WHEN clauses */ - int exceptions_alloc; /* XXX this oughta just be a List ... */ + int exceptions_alloc; /* XXX this oughta just be a List + * ... */ int exceptions_used; PLpgSQL_exception **exceptions; } PLpgSQL_exceptions; @@ -552,10 +553,10 @@ typedef struct PLpgSQL_func_hashkey Oid funcOid; /* - * For a trigger function, the OID of the relation triggered on is part - * of the hashkey --- we want to compile the trigger separately for each - * relation it is used with, in case the rowtype is different. Zero if - * not called as a trigger. + * For a trigger function, the OID of the relation triggered on is + * part of the hashkey --- we want to compile the trigger separately + * for each relation it is used with, in case the rowtype is + * different. Zero if not called as a trigger. */ Oid trigrelOid; @@ -669,7 +670,7 @@ extern PLpgSQL_function *plpgsql_curr_compile; * ---------- */ extern PLpgSQL_function *plpgsql_compile(FunctionCallInfo fcinfo, - bool forValidator); + bool forValidator); extern int plpgsql_parse_word(char *word); extern int plpgsql_parse_dblword(char *word); extern int plpgsql_parse_tripword(char *word); @@ -681,10 +682,10 @@ extern int plpgsql_parse_dblwordrowtype(char *word); extern PLpgSQL_type *plpgsql_parse_datatype(const char *string); extern PLpgSQL_type *plpgsql_build_datatype(Oid typeOid, int32 typmod); extern PLpgSQL_variable *plpgsql_build_variable(char *refname, int lineno, - PLpgSQL_type *dtype, - bool add2namespace); + PLpgSQL_type * dtype, + bool add2namespace); extern PLpgSQL_condition *plpgsql_parse_err_condition(char *condname); -extern void plpgsql_adddatum(PLpgSQL_datum *new); +extern void plpgsql_adddatum(PLpgSQL_datum * new); extern int plpgsql_add_initdatums(int **varnos); extern void plpgsql_HashTableInit(void); diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c index 07eed862477..45340d0ed89 100644 --- a/src/pl/plpython/plpython.c +++ b/src/pl/plpython/plpython.c @@ -29,7 +29,7 @@ * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * * IDENTIFICATION - * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.53 2004/08/05 03:10:29 joe Exp $ + * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.54 2004/08/29 05:07:01 momjian Exp $ * ********************************************************************* */ @@ -115,12 +115,10 @@ typedef struct PLyTypeInfo PLyTypeInput in; PLyTypeOutput out; int is_rowtype; + /* - * is_rowtype can be: - * -1 not known yet (initial state) - * 0 scalar datatype - * 1 rowtype - * 2 rowtype, but I/O functions not set up yet + * is_rowtype can be: -1 not known yet (initial state) 0 scalar + * datatype 1 rowtype 2 rowtype, but I/O functions not set up yet */ } PLyTypeInfo; @@ -161,7 +159,7 @@ typedef struct PLyResultObject { PyObject_HEAD /* HeapTuple *tuples; */ - PyObject *nrows; /* number of rows returned by query */ + PyObject * nrows; /* number of rows returned by query */ PyObject *rows; /* data rows, or None if no data returned */ PyObject *status; /* query status, SPI_OK_*, or SPI_ERR_* */ } PLyResultObject; @@ -225,7 +223,7 @@ static HeapTuple PLy_modify_tuple(PLyProcedure *, PyObject *, static PyObject *PLy_procedure_call(PLyProcedure *, char *, PyObject *); static PLyProcedure *PLy_procedure_get(FunctionCallInfo fcinfo, - Oid tgreloid); + Oid tgreloid); static PLyProcedure *PLy_procedure_create(FunctionCallInfo fcinfo, Oid tgreloid, @@ -339,7 +337,7 @@ plpython_call_handler(PG_FUNCTION_ARGS) HeapTuple trv; proc = PLy_procedure_get(fcinfo, - RelationGetRelid(tdata->tg_relation)); + RelationGetRelid(tdata->tg_relation)); trv = PLy_trigger_handler(fcinfo, proc); retval = PointerGetDatum(trv); } @@ -385,52 +383,52 @@ PLy_trigger_handler(FunctionCallInfo fcinfo, PLyProcedure * proc) PG_TRY(); { - plargs = PLy_trigger_build_args(fcinfo, proc, &rv); - plrv = PLy_procedure_call(proc, "TD", plargs); + plargs = PLy_trigger_build_args(fcinfo, proc, &rv); + plrv = PLy_procedure_call(proc, "TD", plargs); - Assert(plrv != NULL); - Assert(!PLy_error_in_progress); + Assert(plrv != NULL); + Assert(!PLy_error_in_progress); - /* - * Disconnect from SPI manager - */ - if (SPI_finish() != SPI_OK_FINISH) - elog(ERROR, "SPI_finish failed"); + /* + * Disconnect from SPI manager + */ + if (SPI_finish() != SPI_OK_FINISH) + elog(ERROR, "SPI_finish failed"); - /* - * return of None means we're happy with the tuple - */ - if (plrv != Py_None) - { - char *srv; + /* + * return of None means we're happy with the tuple + */ + if (plrv != Py_None) + { + char *srv; - if (!PyString_Check(plrv)) - elog(ERROR, "expected trigger to return None or a String"); + if (!PyString_Check(plrv)) + elog(ERROR, "expected trigger to return None or a String"); - srv = PyString_AsString(plrv); - if (pg_strcasecmp(srv, "SKIP") == 0) - rv = NULL; - else if (pg_strcasecmp(srv, "MODIFY") == 0) - { - TriggerData *tdata = (TriggerData *) fcinfo->context; + srv = PyString_AsString(plrv); + if (pg_strcasecmp(srv, "SKIP") == 0) + rv = NULL; + else if (pg_strcasecmp(srv, "MODIFY") == 0) + { + TriggerData *tdata = (TriggerData *) fcinfo->context; - if ((TRIGGER_FIRED_BY_INSERT(tdata->tg_event)) || - (TRIGGER_FIRED_BY_UPDATE(tdata->tg_event))) - rv = PLy_modify_tuple(proc, plargs, tdata, rv); - else - elog(WARNING, "ignoring modified tuple in DELETE trigger"); - } - else if (pg_strcasecmp(srv, "OK") != 0) - { - /* - * hmmm, perhaps they only read the pltcl page, not a - * surprising thing since i've written no documentation, so - * accept a belated OK - */ - elog(ERROR, "expected return to be \"SKIP\" or \"MODIFY\""); + if ((TRIGGER_FIRED_BY_INSERT(tdata->tg_event)) || + (TRIGGER_FIRED_BY_UPDATE(tdata->tg_event))) + rv = PLy_modify_tuple(proc, plargs, tdata, rv); + else + elog(WARNING, "ignoring modified tuple in DELETE trigger"); + } + else if (pg_strcasecmp(srv, "OK") != 0) + { + /* + * hmmm, perhaps they only read the pltcl page, not a + * surprising thing since i've written no documentation, + * so accept a belated OK + */ + elog(ERROR, "expected return to be \"SKIP\" or \"MODIFY\""); + } } } - } PG_CATCH(); { Py_XDECREF(plargs); @@ -472,70 +470,70 @@ PLy_modify_tuple(PLyProcedure * proc, PyObject * pltd, TriggerData *tdata, PG_TRY(); { - if ((plntup = PyDict_GetItemString(pltd, "new")) == NULL) - elog(ERROR, "TD[\"new\"] deleted, unable to modify tuple"); - if (!PyDict_Check(plntup)) - elog(ERROR, "TD[\"new\"] is not a dictionary object"); - Py_INCREF(plntup); + if ((plntup = PyDict_GetItemString(pltd, "new")) == NULL) + elog(ERROR, "TD[\"new\"] deleted, unable to modify tuple"); + if (!PyDict_Check(plntup)) + elog(ERROR, "TD[\"new\"] is not a dictionary object"); + Py_INCREF(plntup); - plkeys = PyDict_Keys(plntup); - natts = PyList_Size(plkeys); + plkeys = PyDict_Keys(plntup); + natts = PyList_Size(plkeys); - modattrs = (int *) palloc(natts * sizeof(int)); - modvalues = (Datum *) palloc(natts * sizeof(Datum)); - modnulls = (char *) palloc(natts * sizeof(char)); + modattrs = (int *) palloc(natts * sizeof(int)); + modvalues = (Datum *) palloc(natts * sizeof(Datum)); + modnulls = (char *) palloc(natts * sizeof(char)); - tupdesc = tdata->tg_relation->rd_att; + tupdesc = tdata->tg_relation->rd_att; - for (i = 0; i < natts; i++) - { - char *src; + for (i = 0; i < natts; i++) + { + char *src; - platt = PyList_GetItem(plkeys, i); - if (!PyString_Check(platt)) - elog(ERROR, "attribute name is not a string"); - attn = SPI_fnumber(tupdesc, PyString_AsString(platt)); - if (attn == SPI_ERROR_NOATTRIBUTE) - elog(ERROR, "invalid attribute \"%s\" in tuple", - PyString_AsString(platt)); - atti = attn - 1; + platt = PyList_GetItem(plkeys, i); + if (!PyString_Check(platt)) + elog(ERROR, "attribute name is not a string"); + attn = SPI_fnumber(tupdesc, PyString_AsString(platt)); + if (attn == SPI_ERROR_NOATTRIBUTE) + elog(ERROR, "invalid attribute \"%s\" in tuple", + PyString_AsString(platt)); + atti = attn - 1; - plval = PyDict_GetItem(plntup, platt); - if (plval == NULL) - elog(FATAL, "python interpreter is probably corrupted"); + plval = PyDict_GetItem(plntup, platt); + if (plval == NULL) + elog(FATAL, "python interpreter is probably corrupted"); - Py_INCREF(plval); + Py_INCREF(plval); - modattrs[i] = attn; + modattrs[i] = attn; - if (plval != Py_None && !tupdesc->attrs[atti]->attisdropped) - { - plstr = PyObject_Str(plval); - src = PyString_AsString(plstr); + if (plval != Py_None && !tupdesc->attrs[atti]->attisdropped) + { + plstr = PyObject_Str(plval); + src = PyString_AsString(plstr); - modvalues[i] = FunctionCall3(&proc->result.out.r.atts[atti].typfunc, - CStringGetDatum(src), - ObjectIdGetDatum(proc->result.out.r.atts[atti].typioparam), + modvalues[i] = FunctionCall3(&proc->result.out.r.atts[atti].typfunc, + CStringGetDatum(src), + ObjectIdGetDatum(proc->result.out.r.atts[atti].typioparam), Int32GetDatum(tupdesc->attrs[atti]->atttypmod)); - modnulls[i] = ' '; + modnulls[i] = ' '; - Py_DECREF(plstr); - plstr = NULL; - } - else - { - modvalues[i] = (Datum) 0; - modnulls[i] = 'n'; - } + Py_DECREF(plstr); + plstr = NULL; + } + else + { + modvalues[i] = (Datum) 0; + modnulls[i] = 'n'; + } - Py_DECREF(plval); - plval = NULL; - } + Py_DECREF(plval); + plval = NULL; + } - rtup = SPI_modifytuple(tdata->tg_relation, otup, natts, - modattrs, modvalues, modnulls); - if (rtup == NULL) - elog(ERROR, "SPI_modifytuple failed -- error %d", SPI_result); + rtup = SPI_modifytuple(tdata->tg_relation, otup, natts, + modattrs, modvalues, modnulls); + if (rtup == NULL) + elog(ERROR, "SPI_modifytuple failed -- error %d", SPI_result); } PG_CATCH(); { @@ -583,138 +581,138 @@ PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure * proc, HeapTuple * PG_TRY(); { - pltdata = PyDict_New(); - if (!pltdata) - PLy_elog(ERROR, "could not build arguments for trigger procedure"); + pltdata = PyDict_New(); + if (!pltdata) + PLy_elog(ERROR, "could not build arguments for trigger procedure"); - pltname = PyString_FromString(tdata->tg_trigger->tgname); - PyDict_SetItemString(pltdata, "name", pltname); - Py_DECREF(pltname); + pltname = PyString_FromString(tdata->tg_trigger->tgname); + PyDict_SetItemString(pltdata, "name", pltname); + Py_DECREF(pltname); - stroid = DatumGetCString(DirectFunctionCall1(oidout, + stroid = DatumGetCString(DirectFunctionCall1(oidout, ObjectIdGetDatum(tdata->tg_relation->rd_id))); - pltrelid = PyString_FromString(stroid); - PyDict_SetItemString(pltdata, "relid", pltrelid); - Py_DECREF(pltrelid); - pfree(stroid); - - if (TRIGGER_FIRED_BEFORE(tdata->tg_event)) - pltwhen = PyString_FromString("BEFORE"); - else if (TRIGGER_FIRED_AFTER(tdata->tg_event)) - pltwhen = PyString_FromString("AFTER"); - else - { - elog(ERROR, "unrecognized WHEN tg_event: %u", tdata->tg_event); - pltwhen = NULL; /* keep compiler quiet */ - } - PyDict_SetItemString(pltdata, "when", pltwhen); - Py_DECREF(pltwhen); - - if (TRIGGER_FIRED_FOR_ROW(tdata->tg_event)) - { - pltlevel = PyString_FromString("ROW"); - PyDict_SetItemString(pltdata, "level", pltlevel); - Py_DECREF(pltlevel); + pltrelid = PyString_FromString(stroid); + PyDict_SetItemString(pltdata, "relid", pltrelid); + Py_DECREF(pltrelid); + pfree(stroid); + + if (TRIGGER_FIRED_BEFORE(tdata->tg_event)) + pltwhen = PyString_FromString("BEFORE"); + else if (TRIGGER_FIRED_AFTER(tdata->tg_event)) + pltwhen = PyString_FromString("AFTER"); + else + { + elog(ERROR, "unrecognized WHEN tg_event: %u", tdata->tg_event); + pltwhen = NULL; /* keep compiler quiet */ + } + PyDict_SetItemString(pltdata, "when", pltwhen); + Py_DECREF(pltwhen); - if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event)) + if (TRIGGER_FIRED_FOR_ROW(tdata->tg_event)) { - pltevent = PyString_FromString("INSERT"); + pltlevel = PyString_FromString("ROW"); + PyDict_SetItemString(pltdata, "level", pltlevel); + Py_DECREF(pltlevel); - PyDict_SetItemString(pltdata, "old", Py_None); - pytnew = PLyDict_FromTuple(&(proc->result), tdata->tg_trigtuple, - tdata->tg_relation->rd_att); - PyDict_SetItemString(pltdata, "new", pytnew); - Py_DECREF(pytnew); - *rv = tdata->tg_trigtuple; + if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event)) + { + pltevent = PyString_FromString("INSERT"); + + PyDict_SetItemString(pltdata, "old", Py_None); + pytnew = PLyDict_FromTuple(&(proc->result), tdata->tg_trigtuple, + tdata->tg_relation->rd_att); + PyDict_SetItemString(pltdata, "new", pytnew); + Py_DECREF(pytnew); + *rv = tdata->tg_trigtuple; + } + else if (TRIGGER_FIRED_BY_DELETE(tdata->tg_event)) + { + pltevent = PyString_FromString("DELETE"); + + PyDict_SetItemString(pltdata, "new", Py_None); + pytold = PLyDict_FromTuple(&(proc->result), tdata->tg_trigtuple, + tdata->tg_relation->rd_att); + PyDict_SetItemString(pltdata, "old", pytold); + Py_DECREF(pytold); + *rv = tdata->tg_trigtuple; + } + else if (TRIGGER_FIRED_BY_UPDATE(tdata->tg_event)) + { + pltevent = PyString_FromString("UPDATE"); + + pytnew = PLyDict_FromTuple(&(proc->result), tdata->tg_newtuple, + tdata->tg_relation->rd_att); + PyDict_SetItemString(pltdata, "new", pytnew); + Py_DECREF(pytnew); + pytold = PLyDict_FromTuple(&(proc->result), tdata->tg_trigtuple, + tdata->tg_relation->rd_att); + PyDict_SetItemString(pltdata, "old", pytold); + Py_DECREF(pytold); + *rv = tdata->tg_newtuple; + } + else + { + elog(ERROR, "unrecognized OP tg_event: %u", tdata->tg_event); + pltevent = NULL; /* keep compiler quiet */ + } + + PyDict_SetItemString(pltdata, "event", pltevent); + Py_DECREF(pltevent); } - else if (TRIGGER_FIRED_BY_DELETE(tdata->tg_event)) + else if (TRIGGER_FIRED_FOR_STATEMENT(tdata->tg_event)) { - pltevent = PyString_FromString("DELETE"); + pltlevel = PyString_FromString("STATEMENT"); + PyDict_SetItemString(pltdata, "level", pltlevel); + Py_DECREF(pltlevel); + PyDict_SetItemString(pltdata, "old", Py_None); PyDict_SetItemString(pltdata, "new", Py_None); - pytold = PLyDict_FromTuple(&(proc->result), tdata->tg_trigtuple, - tdata->tg_relation->rd_att); - PyDict_SetItemString(pltdata, "old", pytold); - Py_DECREF(pytold); - *rv = tdata->tg_trigtuple; - } - else if (TRIGGER_FIRED_BY_UPDATE(tdata->tg_event)) - { - pltevent = PyString_FromString("UPDATE"); - - pytnew = PLyDict_FromTuple(&(proc->result), tdata->tg_newtuple, - tdata->tg_relation->rd_att); - PyDict_SetItemString(pltdata, "new", pytnew); - Py_DECREF(pytnew); - pytold = PLyDict_FromTuple(&(proc->result), tdata->tg_trigtuple, - tdata->tg_relation->rd_att); - PyDict_SetItemString(pltdata, "old", pytold); - Py_DECREF(pytold); - *rv = tdata->tg_newtuple; + *rv = NULL; + + if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event)) + pltevent = PyString_FromString("INSERT"); + else if (TRIGGER_FIRED_BY_DELETE(tdata->tg_event)) + pltevent = PyString_FromString("DELETE"); + else if (TRIGGER_FIRED_BY_UPDATE(tdata->tg_event)) + pltevent = PyString_FromString("UPDATE"); + else + { + elog(ERROR, "unrecognized OP tg_event: %u", tdata->tg_event); + pltevent = NULL; /* keep compiler quiet */ + } + + PyDict_SetItemString(pltdata, "event", pltevent); + Py_DECREF(pltevent); } else - { - elog(ERROR, "unrecognized OP tg_event: %u", tdata->tg_event); - pltevent = NULL; /* keep compiler quiet */ - } + elog(ERROR, "unrecognized LEVEL tg_event: %u", tdata->tg_event); - PyDict_SetItemString(pltdata, "event", pltevent); - Py_DECREF(pltevent); - } - else if (TRIGGER_FIRED_FOR_STATEMENT(tdata->tg_event)) - { - pltlevel = PyString_FromString("STATEMENT"); - PyDict_SetItemString(pltdata, "level", pltlevel); - Py_DECREF(pltlevel); - - PyDict_SetItemString(pltdata, "old", Py_None); - PyDict_SetItemString(pltdata, "new", Py_None); - *rv = NULL; - - if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event)) - pltevent = PyString_FromString("INSERT"); - else if (TRIGGER_FIRED_BY_DELETE(tdata->tg_event)) - pltevent = PyString_FromString("DELETE"); - else if (TRIGGER_FIRED_BY_UPDATE(tdata->tg_event)) - pltevent = PyString_FromString("UPDATE"); - else + if (tdata->tg_trigger->tgnargs) { - elog(ERROR, "unrecognized OP tg_event: %u", tdata->tg_event); - pltevent = NULL; /* keep compiler quiet */ - } - - PyDict_SetItemString(pltdata, "event", pltevent); - Py_DECREF(pltevent); - } - else - elog(ERROR, "unrecognized LEVEL tg_event: %u", tdata->tg_event); + /* + * all strings... + */ + int i; + PyObject *pltarg; - if (tdata->tg_trigger->tgnargs) - { - /* - * all strings... - */ - int i; - PyObject *pltarg; + pltargs = PyList_New(tdata->tg_trigger->tgnargs); + for (i = 0; i < tdata->tg_trigger->tgnargs; i++) + { + pltarg = PyString_FromString(tdata->tg_trigger->tgargs[i]); - pltargs = PyList_New(tdata->tg_trigger->tgnargs); - for (i = 0; i < tdata->tg_trigger->tgnargs; i++) + /* + * stolen, don't Py_DECREF + */ + PyList_SetItem(pltargs, i, pltarg); + } + } + else { - pltarg = PyString_FromString(tdata->tg_trigger->tgargs[i]); - - /* - * stolen, don't Py_DECREF - */ - PyList_SetItem(pltargs, i, pltarg); + Py_INCREF(Py_None); + pltargs = Py_None; } - } - else - { - Py_INCREF(Py_None); - pltargs = Py_None; - } - PyDict_SetItemString(pltdata, "args", pltargs); - Py_DECREF(pltargs); + PyDict_SetItemString(pltdata, "args", pltargs); + Py_DECREF(pltargs); } PG_CATCH(); { @@ -741,39 +739,39 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure * proc) PG_TRY(); { - plargs = PLy_function_build_args(fcinfo, proc); - plrv = PLy_procedure_call(proc, "args", plargs); + plargs = PLy_function_build_args(fcinfo, proc); + plrv = PLy_procedure_call(proc, "args", plargs); - Assert(plrv != NULL); - Assert(!PLy_error_in_progress); + Assert(plrv != NULL); + Assert(!PLy_error_in_progress); - /* - * Disconnect from SPI manager and then create the return values datum - * (if the input function does a palloc for it this must not be - * allocated in the SPI memory context because SPI_finish would free - * it). - */ - if (SPI_finish() != SPI_OK_FINISH) - elog(ERROR, "SPI_finish failed"); + /* + * Disconnect from SPI manager and then create the return values + * datum (if the input function does a palloc for it this must not + * be allocated in the SPI memory context because SPI_finish would + * free it). + */ + if (SPI_finish() != SPI_OK_FINISH) + elog(ERROR, "SPI_finish failed"); - /* - * convert the python PyObject to a postgresql Datum - */ - if (plrv == Py_None) - { - fcinfo->isnull = true; - rv = (Datum) NULL; - } - else - { - fcinfo->isnull = false; - plrv_so = PyObject_Str(plrv); - plrv_sc = PyString_AsString(plrv_so); - rv = FunctionCall3(&proc->result.out.d.typfunc, - PointerGetDatum(plrv_sc), - ObjectIdGetDatum(proc->result.out.d.typioparam), - Int32GetDatum(-1)); - } + /* + * convert the python PyObject to a postgresql Datum + */ + if (plrv == Py_None) + { + fcinfo->isnull = true; + rv = (Datum) NULL; + } + else + { + fcinfo->isnull = false; + plrv_so = PyObject_Str(plrv); + plrv_sc = PyString_AsString(plrv_so); + rv = FunctionCall3(&proc->result.out.d.typfunc, + PointerGetDatum(plrv_sc), + ObjectIdGetDatum(proc->result.out.d.typioparam), + Int32GetDatum(-1)); + } } PG_CATCH(); @@ -807,12 +805,12 @@ PLy_procedure_call(PLyProcedure * proc, char *kargs, PyObject * vargs) PLy_last_procedure = current; /* - * If there was an error in a PG callback, propagate that - * no matter what Python claims about its success. + * If there was an error in a PG callback, propagate that no matter + * what Python claims about its success. */ if (PLy_error_in_progress) { - ErrorData *edata = PLy_error_in_progress; + ErrorData *edata = PLy_error_in_progress; PLy_error_in_progress = NULL; ReThrowError(edata); @@ -836,68 +834,68 @@ PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure * proc) PG_TRY(); { - args = PyList_New(proc->nargs); - for (i = 0; i < proc->nargs; i++) - { - if (proc->args[i].is_rowtype > 0) + args = PyList_New(proc->nargs); + for (i = 0; i < proc->nargs; i++) { - if (fcinfo->argnull[i]) - arg = NULL; - else + if (proc->args[i].is_rowtype > 0) { - HeapTupleHeader td; - Oid tupType; - int32 tupTypmod; - TupleDesc tupdesc; - HeapTupleData tmptup; - - td = DatumGetHeapTupleHeader(fcinfo->arg[i]); - /* Extract rowtype info and find a tupdesc */ - tupType = HeapTupleHeaderGetTypeId(td); - tupTypmod = HeapTupleHeaderGetTypMod(td); - tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod); - - /* Set up I/O funcs if not done yet */ - if (proc->args[i].is_rowtype != 1) - PLy_input_tuple_funcs(&(proc->args[i]), tupdesc); - - /* Build a temporary HeapTuple control structure */ - tmptup.t_len = HeapTupleHeaderGetDatumLength(td); - tmptup.t_data = td; - - arg = PLyDict_FromTuple(&(proc->args[i]), &tmptup, tupdesc); + if (fcinfo->argnull[i]) + arg = NULL; + else + { + HeapTupleHeader td; + Oid tupType; + int32 tupTypmod; + TupleDesc tupdesc; + HeapTupleData tmptup; + + td = DatumGetHeapTupleHeader(fcinfo->arg[i]); + /* Extract rowtype info and find a tupdesc */ + tupType = HeapTupleHeaderGetTypeId(td); + tupTypmod = HeapTupleHeaderGetTypMod(td); + tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod); + + /* Set up I/O funcs if not done yet */ + if (proc->args[i].is_rowtype != 1) + PLy_input_tuple_funcs(&(proc->args[i]), tupdesc); + + /* Build a temporary HeapTuple control structure */ + tmptup.t_len = HeapTupleHeaderGetDatumLength(td); + tmptup.t_data = td; + + arg = PLyDict_FromTuple(&(proc->args[i]), &tmptup, tupdesc); + } } - } - else - { - if (fcinfo->argnull[i]) - arg = NULL; else { - char *ct; - Datum dt; - - dt = FunctionCall3(&(proc->args[i].in.d.typfunc), - fcinfo->arg[i], - ObjectIdGetDatum(proc->args[i].in.d.typioparam), - Int32GetDatum(-1)); - ct = DatumGetCString(dt); - arg = (proc->args[i].in.d.func) (ct); - pfree(ct); + if (fcinfo->argnull[i]) + arg = NULL; + else + { + char *ct; + Datum dt; + + dt = FunctionCall3(&(proc->args[i].in.d.typfunc), + fcinfo->arg[i], + ObjectIdGetDatum(proc->args[i].in.d.typioparam), + Int32GetDatum(-1)); + ct = DatumGetCString(dt); + arg = (proc->args[i].in.d.func) (ct); + pfree(ct); + } } - } - if (arg == NULL) - { - Py_INCREF(Py_None); - arg = Py_None; - } + if (arg == NULL) + { + Py_INCREF(Py_None); + arg = Py_None; + } - /* - * FIXME -- error check this - */ - PyList_SetItem(args, i, arg); - } + /* + * FIXME -- error check this + */ + PyList_SetItem(args, i, arg); + } } PG_CATCH(); { @@ -917,7 +915,7 @@ PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure * proc) */ /* PLy_procedure_get: returns a cached PLyProcedure, or creates, stores and - * returns a new PLyProcedure. fcinfo is the call info, tgreloid is the + * returns a new PLyProcedure. fcinfo is the call info, tgreloid is the * relation OID when calling a trigger, or InvalidOid (zero) for ordinary * function calls. */ @@ -1016,89 +1014,90 @@ PLy_procedure_create(FunctionCallInfo fcinfo, Oid tgreloid, PG_TRY(); { - /* - * get information required for output conversion of the return value, - * but only if this isn't a trigger. - */ - if (!CALLED_AS_TRIGGER(fcinfo)) - { - HeapTuple rvTypeTup; - Form_pg_type rvTypeStruct; + /* + * get information required for output conversion of the return + * value, but only if this isn't a trigger. + */ + if (!CALLED_AS_TRIGGER(fcinfo)) + { + HeapTuple rvTypeTup; + Form_pg_type rvTypeStruct; - rvTypeTup = SearchSysCache(TYPEOID, + rvTypeTup = SearchSysCache(TYPEOID, ObjectIdGetDatum(procStruct->prorettype), - 0, 0, 0); - if (!HeapTupleIsValid(rvTypeTup)) - elog(ERROR, "cache lookup failed for type %u", - procStruct->prorettype); + 0, 0, 0); + if (!HeapTupleIsValid(rvTypeTup)) + elog(ERROR, "cache lookup failed for type %u", + procStruct->prorettype); + + rvTypeStruct = (Form_pg_type) GETSTRUCT(rvTypeTup); + if (rvTypeStruct->typtype != 'c') + PLy_output_datum_func(&proc->result, rvTypeTup); + else + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("tuple return types are not supported yet"))); - rvTypeStruct = (Form_pg_type) GETSTRUCT(rvTypeTup); - if (rvTypeStruct->typtype != 'c') - PLy_output_datum_func(&proc->result, rvTypeTup); + ReleaseSysCache(rvTypeTup); + } else - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("tuple return types are not supported yet"))); + { + /* + * input/output conversion for trigger tuples. use the result + * TypeInfo variable to store the tuple conversion info. + */ + TriggerData *tdata = (TriggerData *) fcinfo->context; + + PLy_input_tuple_funcs(&(proc->result), tdata->tg_relation->rd_att); + PLy_output_tuple_funcs(&(proc->result), tdata->tg_relation->rd_att); + } - ReleaseSysCache(rvTypeTup); - } - else - { /* - * input/output conversion for trigger tuples. use the result - * TypeInfo variable to store the tuple conversion info. + * now get information required for input conversion of the + * procedures arguments. */ - TriggerData *tdata = (TriggerData *) fcinfo->context; - - PLy_input_tuple_funcs(&(proc->result), tdata->tg_relation->rd_att); - PLy_output_tuple_funcs(&(proc->result), tdata->tg_relation->rd_att); - } - - /* - * now get information required for input conversion of the procedures - * arguments. - */ - proc->nargs = fcinfo->nargs; - for (i = 0; i < fcinfo->nargs; i++) - { - HeapTuple argTypeTup; - Form_pg_type argTypeStruct; + proc->nargs = fcinfo->nargs; + for (i = 0; i < fcinfo->nargs; i++) + { + HeapTuple argTypeTup; + Form_pg_type argTypeStruct; - argTypeTup = SearchSysCache(TYPEOID, + argTypeTup = SearchSysCache(TYPEOID, ObjectIdGetDatum(procStruct->proargtypes[i]), - 0, 0, 0); - if (!HeapTupleIsValid(argTypeTup)) - elog(ERROR, "cache lookup failed for type %u", - procStruct->proargtypes[i]); - argTypeStruct = (Form_pg_type) GETSTRUCT(argTypeTup); - - if (argTypeStruct->typtype != 'c') - PLy_input_datum_func(&(proc->args[i]), - procStruct->proargtypes[i], - argTypeTup); - else - proc->args[i].is_rowtype = 2; /* still need to set I/O funcs */ + 0, 0, 0); + if (!HeapTupleIsValid(argTypeTup)) + elog(ERROR, "cache lookup failed for type %u", + procStruct->proargtypes[i]); + argTypeStruct = (Form_pg_type) GETSTRUCT(argTypeTup); + + if (argTypeStruct->typtype != 'c') + PLy_input_datum_func(&(proc->args[i]), + procStruct->proargtypes[i], + argTypeTup); + else + proc->args[i].is_rowtype = 2; /* still need to set I/O + * funcs */ - ReleaseSysCache(argTypeTup); - } + ReleaseSysCache(argTypeTup); + } - /* - * get the text of the function. - */ - prosrcdatum = SysCacheGetAttr(PROCOID, procTup, - Anum_pg_proc_prosrc, &isnull); - if (isnull) - elog(ERROR, "null prosrc"); - procSource = DatumGetCString(DirectFunctionCall1(textout, - prosrcdatum)); + /* + * get the text of the function. + */ + prosrcdatum = SysCacheGetAttr(PROCOID, procTup, + Anum_pg_proc_prosrc, &isnull); + if (isnull) + elog(ERROR, "null prosrc"); + procSource = DatumGetCString(DirectFunctionCall1(textout, + prosrcdatum)); - PLy_procedure_compile(proc, procSource); + PLy_procedure_compile(proc, procSource); - pfree(procSource); + pfree(procSource); - proc->me = PyCObject_FromVoidPtr(proc, NULL); - PyDict_SetItemString(PLy_procedure_cache, key, proc->me); + proc->me = PyCObject_FromVoidPtr(proc, NULL); + PyDict_SetItemString(PLy_procedure_cache, key, proc->me); } PG_CATCH(); { @@ -1437,41 +1436,41 @@ PLyDict_FromTuple(PLyTypeInfo * info, HeapTuple tuple, TupleDesc desc) PG_TRY(); { - for (i = 0; i < info->in.r.natts; i++) - { - char *key, - *vsrc; - Datum vattr, - vdat; - bool is_null; - PyObject *value; + for (i = 0; i < info->in.r.natts; i++) + { + char *key, + *vsrc; + Datum vattr, + vdat; + bool is_null; + PyObject *value; - if (desc->attrs[i]->attisdropped) - continue; + if (desc->attrs[i]->attisdropped) + continue; - key = NameStr(desc->attrs[i]->attname); - vattr = heap_getattr(tuple, (i + 1), desc, &is_null); + key = NameStr(desc->attrs[i]->attname); + vattr = heap_getattr(tuple, (i + 1), desc, &is_null); - if ((is_null) || (info->in.r.atts[i].func == NULL)) - PyDict_SetItemString(dict, key, Py_None); - else - { - vdat = FunctionCall3(&info->in.r.atts[i].typfunc, - vattr, - ObjectIdGetDatum(info->in.r.atts[i].typioparam), + if ((is_null) || (info->in.r.atts[i].func == NULL)) + PyDict_SetItemString(dict, key, Py_None); + else + { + vdat = FunctionCall3(&info->in.r.atts[i].typfunc, + vattr, + ObjectIdGetDatum(info->in.r.atts[i].typioparam), Int32GetDatum(desc->attrs[i]->atttypmod)); - vsrc = DatumGetCString(vdat); - - /* - * no exceptions allowed - */ - value = info->in.r.atts[i].func(vsrc); - pfree(vsrc); - PyDict_SetItemString(dict, key, value); - Py_DECREF(value); + vsrc = DatumGetCString(vdat); + + /* + * no exceptions allowed + */ + value = info->in.r.atts[i].func(vsrc); + pfree(vsrc); + PyDict_SetItemString(dict, key, value); + Py_DECREF(value); + } } } - } PG_CATCH(); { Py_DECREF(dict); @@ -1858,68 +1857,72 @@ PLy_spi_prepare(PyObject * self, PyObject * args) oldcontext = CurrentMemoryContext; PG_TRY(); { - if (list != NULL) - { - int nargs, - i; - - nargs = PySequence_Length(list); - if (nargs > 0) + if (list != NULL) { - plan->nargs = nargs; - plan->types = PLy_malloc(sizeof(Oid) * nargs); - plan->values = PLy_malloc(sizeof(Datum) * nargs); - plan->args = PLy_malloc(sizeof(PLyTypeInfo) * nargs); + int nargs, + i; - /* - * the other loop might throw an exception, if PLyTypeInfo - * member isn't properly initialized the Py_DECREF(plan) will - * go boom - */ - for (i = 0; i < nargs; i++) + nargs = PySequence_Length(list); + if (nargs > 0) { - PLy_typeinfo_init(&plan->args[i]); - plan->values[i] = (Datum) NULL; - } + plan->nargs = nargs; + plan->types = PLy_malloc(sizeof(Oid) * nargs); + plan->values = PLy_malloc(sizeof(Datum) * nargs); + plan->args = PLy_malloc(sizeof(PLyTypeInfo) * nargs); + + /* + * the other loop might throw an exception, if PLyTypeInfo + * member isn't properly initialized the Py_DECREF(plan) + * will go boom + */ + for (i = 0; i < nargs; i++) + { + PLy_typeinfo_init(&plan->args[i]); + plan->values[i] = (Datum) NULL; + } - for (i = 0; i < nargs; i++) - { - char *sptr; - HeapTuple typeTup; - Form_pg_type typeStruct; - - optr = PySequence_GetItem(list, i); - if (!PyString_Check(optr)) - elog(ERROR, "Type names must be strings."); - sptr = PyString_AsString(optr); - /* XXX should extend this to allow qualified type names */ - typeTup = typenameType(makeTypeName(sptr)); - Py_DECREF(optr); - optr = NULL; /* this is important */ - - plan->types[i] = HeapTupleGetOid(typeTup); - typeStruct = (Form_pg_type) GETSTRUCT(typeTup); - if (typeStruct->typtype != 'c') - PLy_output_datum_func(&plan->args[i], typeTup); - else - elog(ERROR, "tuples not handled in plpy.prepare, yet."); - ReleaseSysCache(typeTup); + for (i = 0; i < nargs; i++) + { + char *sptr; + HeapTuple typeTup; + Form_pg_type typeStruct; + + optr = PySequence_GetItem(list, i); + if (!PyString_Check(optr)) + elog(ERROR, "Type names must be strings."); + sptr = PyString_AsString(optr); + + /* + * XXX should extend this to allow qualified type + * names + */ + typeTup = typenameType(makeTypeName(sptr)); + Py_DECREF(optr); + optr = NULL; /* this is important */ + + plan->types[i] = HeapTupleGetOid(typeTup); + typeStruct = (Form_pg_type) GETSTRUCT(typeTup); + if (typeStruct->typtype != 'c') + PLy_output_datum_func(&plan->args[i], typeTup); + else + elog(ERROR, "tuples not handled in plpy.prepare, yet."); + ReleaseSysCache(typeTup); + } } } - } - plan->plan = SPI_prepare(query, plan->nargs, plan->types); - if (plan->plan == NULL) - elog(ERROR, "SPI_prepare failed: %s", - SPI_result_code_string(SPI_result)); - - /* transfer plan from procCxt to topCxt */ - tmpplan = plan->plan; - plan->plan = SPI_saveplan(tmpplan); - SPI_freeplan(tmpplan); - if (plan->plan == NULL) - elog(ERROR, "SPI_saveplan failed: %s", - SPI_result_code_string(SPI_result)); + plan->plan = SPI_prepare(query, plan->nargs, plan->types); + if (plan->plan == NULL) + elog(ERROR, "SPI_prepare failed: %s", + SPI_result_code_string(SPI_result)); + + /* transfer plan from procCxt to topCxt */ + tmpplan = plan->plan; + plan->plan = SPI_saveplan(tmpplan); + SPI_freeplan(tmpplan); + if (plan->plan == NULL) + elog(ERROR, "SPI_saveplan failed: %s", + SPI_result_code_string(SPI_result)); } PG_CATCH(); { @@ -2015,51 +2018,52 @@ PLy_spi_execute_plan(PyObject * ob, PyObject * list, int limit) oldcontext = CurrentMemoryContext; PG_TRY(); { - nulls = palloc(nargs * sizeof(char)); - - for (i = 0; i < nargs; i++) - { - PyObject *elem, - *so; - char *sv; + nulls = palloc(nargs * sizeof(char)); - elem = PySequence_GetItem(list, i); - if (elem != Py_None) + for (i = 0; i < nargs; i++) { - so = PyObject_Str(elem); - sv = PyString_AsString(so); - - /* - * FIXME -- if this elogs, we have Python reference leak - */ - plan->values[i] = - FunctionCall3(&(plan->args[i].out.d.typfunc), - CStringGetDatum(sv), - ObjectIdGetDatum(plan->args[i].out.d.typioparam), - Int32GetDatum(-1)); + PyObject *elem, + *so; + char *sv; - Py_DECREF(so); - Py_DECREF(elem); - - nulls[i] = ' '; - } - else - { - Py_DECREF(elem); - plan->values[i] = (Datum) 0; - nulls[i] = 'n'; + elem = PySequence_GetItem(list, i); + if (elem != Py_None) + { + so = PyObject_Str(elem); + sv = PyString_AsString(so); + + /* + * FIXME -- if this elogs, we have Python reference leak + */ + plan->values[i] = + FunctionCall3(&(plan->args[i].out.d.typfunc), + CStringGetDatum(sv), + ObjectIdGetDatum(plan->args[i].out.d.typioparam), + Int32GetDatum(-1)); + + Py_DECREF(so); + Py_DECREF(elem); + + nulls[i] = ' '; + } + else + { + Py_DECREF(elem); + plan->values[i] = (Datum) 0; + nulls[i] = 'n'; + } } - } - rv = SPI_execp(plan->plan, plan->values, nulls, limit); + rv = SPI_execp(plan->plan, plan->values, nulls, limit); - pfree(nulls); + pfree(nulls); } PG_CATCH(); { MemoryContextSwitchTo(oldcontext); PLy_error_in_progress = CopyErrorData(); FlushErrorState(); + /* * cleanup plan->values array */ @@ -2110,9 +2114,7 @@ PLy_spi_execute_query(char *query, int limit) oldcontext = CurrentMemoryContext; PG_TRY(); - { rv = SPI_exec(query, limit); - } PG_CATCH(); { MemoryContextSwitchTo(oldcontext); @@ -2178,7 +2180,7 @@ PLy_spi_execute_fetch_result(SPITupleTable *tuptable, int rows, int status) for (i = 0; i < rows; i++) { PyObject *row = PLyDict_FromTuple(&args, tuptable->vals[i], - tuptable->tupdesc); + tuptable->tupdesc); PyList_SetItem(result->rows, i, row); } @@ -2194,7 +2196,7 @@ PLy_spi_execute_fetch_result(SPITupleTable *tuptable, int rows, int status) FlushErrorState(); if (!PyErr_Occurred()) PyErr_SetString(PLy_exc_error, - "Unknown error in PLy_spi_execute_fetch_result"); + "Unknown error in PLy_spi_execute_fetch_result"); Py_DECREF(result); PLy_typeinfo_dealloc(&args); return NULL; @@ -2373,15 +2375,14 @@ PLy_output(volatile int level, PyObject * self, PyObject * args) oldcontext = CurrentMemoryContext; PG_TRY(); - { elog(level, "%s", sv); - } PG_CATCH(); { MemoryContextSwitchTo(oldcontext); PLy_error_in_progress = CopyErrorData(); FlushErrorState(); Py_XDECREF(so); + /* * returning NULL here causes the python interpreter to bail. when * control passes back to PLy_procedure_call, we check for PG diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c index 2a8e6c84585..87cc2bf4a63 100644 --- a/src/pl/tcl/pltcl.c +++ b/src/pl/tcl/pltcl.c @@ -31,7 +31,7 @@ * ENHANCEMENTS, OR MODIFICATIONS. * * IDENTIFICATION - * $PostgreSQL: pgsql/src/pl/tcl/pltcl.c,v 1.89 2004/08/04 21:34:32 tgl Exp $ + * $PostgreSQL: pgsql/src/pl/tcl/pltcl.c,v 1.90 2004/08/29 05:07:02 momjian Exp $ * **********************************************************************/ @@ -156,9 +156,9 @@ static ErrorData *pltcl_error_in_progress = NULL; * Forward declarations **********************************************************************/ static void pltcl_init_all(void); -static void pltcl_init_interp(Tcl_Interp *interp); +static void pltcl_init_interp(Tcl_Interp * interp); -static void pltcl_init_load_unknown(Tcl_Interp *interp); +static void pltcl_init_load_unknown(Tcl_Interp * interp); Datum pltcl_call_handler(PG_FUNCTION_ARGS); Datum pltclu_call_handler(PG_FUNCTION_ARGS); @@ -170,28 +170,28 @@ static HeapTuple pltcl_trigger_handler(PG_FUNCTION_ARGS); static pltcl_proc_desc *compile_pltcl_function(Oid fn_oid, Oid tgreloid); -static int pltcl_elog(ClientData cdata, Tcl_Interp *interp, +static int pltcl_elog(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]); -static int pltcl_quote(ClientData cdata, Tcl_Interp *interp, +static int pltcl_quote(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]); -static int pltcl_argisnull(ClientData cdata, Tcl_Interp *interp, +static int pltcl_argisnull(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]); -static int pltcl_returnnull(ClientData cdata, Tcl_Interp *interp, +static int pltcl_returnnull(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]); -static int pltcl_SPI_exec(ClientData cdata, Tcl_Interp *interp, +static int pltcl_SPI_exec(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]); -static int pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp, +static int pltcl_SPI_prepare(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]); -static int pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp, +static int pltcl_SPI_execp(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]); -static int pltcl_SPI_lastoid(ClientData cdata, Tcl_Interp *interp, +static int pltcl_SPI_lastoid(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]); -static void pltcl_set_tuple_values(Tcl_Interp *interp, CONST84 char *arrayname, +static void pltcl_set_tuple_values(Tcl_Interp * interp, CONST84 char *arrayname, int tupno, HeapTuple tuple, TupleDesc tupdesc); static void pltcl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc, - Tcl_DString *retval); + Tcl_DString * retval); /* @@ -292,7 +292,7 @@ pltcl_init_all(void) * pltcl_init_interp() - initialize a Tcl interpreter **********************************************************************/ static void -pltcl_init_interp(Tcl_Interp *interp) +pltcl_init_interp(Tcl_Interp * interp) { /************************************************************ * Install the commands for SPI support in the interpreter @@ -322,7 +322,7 @@ pltcl_init_interp(Tcl_Interp *interp) * table pltcl_modules (if it exists) **********************************************************************/ static void -pltcl_init_load_unknown(Tcl_Interp *interp) +pltcl_init_load_unknown(Tcl_Interp * interp) { int spi_rc; int tcl_rc; @@ -485,62 +485,62 @@ pltcl_func_handler(PG_FUNCTION_ARGS) ************************************************************/ PG_TRY(); { - for (i = 0; i < prodesc->nargs; i++) - { - if (prodesc->arg_is_rowtype[i]) + for (i = 0; i < prodesc->nargs; i++) { - /************************************************** - * For tuple values, add a list for 'array set ...' - **************************************************/ - if (fcinfo->argnull[i]) - Tcl_DStringAppendElement(&tcl_cmd, ""); - else + if (prodesc->arg_is_rowtype[i]) { - HeapTupleHeader td; - Oid tupType; - int32 tupTypmod; - TupleDesc tupdesc; - HeapTupleData tmptup; - - td = DatumGetHeapTupleHeader(fcinfo->arg[i]); - /* Extract rowtype info and find a tupdesc */ - tupType = HeapTupleHeaderGetTypeId(td); - tupTypmod = HeapTupleHeaderGetTypMod(td); - tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod); - /* Build a temporary HeapTuple control structure */ - tmptup.t_len = HeapTupleHeaderGetDatumLength(td); - tmptup.t_data = td; - - Tcl_DStringSetLength(&list_tmp, 0); - pltcl_build_tuple_argument(&tmptup, tupdesc, &list_tmp); - Tcl_DStringAppendElement(&tcl_cmd, - Tcl_DStringValue(&list_tmp)); + /************************************************** + * For tuple values, add a list for 'array set ...' + **************************************************/ + if (fcinfo->argnull[i]) + Tcl_DStringAppendElement(&tcl_cmd, ""); + else + { + HeapTupleHeader td; + Oid tupType; + int32 tupTypmod; + TupleDesc tupdesc; + HeapTupleData tmptup; + + td = DatumGetHeapTupleHeader(fcinfo->arg[i]); + /* Extract rowtype info and find a tupdesc */ + tupType = HeapTupleHeaderGetTypeId(td); + tupTypmod = HeapTupleHeaderGetTypMod(td); + tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod); + /* Build a temporary HeapTuple control structure */ + tmptup.t_len = HeapTupleHeaderGetDatumLength(td); + tmptup.t_data = td; + + Tcl_DStringSetLength(&list_tmp, 0); + pltcl_build_tuple_argument(&tmptup, tupdesc, &list_tmp); + Tcl_DStringAppendElement(&tcl_cmd, + Tcl_DStringValue(&list_tmp)); + } } - } - else - { - /************************************************** - * Single values are added as string element - * of their external representation - **************************************************/ - if (fcinfo->argnull[i]) - Tcl_DStringAppendElement(&tcl_cmd, ""); else { - char *tmp; - - tmp = DatumGetCString(FunctionCall3(&prodesc->arg_out_func[i], - fcinfo->arg[i], - ObjectIdGetDatum(prodesc->arg_typioparam[i]), - Int32GetDatum(-1))); - UTF_BEGIN; - Tcl_DStringAppendElement(&tcl_cmd, UTF_E2U(tmp)); - UTF_END; - pfree(tmp); + /************************************************** + * Single values are added as string element + * of their external representation + **************************************************/ + if (fcinfo->argnull[i]) + Tcl_DStringAppendElement(&tcl_cmd, ""); + else + { + char *tmp; + + tmp = DatumGetCString(FunctionCall3(&prodesc->arg_out_func[i], + fcinfo->arg[i], + ObjectIdGetDatum(prodesc->arg_typioparam[i]), + Int32GetDatum(-1))); + UTF_BEGIN; + Tcl_DStringAppendElement(&tcl_cmd, UTF_E2U(tmp)); + UTF_END; + pfree(tmp); + } } } } - } PG_CATCH(); { Tcl_DStringFree(&tcl_cmd); @@ -564,7 +564,7 @@ pltcl_func_handler(PG_FUNCTION_ARGS) ************************************************************/ if (pltcl_error_in_progress) { - ErrorData *edata = pltcl_error_in_progress; + ErrorData *edata = pltcl_error_in_progress; pltcl_error_in_progress = NULL; ReThrowError(edata); @@ -603,7 +603,7 @@ pltcl_func_handler(PG_FUNCTION_ARGS) UTF_BEGIN; retval = FunctionCall3(&prodesc->result_in_func, PointerGetDatum(UTF_U2E(interp->result)), - ObjectIdGetDatum(prodesc->result_typioparam), + ObjectIdGetDatum(prodesc->result_typioparam), Int32GetDatum(-1)); UTF_END; } @@ -641,7 +641,7 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS) /* Find or compile the function */ prodesc = compile_pltcl_function(fcinfo->flinfo->fn_oid, - RelationGetRelid(trigdata->tg_relation)); + RelationGetRelid(trigdata->tg_relation)); if (prodesc->lanpltrusted) interp = pltcl_safe_interp; @@ -659,110 +659,110 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS) Tcl_DStringInit(&tcl_newtup); PG_TRY(); { - /* The procedure name */ - Tcl_DStringAppendElement(&tcl_cmd, prodesc->proname); + /* The procedure name */ + Tcl_DStringAppendElement(&tcl_cmd, prodesc->proname); - /* The trigger name for argument TG_name */ - Tcl_DStringAppendElement(&tcl_cmd, trigdata->tg_trigger->tgname); + /* The trigger name for argument TG_name */ + Tcl_DStringAppendElement(&tcl_cmd, trigdata->tg_trigger->tgname); - /* The oid of the trigger relation for argument TG_relid */ - stroid = DatumGetCString(DirectFunctionCall1(oidout, + /* The oid of the trigger relation for argument TG_relid */ + stroid = DatumGetCString(DirectFunctionCall1(oidout, ObjectIdGetDatum(trigdata->tg_relation->rd_id))); - Tcl_DStringAppendElement(&tcl_cmd, stroid); - pfree(stroid); + Tcl_DStringAppendElement(&tcl_cmd, stroid); + pfree(stroid); - /* A list of attribute names for argument TG_relatts */ - Tcl_DStringAppendElement(&tcl_trigtup, ""); - for (i = 0; i < tupdesc->natts; i++) - { - if (tupdesc->attrs[i]->attisdropped) - Tcl_DStringAppendElement(&tcl_trigtup, ""); + /* A list of attribute names for argument TG_relatts */ + Tcl_DStringAppendElement(&tcl_trigtup, ""); + for (i = 0; i < tupdesc->natts; i++) + { + if (tupdesc->attrs[i]->attisdropped) + Tcl_DStringAppendElement(&tcl_trigtup, ""); + else + Tcl_DStringAppendElement(&tcl_trigtup, + NameStr(tupdesc->attrs[i]->attname)); + } + Tcl_DStringAppendElement(&tcl_cmd, Tcl_DStringValue(&tcl_trigtup)); + Tcl_DStringFree(&tcl_trigtup); + Tcl_DStringInit(&tcl_trigtup); + + /* The when part of the event for TG_when */ + if (TRIGGER_FIRED_BEFORE(trigdata->tg_event)) + Tcl_DStringAppendElement(&tcl_cmd, "BEFORE"); + else if (TRIGGER_FIRED_AFTER(trigdata->tg_event)) + Tcl_DStringAppendElement(&tcl_cmd, "AFTER"); else - Tcl_DStringAppendElement(&tcl_trigtup, - NameStr(tupdesc->attrs[i]->attname)); - } - Tcl_DStringAppendElement(&tcl_cmd, Tcl_DStringValue(&tcl_trigtup)); - Tcl_DStringFree(&tcl_trigtup); - Tcl_DStringInit(&tcl_trigtup); + elog(ERROR, "unrecognized WHEN tg_event: %u", trigdata->tg_event); - /* The when part of the event for TG_when */ - if (TRIGGER_FIRED_BEFORE(trigdata->tg_event)) - Tcl_DStringAppendElement(&tcl_cmd, "BEFORE"); - else if (TRIGGER_FIRED_AFTER(trigdata->tg_event)) - Tcl_DStringAppendElement(&tcl_cmd, "AFTER"); - else - elog(ERROR, "unrecognized WHEN tg_event: %u", trigdata->tg_event); + /* The level part of the event for TG_level */ + if (TRIGGER_FIRED_FOR_ROW(trigdata->tg_event)) + { + Tcl_DStringAppendElement(&tcl_cmd, "ROW"); - /* The level part of the event for TG_level */ - if (TRIGGER_FIRED_FOR_ROW(trigdata->tg_event)) - { - Tcl_DStringAppendElement(&tcl_cmd, "ROW"); + /* Build the data list for the trigtuple */ + pltcl_build_tuple_argument(trigdata->tg_trigtuple, + tupdesc, &tcl_trigtup); - /* Build the data list for the trigtuple */ - pltcl_build_tuple_argument(trigdata->tg_trigtuple, - tupdesc, &tcl_trigtup); + /* + * Now the command part of the event for TG_op and data for + * NEW and OLD + */ + if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) + { + Tcl_DStringAppendElement(&tcl_cmd, "INSERT"); - /* - * Now the command part of the event for TG_op and data for NEW - * and OLD - */ - if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) - { - Tcl_DStringAppendElement(&tcl_cmd, "INSERT"); + Tcl_DStringAppendElement(&tcl_cmd, Tcl_DStringValue(&tcl_trigtup)); + Tcl_DStringAppendElement(&tcl_cmd, ""); - Tcl_DStringAppendElement(&tcl_cmd, Tcl_DStringValue(&tcl_trigtup)); - Tcl_DStringAppendElement(&tcl_cmd, ""); + rettup = trigdata->tg_trigtuple; + } + else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event)) + { + Tcl_DStringAppendElement(&tcl_cmd, "DELETE"); - rettup = trigdata->tg_trigtuple; - } - else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event)) - { - Tcl_DStringAppendElement(&tcl_cmd, "DELETE"); + Tcl_DStringAppendElement(&tcl_cmd, ""); + Tcl_DStringAppendElement(&tcl_cmd, Tcl_DStringValue(&tcl_trigtup)); - Tcl_DStringAppendElement(&tcl_cmd, ""); - Tcl_DStringAppendElement(&tcl_cmd, Tcl_DStringValue(&tcl_trigtup)); + rettup = trigdata->tg_trigtuple; + } + else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) + { + Tcl_DStringAppendElement(&tcl_cmd, "UPDATE"); - rettup = trigdata->tg_trigtuple; + pltcl_build_tuple_argument(trigdata->tg_newtuple, + tupdesc, &tcl_newtup); + + Tcl_DStringAppendElement(&tcl_cmd, Tcl_DStringValue(&tcl_newtup)); + Tcl_DStringAppendElement(&tcl_cmd, Tcl_DStringValue(&tcl_trigtup)); + + rettup = trigdata->tg_newtuple; + } + else + elog(ERROR, "unrecognized OP tg_event: %u", trigdata->tg_event); } - else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) + else if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event)) { - Tcl_DStringAppendElement(&tcl_cmd, "UPDATE"); - - pltcl_build_tuple_argument(trigdata->tg_newtuple, - tupdesc, &tcl_newtup); + Tcl_DStringAppendElement(&tcl_cmd, "STATEMENT"); + + if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) + Tcl_DStringAppendElement(&tcl_cmd, "INSERT"); + else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event)) + Tcl_DStringAppendElement(&tcl_cmd, "DELETE"); + else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) + Tcl_DStringAppendElement(&tcl_cmd, "UPDATE"); + else + elog(ERROR, "unrecognized OP tg_event: %u", trigdata->tg_event); - Tcl_DStringAppendElement(&tcl_cmd, Tcl_DStringValue(&tcl_newtup)); - Tcl_DStringAppendElement(&tcl_cmd, Tcl_DStringValue(&tcl_trigtup)); + Tcl_DStringAppendElement(&tcl_cmd, ""); + Tcl_DStringAppendElement(&tcl_cmd, ""); - rettup = trigdata->tg_newtuple; + rettup = (HeapTuple) NULL; } else - elog(ERROR, "unrecognized OP tg_event: %u", trigdata->tg_event); - } - else if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event)) - { - Tcl_DStringAppendElement(&tcl_cmd, "STATEMENT"); - - if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) - Tcl_DStringAppendElement(&tcl_cmd, "INSERT"); - else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event)) - Tcl_DStringAppendElement(&tcl_cmd, "DELETE"); - else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) - Tcl_DStringAppendElement(&tcl_cmd, "UPDATE"); - else - elog(ERROR, "unrecognized OP tg_event: %u", trigdata->tg_event); + elog(ERROR, "unrecognized LEVEL tg_event: %u", trigdata->tg_event); - Tcl_DStringAppendElement(&tcl_cmd, ""); - Tcl_DStringAppendElement(&tcl_cmd, ""); - - rettup = (HeapTuple) NULL; - } - else - elog(ERROR, "unrecognized LEVEL tg_event: %u", trigdata->tg_event); - - /* Finally append the arguments from CREATE TRIGGER */ - for (i = 0; i < trigdata->tg_trigger->tgnargs; i++) - Tcl_DStringAppendElement(&tcl_cmd, trigdata->tg_trigger->tgargs[i]); + /* Finally append the arguments from CREATE TRIGGER */ + for (i = 0; i < trigdata->tg_trigger->tgnargs; i++) + Tcl_DStringAppendElement(&tcl_cmd, trigdata->tg_trigger->tgargs[i]); } PG_CATCH(); @@ -790,7 +790,7 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS) ************************************************************/ if (pltcl_error_in_progress) { - ErrorData *edata = pltcl_error_in_progress; + ErrorData *edata = pltcl_error_in_progress; pltcl_error_in_progress = NULL; ReThrowError(edata); @@ -835,88 +835,88 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS) PG_TRY(); { - if (ret_numvals % 2 != 0) - elog(ERROR, "invalid return list from trigger - must have even # of elements"); + if (ret_numvals % 2 != 0) + elog(ERROR, "invalid return list from trigger - must have even # of elements"); - modattrs = (int *) palloc(tupdesc->natts * sizeof(int)); - modvalues = (Datum *) palloc(tupdesc->natts * sizeof(Datum)); - for (i = 0; i < tupdesc->natts; i++) - { - modattrs[i] = i + 1; - modvalues[i] = (Datum) NULL; - } + modattrs = (int *) palloc(tupdesc->natts * sizeof(int)); + modvalues = (Datum *) palloc(tupdesc->natts * sizeof(Datum)); + for (i = 0; i < tupdesc->natts; i++) + { + modattrs[i] = i + 1; + modvalues[i] = (Datum) NULL; + } - modnulls = palloc(tupdesc->natts); - memset(modnulls, 'n', tupdesc->natts); + modnulls = palloc(tupdesc->natts); + memset(modnulls, 'n', tupdesc->natts); - for (i = 0; i < ret_numvals; i += 2) - { - CONST84 char *ret_name = ret_values[i]; - CONST84 char *ret_value = ret_values[i + 1]; - int attnum; - HeapTuple typeTup; - Oid typinput; - Oid typioparam; - FmgrInfo finfo; + for (i = 0; i < ret_numvals; i += 2) + { + CONST84 char *ret_name = ret_values[i]; + CONST84 char *ret_value = ret_values[i + 1]; + int attnum; + HeapTuple typeTup; + Oid typinput; + Oid typioparam; + FmgrInfo finfo; - /************************************************************ - * Ignore ".tupno" pseudo elements (see pltcl_set_tuple_values) - ************************************************************/ - if (strcmp(ret_name, ".tupno") == 0) - continue; + /************************************************************ + * Ignore ".tupno" pseudo elements (see pltcl_set_tuple_values) + ************************************************************/ + if (strcmp(ret_name, ".tupno") == 0) + continue; - /************************************************************ - * Get the attribute number - ************************************************************/ - attnum = SPI_fnumber(tupdesc, ret_name); - if (attnum == SPI_ERROR_NOATTRIBUTE) - elog(ERROR, "invalid attribute \"%s\"", ret_name); - if (attnum <= 0) - elog(ERROR, "cannot set system attribute \"%s\"", ret_name); + /************************************************************ + * Get the attribute number + ************************************************************/ + attnum = SPI_fnumber(tupdesc, ret_name); + if (attnum == SPI_ERROR_NOATTRIBUTE) + elog(ERROR, "invalid attribute \"%s\"", ret_name); + if (attnum <= 0) + elog(ERROR, "cannot set system attribute \"%s\"", ret_name); - /************************************************************ - * Ignore dropped columns - ************************************************************/ - if (tupdesc->attrs[attnum - 1]->attisdropped) - continue; + /************************************************************ + * Ignore dropped columns + ************************************************************/ + if (tupdesc->attrs[attnum - 1]->attisdropped) + continue; - /************************************************************ - * Lookup the attribute type in the syscache - * for the input function - ************************************************************/ - typeTup = SearchSysCache(TYPEOID, + /************************************************************ + * Lookup the attribute type in the syscache + * for the input function + ************************************************************/ + typeTup = SearchSysCache(TYPEOID, ObjectIdGetDatum(tupdesc->attrs[attnum - 1]->atttypid), - 0, 0, 0); - if (!HeapTupleIsValid(typeTup)) - elog(ERROR, "cache lookup failed for type %u", - tupdesc->attrs[attnum - 1]->atttypid); - typinput = ((Form_pg_type) GETSTRUCT(typeTup))->typinput; - typioparam = getTypeIOParam(typeTup); - ReleaseSysCache(typeTup); + 0, 0, 0); + if (!HeapTupleIsValid(typeTup)) + elog(ERROR, "cache lookup failed for type %u", + tupdesc->attrs[attnum - 1]->atttypid); + typinput = ((Form_pg_type) GETSTRUCT(typeTup))->typinput; + typioparam = getTypeIOParam(typeTup); + ReleaseSysCache(typeTup); - /************************************************************ - * Set the attribute to NOT NULL and convert the contents - ************************************************************/ - modnulls[attnum - 1] = ' '; - fmgr_info(typinput, &finfo); - UTF_BEGIN; - modvalues[attnum - 1] = - FunctionCall3(&finfo, - CStringGetDatum(UTF_U2E(ret_value)), - ObjectIdGetDatum(typioparam), + /************************************************************ + * Set the attribute to NOT NULL and convert the contents + ************************************************************/ + modnulls[attnum - 1] = ' '; + fmgr_info(typinput, &finfo); + UTF_BEGIN; + modvalues[attnum - 1] = + FunctionCall3(&finfo, + CStringGetDatum(UTF_U2E(ret_value)), + ObjectIdGetDatum(typioparam), Int32GetDatum(tupdesc->attrs[attnum - 1]->atttypmod)); - UTF_END; - } + UTF_END; + } - rettup = SPI_modifytuple(trigdata->tg_relation, rettup, tupdesc->natts, - modattrs, modvalues, modnulls); + rettup = SPI_modifytuple(trigdata->tg_relation, rettup, tupdesc->natts, + modattrs, modvalues, modnulls); - pfree(modattrs); - pfree(modvalues); - pfree(modnulls); + pfree(modattrs); + pfree(modvalues); + pfree(modnulls); - if (rettup == NULL) - elog(ERROR, "SPI_modifytuple() failed - RC = %d", SPI_result); + if (rettup == NULL) + elog(ERROR, "SPI_modifytuple() failed - RC = %d", SPI_result); } PG_CATCH(); @@ -1267,7 +1267,7 @@ compile_pltcl_function(Oid fn_oid, Oid tgreloid) * pltcl_elog() - elog() support for PLTcl **********************************************************************/ static int -pltcl_elog(ClientData cdata, Tcl_Interp *interp, +pltcl_elog(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]) { volatile int level; @@ -1339,7 +1339,7 @@ pltcl_elog(ClientData cdata, Tcl_Interp *interp, * be used in SPI_exec query strings **********************************************************************/ static int -pltcl_quote(ClientData cdata, Tcl_Interp *interp, +pltcl_quote(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]) { char *tmp; @@ -1392,7 +1392,7 @@ pltcl_quote(ClientData cdata, Tcl_Interp *interp, * pltcl_argisnull() - determine if a specific argument is NULL **********************************************************************/ static int -pltcl_argisnull(ClientData cdata, Tcl_Interp *interp, +pltcl_argisnull(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]) { int argno; @@ -1449,7 +1449,7 @@ pltcl_argisnull(ClientData cdata, Tcl_Interp *interp, * pltcl_returnnull() - Cause a NULL return from a function **********************************************************************/ static int -pltcl_returnnull(ClientData cdata, Tcl_Interp *interp, +pltcl_returnnull(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]) { FunctionCallInfo fcinfo = pltcl_current_fcinfo; @@ -1488,7 +1488,7 @@ pltcl_returnnull(ClientData cdata, Tcl_Interp *interp, * for the Tcl interpreter **********************************************************************/ static int -pltcl_SPI_exec(ClientData cdata, Tcl_Interp *interp, +pltcl_SPI_exec(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]) { volatile int my_rc; @@ -1696,7 +1696,7 @@ pltcl_SPI_exec(ClientData cdata, Tcl_Interp *interp, * and not save the plan currently. **********************************************************************/ static int -pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp, +pltcl_SPI_prepare(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]) { int nargs; @@ -1748,70 +1748,70 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp, oldcontext = CurrentMemoryContext; PG_TRY(); { - /************************************************************ - * Lookup the argument types by name in the system cache - * and remember the required information for input conversion - ************************************************************/ - for (i = 0; i < nargs; i++) - { - char *argcopy; - List *names = NIL; - ListCell *l; - TypeName *typename; - /************************************************************ - * Use SplitIdentifierString() on a copy of the type name, - * turn the resulting pointer list into a TypeName node - * and call typenameType() to get the pg_type tuple. + * Lookup the argument types by name in the system cache + * and remember the required information for input conversion ************************************************************/ - argcopy = pstrdup(args[i]); - SplitIdentifierString(argcopy, '.', &names); - typename = makeNode(TypeName); - foreach (l, names) - typename->names = lappend(typename->names, makeString(lfirst(l))); - - typeTup = typenameType(typename); - qdesc->argtypes[i] = HeapTupleGetOid(typeTup); - perm_fmgr_info(((Form_pg_type) GETSTRUCT(typeTup))->typinput, - &(qdesc->arginfuncs[i])); - qdesc->argtypioparams[i] = getTypeIOParam(typeTup); - ReleaseSysCache(typeTup); + for (i = 0; i < nargs; i++) + { + char *argcopy; + List *names = NIL; + ListCell *l; + TypeName *typename; - list_free(typename->names); - pfree(typename); - list_free(names); - pfree(argcopy); - } + /************************************************************ + * Use SplitIdentifierString() on a copy of the type name, + * turn the resulting pointer list into a TypeName node + * and call typenameType() to get the pg_type tuple. + ************************************************************/ + argcopy = pstrdup(args[i]); + SplitIdentifierString(argcopy, '.', &names); + typename = makeNode(TypeName); + foreach(l, names) + typename->names = lappend(typename->names, makeString(lfirst(l))); + + typeTup = typenameType(typename); + qdesc->argtypes[i] = HeapTupleGetOid(typeTup); + perm_fmgr_info(((Form_pg_type) GETSTRUCT(typeTup))->typinput, + &(qdesc->arginfuncs[i])); + qdesc->argtypioparams[i] = getTypeIOParam(typeTup); + ReleaseSysCache(typeTup); - /************************************************************ - * Prepare the plan and check for errors - ************************************************************/ - UTF_BEGIN; - plan = SPI_prepare(UTF_U2E(argv[1]), nargs, qdesc->argtypes); - UTF_END; + list_free(typename->names); + pfree(typename); + list_free(names); + pfree(argcopy); + } - if (plan == NULL) - elog(ERROR, "SPI_prepare() failed"); + /************************************************************ + * Prepare the plan and check for errors + ************************************************************/ + UTF_BEGIN; + plan = SPI_prepare(UTF_U2E(argv[1]), nargs, qdesc->argtypes); + UTF_END; - /************************************************************ - * Save the plan into permanent memory (right now it's in the - * SPI procCxt, which will go away at function end). - ************************************************************/ - qdesc->plan = SPI_saveplan(plan); - if (qdesc->plan == NULL) - elog(ERROR, "SPI_saveplan() failed"); + if (plan == NULL) + elog(ERROR, "SPI_prepare() failed"); - /* Release the procCxt copy to avoid within-function memory leak */ - SPI_freeplan(plan); + /************************************************************ + * Save the plan into permanent memory (right now it's in the + * SPI procCxt, which will go away at function end). + ************************************************************/ + qdesc->plan = SPI_saveplan(plan); + if (qdesc->plan == NULL) + elog(ERROR, "SPI_saveplan() failed"); - /************************************************************ - * Insert a hashtable entry for the plan and return - * the key to the caller - ************************************************************/ - if (interp == pltcl_norm_interp) - query_hash = pltcl_norm_query_hash; - else - query_hash = pltcl_safe_query_hash; + /* Release the procCxt copy to avoid within-function memory leak */ + SPI_freeplan(plan); + + /************************************************************ + * Insert a hashtable entry for the plan and return + * the key to the caller + ************************************************************/ + if (interp == pltcl_norm_interp) + query_hash = pltcl_norm_query_hash; + else + query_hash = pltcl_safe_query_hash; } PG_CATCH(); @@ -1843,7 +1843,7 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp, * pltcl_SPI_execp() - Execute a prepared plan **********************************************************************/ static int -pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp, +pltcl_SPI_execp(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]) { volatile int my_rc; @@ -2012,8 +2012,8 @@ pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp, UTF_BEGIN; argvalues[j] = FunctionCall3(&qdesc->arginfuncs[j], - CStringGetDatum(UTF_U2E(callargs[j])), - ObjectIdGetDatum(qdesc->argtypioparams[j]), + CStringGetDatum(UTF_U2E(callargs[j])), + ObjectIdGetDatum(qdesc->argtypioparams[j]), Int32GetDatum(-1)); UTF_END; } @@ -2046,9 +2046,7 @@ pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp, ************************************************************/ oldcontext = CurrentMemoryContext; PG_TRY(); - { spi_rc = SPI_execp(qdesc->plan, argvalues, nulls, count); - } PG_CATCH(); { MemoryContextSwitchTo(oldcontext); @@ -2170,7 +2168,7 @@ pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp, * be used after insert queries **********************************************************************/ static int -pltcl_SPI_lastoid(ClientData cdata, Tcl_Interp *interp, +pltcl_SPI_lastoid(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]) { char buf[64]; @@ -2186,7 +2184,7 @@ pltcl_SPI_lastoid(ClientData cdata, Tcl_Interp *interp, * of a given tuple **********************************************************************/ static void -pltcl_set_tuple_values(Tcl_Interp *interp, CONST84 char *arrayname, +pltcl_set_tuple_values(Tcl_Interp * interp, CONST84 char *arrayname, int tupno, HeapTuple tuple, TupleDesc tupdesc) { int i; @@ -2264,7 +2262,7 @@ pltcl_set_tuple_values(Tcl_Interp *interp, CONST84 char *arrayname, { outputstr = DatumGetCString(OidFunctionCall3(typoutput, attr, - ObjectIdGetDatum(typioparam), + ObjectIdGetDatum(typioparam), Int32GetDatum(tupdesc->attrs[i]->atttypmod))); UTF_BEGIN; Tcl_SetVar2(interp, *arrptr, *nameptr, UTF_E2U(outputstr), 0); @@ -2283,7 +2281,7 @@ pltcl_set_tuple_values(Tcl_Interp *interp, CONST84 char *arrayname, **********************************************************************/ static void pltcl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc, - Tcl_DString *retval) + Tcl_DString * retval) { int i; char *outputstr; @@ -2338,7 +2336,7 @@ pltcl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc, { outputstr = DatumGetCString(OidFunctionCall3(typoutput, attr, - ObjectIdGetDatum(typioparam), + ObjectIdGetDatum(typioparam), Int32GetDatum(tupdesc->attrs[i]->atttypmod))); Tcl_DStringAppendElement(retval, attname); UTF_BEGIN; |