PostgreSQL Source Code  git master
plperl.h File Reference
#include "EXTERN.h"
#include "perl.h"
#include "ppport.h"
Include dependency graph for plperl.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define PERL_UNUSED_DECL   pg_attribute_unused()
 
#define PERL_NO_GET_CONTEXT
 
#define vsnprintf   pg_vsnprintf
 
#define snprintf   pg_snprintf
 
#define vsprintf   pg_vsprintf
 
#define sprintf   pg_sprintf
 
#define vfprintf   pg_vfprintf
 
#define fprintf   pg_fprintf
 
#define vprintf   pg_vprintf
 
#define printf(...)   pg_printf(__VA_ARGS__)
 
#define _(x)   dgettext(TEXTDOMAIN, x)
 
#define NEED_eval_pv
 
#define NEED_newRV_noinc
 
#define NEED_sv_2pv_flags
 
#define HeUTF8(he)
 
#define GvCV_set(gv, cv)   (GvCV(gv) = cv)
 
#define AV_SIZE_MAX   I32_MAX
 

Functions

HV * plperl_spi_exec (char *, int)
 
void plperl_return_next (SV *)
 
SV * plperl_spi_query (char *)
 
SV * plperl_spi_fetchrow (char *)
 
SV * plperl_spi_prepare (char *, int, SV **)
 
HV * plperl_spi_exec_prepared (char *, HV *, int, SV **)
 
SV * plperl_spi_query_prepared (char *, int, SV **)
 
void plperl_spi_freeplan (char *)
 
void plperl_spi_cursor_close (char *)
 
void plperl_spi_commit (void)
 
void plperl_spi_rollback (void)
 
char * plperl_sv_to_literal (SV *, char *)
 
void plperl_util_elog (int level, SV *msg)
 

Macro Definition Documentation

◆ _

#define _ (   x)    dgettext(TEXTDOMAIN, x)

Definition at line 156 of file plperl.h.

◆ AV_SIZE_MAX

#define AV_SIZE_MAX   I32_MAX

Definition at line 200 of file plperl.h.

Referenced by plperl_spi_execute_fetch_result().

◆ fprintf

#define fprintf   pg_fprintf

Definition at line 144 of file plperl.h.

◆ GvCV_set

#define GvCV_set (   gv,
  cv 
)    (GvCV(gv) = cv)

Definition at line 193 of file plperl.h.

Referenced by plperl_trusted_init().

◆ HeUTF8

#define HeUTF8 (   he)
Value:
((HeKLEN(he) == HEf_SVKEY) ? \
SvUTF8(HeKEY_sv(he)) : \
(U32)HeKUTF8(he))

Definition at line 186 of file plperl.h.

Referenced by hek2cstr().

◆ NEED_eval_pv

#define NEED_eval_pv

Definition at line 166 of file plperl.h.

◆ NEED_newRV_noinc

#define NEED_newRV_noinc

Definition at line 167 of file plperl.h.

◆ NEED_sv_2pv_flags

#define NEED_sv_2pv_flags

Definition at line 168 of file plperl.h.

◆ PERL_NO_GET_CONTEXT

#define PERL_NO_GET_CONTEXT

Definition at line 76 of file plperl.h.

◆ PERL_UNUSED_DECL

#define PERL_UNUSED_DECL   pg_attribute_unused()

Definition at line 26 of file plperl.h.

◆ printf

#define printf (   ...)    pg_printf(__VA_ARGS__)

Definition at line 146 of file plperl.h.

◆ snprintf

#define snprintf   pg_snprintf

Definition at line 140 of file plperl.h.

◆ sprintf

#define sprintf   pg_sprintf

Definition at line 142 of file plperl.h.

◆ vfprintf

#define vfprintf   pg_vfprintf

Definition at line 143 of file plperl.h.

◆ vprintf

#define vprintf   pg_vprintf

Definition at line 145 of file plperl.h.

◆ vsnprintf

#define vsnprintf   pg_vsnprintf

Definition at line 139 of file plperl.h.

◆ vsprintf

#define vsprintf   pg_vsprintf

Definition at line 141 of file plperl.h.

Function Documentation

◆ plperl_return_next()

void plperl_return_next ( SV *  )

Definition at line 3221 of file plperl.c.

References CopyErrorData(), croak_cstr(), CurrentMemoryContext, FlushErrorState(), MemoryContextSwitchTo(), ErrorData::message, PG_CATCH, PG_END_TRY, PG_TRY, and plperl_return_next_internal().

3222 {
3223  MemoryContext oldcontext = CurrentMemoryContext;
3224 
3225  PG_TRY();
3226  {
3228  }
3229  PG_CATCH();
3230  {
3231  ErrorData *edata;
3232 
3233  /* Must reset elog.c's state */
3234  MemoryContextSwitchTo(oldcontext);
3235  edata = CopyErrorData();
3236  FlushErrorState();
3237 
3238  /* Punt the error to Perl */
3239  croak_cstr(edata->message);
3240  }
3241  PG_END_TRY();
3242 }
ErrorData * CopyErrorData(void)
Definition: elog.c:1584
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void FlushErrorState(void)
Definition: elog.c:1678
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
static void plperl_return_next_internal(SV *sv)
Definition: plperl.c:3249
static void croak_cstr(const char *str)
#define PG_CATCH()
Definition: elog.h:332
#define PG_TRY()
Definition: elog.h:322
#define PG_END_TRY()
Definition: elog.h:347
char * message
Definition: elog.h:392

◆ plperl_spi_commit()

void plperl_spi_commit ( void  )

Definition at line 3965 of file plperl.c.

References CopyErrorData(), croak_cstr(), CurrentMemoryContext, FlushErrorState(), MemoryContextSwitchTo(), ErrorData::message, PG_CATCH, PG_END_TRY, PG_TRY, SPI_commit(), and SPI_start_transaction().

3966 {
3967  MemoryContext oldcontext = CurrentMemoryContext;
3968 
3969  PG_TRY();
3970  {
3971  SPI_commit();
3973  }
3974  PG_CATCH();
3975  {
3976  ErrorData *edata;
3977 
3978  /* Save error info */
3979  MemoryContextSwitchTo(oldcontext);
3980  edata = CopyErrorData();
3981  FlushErrorState();
3982 
3983  /* Punt the error to Perl */
3984  croak_cstr(edata->message);
3985  }
3986  PG_END_TRY();
3987 }
ErrorData * CopyErrorData(void)
Definition: elog.c:1584
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void FlushErrorState(void)
Definition: elog.c:1678
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
void SPI_commit(void)
Definition: spi.c:278
static void croak_cstr(const char *str)
#define PG_CATCH()
Definition: elog.h:332
void SPI_start_transaction(void)
Definition: spi.c:212
#define PG_TRY()
Definition: elog.h:322
#define PG_END_TRY()
Definition: elog.h:347
char * message
Definition: elog.h:392

◆ plperl_spi_cursor_close()

void plperl_spi_cursor_close ( char *  )

Definition at line 3525 of file plperl.c.

References check_spi_usage_allowed(), SPI_cursor_close(), SPI_cursor_find(), and UnpinPortal().

3526 {
3527  Portal p;
3528 
3530 
3531  p = SPI_cursor_find(cursor);
3532 
3533  if (p)
3534  {
3535  UnpinPortal(p);
3536  SPI_cursor_close(p);
3537  }
3538 }
void UnpinPortal(Portal portal)
Definition: portalmem.c:377
Portal SPI_cursor_find(const char *name)
Definition: spi.c:1527
Definition: type.h:130
static void check_spi_usage_allowed(void)
Definition: plperl.c:3097
void SPI_cursor_close(Portal portal)
Definition: spi.c:1595

◆ plperl_spi_exec()

HV* plperl_spi_exec ( char *  ,
int   
)

Definition at line 3109 of file plperl.c.

References BeginInternalSubTransaction(), check_spi_usage_allowed(), CopyErrorData(), croak_cstr(), CurrentMemoryContext, CurrentResourceOwner, FlushErrorState(), plperl_proc_desc::fn_readonly, MemoryContextSwitchTo(), ErrorData::message, PG_CATCH, PG_END_TRY, PG_TRY, pg_verifymbstr(), plperl_spi_execute_fetch_result(), plperl_call_data::prodesc, ReleaseCurrentSubTransaction(), RollbackAndReleaseCurrentSubTransaction(), SPI_execute(), SPI_processed, and SPI_tuptable.

3110 {
3111  HV *ret_hv;
3112 
3113  /*
3114  * Execute the query inside a sub-transaction, so we can cope with errors
3115  * sanely
3116  */
3117  MemoryContext oldcontext = CurrentMemoryContext;
3119 
3121 
3123  /* Want to run inside function's memory context */
3124  MemoryContextSwitchTo(oldcontext);
3125 
3126  PG_TRY();
3127  {
3128  int spi_rv;
3129 
3130  pg_verifymbstr(query, strlen(query), false);
3131 
3133  limit);
3135  spi_rv);
3136 
3137  /* Commit the inner transaction, return to outer xact context */
3139  MemoryContextSwitchTo(oldcontext);
3140  CurrentResourceOwner = oldowner;
3141  }
3142  PG_CATCH();
3143  {
3144  ErrorData *edata;
3145 
3146  /* Save error info */
3147  MemoryContextSwitchTo(oldcontext);
3148  edata = CopyErrorData();
3149  FlushErrorState();
3150 
3151  /* Abort the inner transaction */
3153  MemoryContextSwitchTo(oldcontext);
3154  CurrentResourceOwner = oldowner;
3155 
3156  /* Punt the error to Perl */
3157  croak_cstr(edata->message);
3158 
3159  /* Can't get here, but keep compiler quiet */
3160  return NULL;
3161  }
3162  PG_END_TRY();
3163 
3164  return ret_hv;
3165 }
ErrorData * CopyErrorData(void)
Definition: elog.c:1584
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
void ReleaseCurrentSubTransaction(void)
Definition: xact.c:4430
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
SPITupleTable * SPI_tuptable
Definition: spi.c:46
void FlushErrorState(void)
Definition: elog.c:1678
uint64 SPI_processed
Definition: spi.c:45
void RollbackAndReleaseCurrentSubTransaction(void)
Definition: xact.c:4464
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
static void croak_cstr(const char *str)
bool fn_readonly
Definition: plperl.c:111
#define PG_CATCH()
Definition: elog.h:332
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4359
static void check_spi_usage_allowed(void)
Definition: plperl.c:3097
static HV * plperl_spi_execute_fetch_result(SPITupleTable *, uint64, int)
Definition: plperl.c:3169
bool pg_verifymbstr(const char *mbstr, int len, bool noError)
Definition: wchar.c:1914
plperl_proc_desc * prodesc
Definition: plperl.c:175
#define PG_TRY()
Definition: elog.h:322
static plperl_call_data * current_call_data
Definition: plperl.c:243
#define PG_END_TRY()
Definition: elog.h:347
char * message
Definition: elog.h:392
int SPI_execute(const char *src, bool read_only, long tcount)
Definition: spi.c:496

◆ plperl_spi_exec_prepared()

HV* plperl_spi_exec_prepared ( char *  ,
HV *  ,
int  ,
SV **   
)

Definition at line 3689 of file plperl.c.

References plperl_query_desc::arginfuncs, plperl_query_desc::argtypes, plperl_query_desc::argtypioparams, BeginInternalSubTransaction(), check_spi_usage_allowed(), CopyErrorData(), croak_cstr(), CurrentMemoryContext, CurrentResourceOwner, dTHX, elog, ERROR, FlushErrorState(), plperl_proc_desc::fn_readonly, HASH_FIND, hash_search(), hv_fetch_string(), i, MemoryContextSwitchTo(), ErrorData::message, plperl_query_desc::nargs, palloc(), pfree(), PG_CATCH, PG_END_TRY, PG_TRY, plperl_query_desc::plan, plperl_spi_execute_fetch_result(), plperl_sv_to_datum(), plperl_call_data::prodesc, plperl_query_entry::query_data, plperl_interp_desc::query_hash, ReleaseCurrentSubTransaction(), RollbackAndReleaseCurrentSubTransaction(), SPI_execute_plan(), SPI_processed, and SPI_tuptable.

3690 {
3691  HV *ret_hv;
3692  SV **sv;
3693  int i,
3694  limit,
3695  spi_rv;
3696  char *nulls;
3697  Datum *argvalues;
3698  plperl_query_desc *qdesc;
3699  plperl_query_entry *hash_entry;
3700 
3701  /*
3702  * Execute the query inside a sub-transaction, so we can cope with errors
3703  * sanely
3704  */
3705  MemoryContext oldcontext = CurrentMemoryContext;
3707 
3709 
3711  /* Want to run inside function's memory context */
3712  MemoryContextSwitchTo(oldcontext);
3713 
3714  PG_TRY();
3715  {
3716  dTHX;
3717 
3718  /************************************************************
3719  * Fetch the saved plan descriptor, see if it's o.k.
3720  ************************************************************/
3721  hash_entry = hash_search(plperl_active_interp->query_hash, query,
3722  HASH_FIND, NULL);
3723  if (hash_entry == NULL)
3724  elog(ERROR, "spi_exec_prepared: Invalid prepared query passed");
3725 
3726  qdesc = hash_entry->query_data;
3727  if (qdesc == NULL)
3728  elog(ERROR, "spi_exec_prepared: plperl query_hash value vanished");
3729 
3730  if (qdesc->nargs != argc)
3731  elog(ERROR, "spi_exec_prepared: expected %d argument(s), %d passed",
3732  qdesc->nargs, argc);
3733 
3734  /************************************************************
3735  * Parse eventual attributes
3736  ************************************************************/
3737  limit = 0;
3738  if (attr != NULL)
3739  {
3740  sv = hv_fetch_string(attr, "limit");
3741  if (sv && *sv && SvIOK(*sv))
3742  limit = SvIV(*sv);
3743  }
3744  /************************************************************
3745  * Set up arguments
3746  ************************************************************/
3747  if (argc > 0)
3748  {
3749  nulls = (char *) palloc(argc);
3750  argvalues = (Datum *) palloc(argc * sizeof(Datum));
3751  }
3752  else
3753  {
3754  nulls = NULL;
3755  argvalues = NULL;
3756  }
3757 
3758  for (i = 0; i < argc; i++)
3759  {
3760  bool isnull;
3761 
3762  argvalues[i] = plperl_sv_to_datum(argv[i],
3763  qdesc->argtypes[i],
3764  -1,
3765  NULL,
3766  &qdesc->arginfuncs[i],
3767  qdesc->argtypioparams[i],
3768  &isnull);
3769  nulls[i] = isnull ? 'n' : ' ';
3770  }
3771 
3772  /************************************************************
3773  * go
3774  ************************************************************/
3775  spi_rv = SPI_execute_plan(qdesc->plan, argvalues, nulls,
3778  spi_rv);
3779  if (argc > 0)
3780  {
3781  pfree(argvalues);
3782  pfree(nulls);
3783  }
3784 
3785  /* Commit the inner transaction, return to outer xact context */
3787  MemoryContextSwitchTo(oldcontext);
3788  CurrentResourceOwner = oldowner;
3789  }
3790  PG_CATCH();
3791  {
3792  ErrorData *edata;
3793 
3794  /* Save error info */
3795  MemoryContextSwitchTo(oldcontext);
3796  edata = CopyErrorData();
3797  FlushErrorState();
3798 
3799  /* Abort the inner transaction */
3801  MemoryContextSwitchTo(oldcontext);
3802  CurrentResourceOwner = oldowner;
3803 
3804  /* Punt the error to Perl */
3805  croak_cstr(edata->message);
3806 
3807  /* Can't get here, but keep compiler quiet */
3808  return NULL;
3809  }
3810  PG_END_TRY();
3811 
3812  return ret_hv;
3813 }
Definition: plperl.c:201
static Datum plperl_sv_to_datum(SV *sv, Oid typid, int32 typmod, FunctionCallInfo fcinfo, FmgrInfo *finfo, Oid typioparam, bool *isnull)
Definition: plperl.c:1310
HTAB * query_hash
Definition: plperl.c:89
#define dTHX
Definition: ppport.h:3208
SPIPlanPtr plan
Definition: plperl.c:192
ErrorData * CopyErrorData(void)
Definition: elog.c:1584
Oid * argtypioparams
Definition: plperl.c:196
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
void ReleaseCurrentSubTransaction(void)
Definition: xact.c:4430
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
SPITupleTable * SPI_tuptable
Definition: spi.c:46
static SV ** hv_fetch_string(HV *hv, const char *key)
Definition: plperl.c:4087
static plperl_interp_desc * plperl_active_interp
Definition: plperl.c:227
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:906
void FlushErrorState(void)
Definition: elog.c:1678
uint64 SPI_processed
Definition: spi.c:45
void pfree(void *pointer)
Definition: mcxt.c:1056
#define ERROR
Definition: elog.h:43
int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only, long tcount)
Definition: spi.c:531
void RollbackAndReleaseCurrentSubTransaction(void)
Definition: xact.c:4464
Oid * argtypes
Definition: plperl.c:194
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
uintptr_t Datum
Definition: postgres.h:367
FmgrInfo * arginfuncs
Definition: plperl.c:195
static void croak_cstr(const char *str)
bool fn_readonly
Definition: plperl.c:111
#define PG_CATCH()
Definition: elog.h:332
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4359
static void check_spi_usage_allowed(void)
Definition: plperl.c:3097
void * palloc(Size size)
Definition: mcxt.c:949
#define elog(elevel,...)
Definition: elog.h:228
int i
static HV * plperl_spi_execute_fetch_result(SPITupleTable *, uint64, int)
Definition: plperl.c:3169
plperl_proc_desc * prodesc
Definition: plperl.c:175
#define PG_TRY()
Definition: elog.h:322
static plperl_call_data * current_call_data
Definition: plperl.c:243
#define PG_END_TRY()
Definition: elog.h:347
char * message
Definition: elog.h:392
plperl_query_desc * query_data
Definition: plperl.c:204

◆ plperl_spi_fetchrow()

SV* plperl_spi_fetchrow ( char *  )

Definition at line 3450 of file plperl.c.

References BeginInternalSubTransaction(), check_spi_usage_allowed(), CopyErrorData(), croak_cstr(), CurrentMemoryContext, CurrentResourceOwner, dTHX, FlushErrorState(), MemoryContextSwitchTo(), ErrorData::message, PG_CATCH, PG_END_TRY, PG_TRY, PL_sv_undef, plperl_hash_from_tuple(), ReleaseCurrentSubTransaction(), RollbackAndReleaseCurrentSubTransaction(), SPI_cursor_close(), SPI_cursor_fetch(), SPI_cursor_find(), SPI_freetuptable(), SPI_processed, SPI_tuptable, SPITupleTable::tupdesc, UnpinPortal(), and SPITupleTable::vals.

3451 {
3452  SV *row;
3453 
3454  /*
3455  * Execute the FETCH inside a sub-transaction, so we can cope with errors
3456  * sanely
3457  */
3458  MemoryContext oldcontext = CurrentMemoryContext;
3460 
3462 
3464  /* Want to run inside function's memory context */
3465  MemoryContextSwitchTo(oldcontext);
3466 
3467  PG_TRY();
3468  {
3469  dTHX;
3471 
3472  if (!p)
3473  {
3474  row = &PL_sv_undef;
3475  }
3476  else
3477  {
3478  SPI_cursor_fetch(p, true, 1);
3479  if (SPI_processed == 0)
3480  {
3481  UnpinPortal(p);
3482  SPI_cursor_close(p);
3483  row = &PL_sv_undef;
3484  }
3485  else
3486  {
3489  true);
3490  }
3492  }
3493 
3494  /* Commit the inner transaction, return to outer xact context */
3496  MemoryContextSwitchTo(oldcontext);
3497  CurrentResourceOwner = oldowner;
3498  }
3499  PG_CATCH();
3500  {
3501  ErrorData *edata;
3502 
3503  /* Save error info */
3504  MemoryContextSwitchTo(oldcontext);
3505  edata = CopyErrorData();
3506  FlushErrorState();
3507 
3508  /* Abort the inner transaction */
3510  MemoryContextSwitchTo(oldcontext);
3511  CurrentResourceOwner = oldowner;
3512 
3513  /* Punt the error to Perl */
3514  croak_cstr(edata->message);
3515 
3516  /* Can't get here, but keep compiler quiet */
3517  return NULL;
3518  }
3519  PG_END_TRY();
3520 
3521  return row;
3522 }
void UnpinPortal(Portal portal)
Definition: portalmem.c:377
#define dTHX
Definition: ppport.h:3208
ErrorData * CopyErrorData(void)
Definition: elog.c:1584
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
void ReleaseCurrentSubTransaction(void)
Definition: xact.c:4430
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
SPITupleTable * SPI_tuptable
Definition: spi.c:46
#define PL_sv_undef
Definition: ppport.h:4129
HeapTuple * vals
Definition: spi.h:26
void FlushErrorState(void)
Definition: elog.c:1678
uint64 SPI_processed
Definition: spi.c:45
Portal SPI_cursor_find(const char *name)
Definition: spi.c:1527
void RollbackAndReleaseCurrentSubTransaction(void)
Definition: xact.c:4464
Definition: type.h:130
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
void SPI_freetuptable(SPITupleTable *tuptable)
Definition: spi.c:1162
static void croak_cstr(const char *str)
TupleDesc tupdesc
Definition: spi.h:25
#define PG_CATCH()
Definition: elog.h:332
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4359
static void check_spi_usage_allowed(void)
Definition: plperl.c:3097
void SPI_cursor_close(Portal portal)
Definition: spi.c:1595
static SV * plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc, bool include_generated)
Definition: plperl.c:3017
void SPI_cursor_fetch(Portal portal, bool forward, long count)
Definition: spi.c:1539
#define PG_TRY()
Definition: elog.h:322
#define PG_END_TRY()
Definition: elog.h:347
char * message
Definition: elog.h:392

◆ plperl_spi_freeplan()

void plperl_spi_freeplan ( char *  )

Definition at line 3934 of file plperl.c.

References check_spi_usage_allowed(), elog, ERROR, HASH_FIND, HASH_REMOVE, hash_search(), MemoryContextDelete(), plperl_query_desc::plan, plperl_query_desc::plan_cxt, plperl_query_entry::query_data, plperl_interp_desc::query_hash, and SPI_freeplan().

3935 {
3936  SPIPlanPtr plan;
3937  plperl_query_desc *qdesc;
3938  plperl_query_entry *hash_entry;
3939 
3941 
3942  hash_entry = hash_search(plperl_active_interp->query_hash, query,
3943  HASH_FIND, NULL);
3944  if (hash_entry == NULL)
3945  elog(ERROR, "spi_freeplan: Invalid prepared query passed");
3946 
3947  qdesc = hash_entry->query_data;
3948  if (qdesc == NULL)
3949  elog(ERROR, "spi_freeplan: plperl query_hash value vanished");
3950  plan = qdesc->plan;
3951 
3952  /*
3953  * free all memory before SPI_freeplan, so if it dies, nothing will be
3954  * left over
3955  */
3957  HASH_REMOVE, NULL);
3958 
3959  MemoryContextDelete(qdesc->plan_cxt);
3960 
3961  SPI_freeplan(plan);
3962 }
Definition: plperl.c:201
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:211
HTAB * query_hash
Definition: plperl.c:89
SPIPlanPtr plan
Definition: plperl.c:192
static plperl_interp_desc * plperl_active_interp
Definition: plperl.c:227
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:906
#define ERROR
Definition: elog.h:43
MemoryContext plan_cxt
Definition: plperl.c:191
static void check_spi_usage_allowed(void)
Definition: plperl.c:3097
int SPI_freeplan(SPIPlanPtr plan)
Definition: spi.c:801
#define elog(elevel,...)
Definition: elog.h:228
plperl_query_desc * query_data
Definition: plperl.c:204

◆ plperl_spi_prepare()

SV* plperl_spi_prepare ( char *  ,
int  ,
SV **   
)

Definition at line 3541 of file plperl.c.

References ALLOCSET_DEFAULT_SIZES, ALLOCSET_SMALL_SIZES, AllocSetContextCreate, plperl_query_desc::arginfuncs, plperl_query_desc::argtypes, plperl_query_desc::argtypioparams, BeginInternalSubTransaction(), CHECK_FOR_INTERRUPTS, check_spi_usage_allowed(), CopyErrorData(), croak_cstr(), cstr2sv(), CurrentMemoryContext, CurrentResourceOwner, elog, ERROR, FlushErrorState(), fmgr_info_cxt(), getTypeInputInfo(), HASH_ENTER, HASH_REMOVE, hash_search(), i, MemoryContextDelete(), MemoryContextSwitchTo(), ErrorData::message, plperl_query_desc::nargs, palloc(), palloc0(), parseTypeString(), pfree(), PG_CATCH, PG_END_TRY, PG_TRY, pg_verifymbstr(), plperl_query_desc::plan, plperl_query_desc::plan_cxt, plperl_query_desc::qname, plperl_query_entry::query_data, plperl_interp_desc::query_hash, ReleaseCurrentSubTransaction(), RollbackAndReleaseCurrentSubTransaction(), snprintf, SPI_freeplan(), SPI_keepplan(), SPI_prepare(), SPI_result, SPI_result_code_string(), sv2cstr(), and TopMemoryContext.

3542 {
3543  volatile SPIPlanPtr plan = NULL;
3544  volatile MemoryContext plan_cxt = NULL;
3545  plperl_query_desc *volatile qdesc = NULL;
3546  plperl_query_entry *volatile hash_entry = NULL;
3547  MemoryContext oldcontext = CurrentMemoryContext;
3549  MemoryContext work_cxt;
3550  bool found;
3551  int i;
3552 
3554 
3556  MemoryContextSwitchTo(oldcontext);
3557 
3558  PG_TRY();
3559  {
3561 
3562  /************************************************************
3563  * Allocate the new querydesc structure
3564  *
3565  * The qdesc struct, as well as all its subsidiary data, lives in its
3566  * plan_cxt. But note that the SPIPlan does not.
3567  ************************************************************/
3569  "PL/Perl spi_prepare query",
3571  MemoryContextSwitchTo(plan_cxt);
3572  qdesc = (plperl_query_desc *) palloc0(sizeof(plperl_query_desc));
3573  snprintf(qdesc->qname, sizeof(qdesc->qname), "%p", qdesc);
3574  qdesc->plan_cxt = plan_cxt;
3575  qdesc->nargs = argc;
3576  qdesc->argtypes = (Oid *) palloc(argc * sizeof(Oid));
3577  qdesc->arginfuncs = (FmgrInfo *) palloc(argc * sizeof(FmgrInfo));
3578  qdesc->argtypioparams = (Oid *) palloc(argc * sizeof(Oid));
3579  MemoryContextSwitchTo(oldcontext);
3580 
3581  /************************************************************
3582  * Do the following work in a short-lived context so that we don't
3583  * leak a lot of memory in the PL/Perl function's SPI Proc context.
3584  ************************************************************/
3586  "PL/Perl spi_prepare workspace",
3588  MemoryContextSwitchTo(work_cxt);
3589 
3590  /************************************************************
3591  * Resolve argument type names and then look them up by oid
3592  * in the system cache, and remember the required information
3593  * for input conversion.
3594  ************************************************************/
3595  for (i = 0; i < argc; i++)
3596  {
3597  Oid typId,
3598  typInput,
3599  typIOParam;
3600  int32 typmod;
3601  char *typstr;
3602 
3603  typstr = sv2cstr(argv[i]);
3604  parseTypeString(typstr, &typId, &typmod, false);
3605  pfree(typstr);
3606 
3607  getTypeInputInfo(typId, &typInput, &typIOParam);
3608 
3609  qdesc->argtypes[i] = typId;
3610  fmgr_info_cxt(typInput, &(qdesc->arginfuncs[i]), plan_cxt);
3611  qdesc->argtypioparams[i] = typIOParam;
3612  }
3613 
3614  /* Make sure the query is validly encoded */
3615  pg_verifymbstr(query, strlen(query), false);
3616 
3617  /************************************************************
3618  * Prepare the plan and check for errors
3619  ************************************************************/
3620  plan = SPI_prepare(query, argc, qdesc->argtypes);
3621 
3622  if (plan == NULL)
3623  elog(ERROR, "SPI_prepare() failed:%s",
3625 
3626  /************************************************************
3627  * Save the plan into permanent memory (right now it's in the
3628  * SPI procCxt, which will go away at function end).
3629  ************************************************************/
3630  if (SPI_keepplan(plan))
3631  elog(ERROR, "SPI_keepplan() failed");
3632  qdesc->plan = plan;
3633 
3634  /************************************************************
3635  * Insert a hashtable entry for the plan.
3636  ************************************************************/
3638  qdesc->qname,
3639  HASH_ENTER, &found);
3640  hash_entry->query_data = qdesc;
3641 
3642  /* Get rid of workspace */
3643  MemoryContextDelete(work_cxt);
3644 
3645  /* Commit the inner transaction, return to outer xact context */
3647  MemoryContextSwitchTo(oldcontext);
3648  CurrentResourceOwner = oldowner;
3649  }
3650  PG_CATCH();
3651  {
3652  ErrorData *edata;
3653 
3654  /* Save error info */
3655  MemoryContextSwitchTo(oldcontext);
3656  edata = CopyErrorData();
3657  FlushErrorState();
3658 
3659  /* Drop anything we managed to allocate */
3660  if (hash_entry)
3662  qdesc->qname,
3663  HASH_REMOVE, NULL);
3664  if (plan_cxt)
3665  MemoryContextDelete(plan_cxt);
3666  if (plan)
3667  SPI_freeplan(plan);
3668 
3669  /* Abort the inner transaction */
3671  MemoryContextSwitchTo(oldcontext);
3672  CurrentResourceOwner = oldowner;
3673 
3674  /* Punt the error to Perl */
3675  croak_cstr(edata->message);
3676 
3677  /* Can't get here, but keep compiler quiet */
3678  return NULL;
3679  }
3680  PG_END_TRY();
3681 
3682  /************************************************************
3683  * Return the query's hash key to the caller.
3684  ************************************************************/
3685  return cstr2sv(qdesc->qname);
3686 }
Definition: fmgr.h:56
Definition: plperl.c:201
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:211
#define AllocSetContextCreate
Definition: memutils.h:170
HTAB * query_hash
Definition: plperl.c:89
SPIPlanPtr plan
Definition: plperl.c:192
ErrorData * CopyErrorData(void)
Definition: elog.c:1584
Oid * argtypioparams
Definition: plperl.c:196
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes)
Definition: spi.c:674
#define ALLOCSET_SMALL_SIZES
Definition: memutils.h:202
void ReleaseCurrentSubTransaction(void)
Definition: xact.c:4430
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static plperl_interp_desc * plperl_active_interp
Definition: plperl.c:227
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:906
unsigned int Oid
Definition: postgres_ext.h:31
void FlushErrorState(void)
Definition: elog.c:1678
signed int int32
Definition: c.h:347
int SPI_result
Definition: spi.c:47
void pfree(void *pointer)
Definition: mcxt.c:1056
#define ERROR
Definition: elog.h:43
const char * SPI_result_code_string(int code)
Definition: spi.c:1705
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:192
int SPI_keepplan(SPIPlanPtr plan)
Definition: spi.c:752
void RollbackAndReleaseCurrentSubTransaction(void)
Definition: xact.c:4464
Oid * argtypes
Definition: plperl.c:194
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
MemoryContext plan_cxt
Definition: plperl.c:191
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:134
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition: lsyscache.c:2641
MemoryContext TopMemoryContext
Definition: mcxt.c:44
void * palloc0(Size size)
Definition: mcxt.c:980
char qname[24]
Definition: plperl.c:190
FmgrInfo * arginfuncs
Definition: plperl.c:195
static void croak_cstr(const char *str)
static SV * cstr2sv(const char *str)
void parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p, bool missing_ok)
Definition: parse_type.c:832
#define PG_CATCH()
Definition: elog.h:332
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4359
static void check_spi_usage_allowed(void)
Definition: plperl.c:3097
int SPI_freeplan(SPIPlanPtr plan)
Definition: spi.c:801
void * palloc(Size size)
Definition: mcxt.c:949
#define elog(elevel,...)
Definition: elog.h:228
int i
bool pg_verifymbstr(const char *mbstr, int len, bool noError)
Definition: wchar.c:1914
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
#define PG_TRY()
Definition: elog.h:322
#define snprintf
Definition: port.h:192
#define PG_END_TRY()
Definition: elog.h:347
char * message
Definition: elog.h:392
static char * sv2cstr(SV *sv)
plperl_query_desc * query_data
Definition: plperl.c:204

◆ plperl_spi_query()

SV* plperl_spi_query ( char *  )

Definition at line 3378 of file plperl.c.

References BeginInternalSubTransaction(), check_spi_usage_allowed(), CopyErrorData(), croak_cstr(), cstr2sv(), CurrentMemoryContext, CurrentResourceOwner, elog, ERROR, FlushErrorState(), MemoryContextSwitchTo(), ErrorData::message, PortalData::name, PG_CATCH, PG_END_TRY, PG_TRY, pg_verifymbstr(), PinPortal(), ReleaseCurrentSubTransaction(), RollbackAndReleaseCurrentSubTransaction(), SPI_cursor_open(), SPI_freeplan(), SPI_prepare(), SPI_result, and SPI_result_code_string().

3379 {
3380  SV *cursor;
3381 
3382  /*
3383  * Execute the query inside a sub-transaction, so we can cope with errors
3384  * sanely
3385  */
3386  MemoryContext oldcontext = CurrentMemoryContext;
3388 
3390 
3392  /* Want to run inside function's memory context */
3393  MemoryContextSwitchTo(oldcontext);
3394 
3395  PG_TRY();
3396  {
3397  SPIPlanPtr plan;
3398  Portal portal;
3399 
3400  /* Make sure the query is validly encoded */
3401  pg_verifymbstr(query, strlen(query), false);
3402 
3403  /* Create a cursor for the query */
3404  plan = SPI_prepare(query, 0, NULL);
3405  if (plan == NULL)
3406  elog(ERROR, "SPI_prepare() failed:%s",
3408 
3409  portal = SPI_cursor_open(NULL, plan, NULL, NULL, false);
3410  SPI_freeplan(plan);
3411  if (portal == NULL)
3412  elog(ERROR, "SPI_cursor_open() failed:%s",
3414  cursor = cstr2sv(portal->name);
3415 
3416  PinPortal(portal);
3417 
3418  /* Commit the inner transaction, return to outer xact context */
3420  MemoryContextSwitchTo(oldcontext);
3421  CurrentResourceOwner = oldowner;
3422  }
3423  PG_CATCH();
3424  {
3425  ErrorData *edata;
3426 
3427  /* Save error info */
3428  MemoryContextSwitchTo(oldcontext);
3429  edata = CopyErrorData();
3430  FlushErrorState();
3431 
3432  /* Abort the inner transaction */
3434  MemoryContextSwitchTo(oldcontext);
3435  CurrentResourceOwner = oldowner;
3436 
3437  /* Punt the error to Perl */
3438  croak_cstr(edata->message);
3439 
3440  /* Can't get here, but keep compiler quiet */
3441  return NULL;
3442  }
3443  PG_END_TRY();
3444 
3445  return cursor;
3446 }
ErrorData * CopyErrorData(void)
Definition: elog.c:1584
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes)
Definition: spi.c:674
void ReleaseCurrentSubTransaction(void)
Definition: xact.c:4430
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only)
Definition: spi.c:1221
void FlushErrorState(void)
Definition: elog.c:1678
int SPI_result
Definition: spi.c:47
const char * name
Definition: portal.h:117
#define ERROR
Definition: elog.h:43
const char * SPI_result_code_string(int code)
Definition: spi.c:1705
void RollbackAndReleaseCurrentSubTransaction(void)
Definition: xact.c:4464
void PinPortal(Portal portal)
Definition: portalmem.c:368
Definition: type.h:130
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
static void croak_cstr(const char *str)
static SV * cstr2sv(const char *str)
#define PG_CATCH()
Definition: elog.h:332
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4359
static void check_spi_usage_allowed(void)
Definition: plperl.c:3097
int SPI_freeplan(SPIPlanPtr plan)
Definition: spi.c:801
#define elog(elevel,...)
Definition: elog.h:228
bool pg_verifymbstr(const char *mbstr, int len, bool noError)
Definition: wchar.c:1914
#define PG_TRY()
Definition: elog.h:322
#define PG_END_TRY()
Definition: elog.h:347
char * message
Definition: elog.h:392

◆ plperl_spi_query_prepared()

SV* plperl_spi_query_prepared ( char *  ,
int  ,
SV **   
)

Definition at line 3816 of file plperl.c.

References plperl_query_desc::arginfuncs, plperl_query_desc::argtypes, plperl_query_desc::argtypioparams, BeginInternalSubTransaction(), check_spi_usage_allowed(), CopyErrorData(), croak_cstr(), cstr2sv(), CurrentMemoryContext, CurrentResourceOwner, elog, ERROR, FlushErrorState(), plperl_proc_desc::fn_readonly, HASH_FIND, hash_search(), i, MemoryContextSwitchTo(), ErrorData::message, PortalData::name, plperl_query_desc::nargs, palloc(), pfree(), PG_CATCH, PG_END_TRY, PG_TRY, PinPortal(), plperl_query_desc::plan, plperl_sv_to_datum(), plperl_call_data::prodesc, plperl_query_entry::query_data, plperl_interp_desc::query_hash, ReleaseCurrentSubTransaction(), RollbackAndReleaseCurrentSubTransaction(), SPI_cursor_open(), SPI_result, and SPI_result_code_string().

3817 {
3818  int i;
3819  char *nulls;
3820  Datum *argvalues;
3821  plperl_query_desc *qdesc;
3822  plperl_query_entry *hash_entry;
3823  SV *cursor;
3824  Portal portal = NULL;
3825 
3826  /*
3827  * Execute the query inside a sub-transaction, so we can cope with errors
3828  * sanely
3829  */
3830  MemoryContext oldcontext = CurrentMemoryContext;
3832 
3834 
3836  /* Want to run inside function's memory context */
3837  MemoryContextSwitchTo(oldcontext);
3838 
3839  PG_TRY();
3840  {
3841  /************************************************************
3842  * Fetch the saved plan descriptor, see if it's o.k.
3843  ************************************************************/
3844  hash_entry = hash_search(plperl_active_interp->query_hash, query,
3845  HASH_FIND, NULL);
3846  if (hash_entry == NULL)
3847  elog(ERROR, "spi_query_prepared: Invalid prepared query passed");
3848 
3849  qdesc = hash_entry->query_data;
3850  if (qdesc == NULL)
3851  elog(ERROR, "spi_query_prepared: plperl query_hash value vanished");
3852 
3853  if (qdesc->nargs != argc)
3854  elog(ERROR, "spi_query_prepared: expected %d argument(s), %d passed",
3855  qdesc->nargs, argc);
3856 
3857  /************************************************************
3858  * Set up arguments
3859  ************************************************************/
3860  if (argc > 0)
3861  {
3862  nulls = (char *) palloc(argc);
3863  argvalues = (Datum *) palloc(argc * sizeof(Datum));
3864  }
3865  else
3866  {
3867  nulls = NULL;
3868  argvalues = NULL;
3869  }
3870 
3871  for (i = 0; i < argc; i++)
3872  {
3873  bool isnull;
3874 
3875  argvalues[i] = plperl_sv_to_datum(argv[i],
3876  qdesc->argtypes[i],
3877  -1,
3878  NULL,
3879  &qdesc->arginfuncs[i],
3880  qdesc->argtypioparams[i],
3881  &isnull);
3882  nulls[i] = isnull ? 'n' : ' ';
3883  }
3884 
3885  /************************************************************
3886  * go
3887  ************************************************************/
3888  portal = SPI_cursor_open(NULL, qdesc->plan, argvalues, nulls,
3890  if (argc > 0)
3891  {
3892  pfree(argvalues);
3893  pfree(nulls);
3894  }
3895  if (portal == NULL)
3896  elog(ERROR, "SPI_cursor_open() failed:%s",
3898 
3899  cursor = cstr2sv(portal->name);
3900 
3901  PinPortal(portal);
3902 
3903  /* Commit the inner transaction, return to outer xact context */
3905  MemoryContextSwitchTo(oldcontext);
3906  CurrentResourceOwner = oldowner;
3907  }
3908  PG_CATCH();
3909  {
3910  ErrorData *edata;
3911 
3912  /* Save error info */
3913  MemoryContextSwitchTo(oldcontext);
3914  edata = CopyErrorData();
3915  FlushErrorState();
3916 
3917  /* Abort the inner transaction */
3919  MemoryContextSwitchTo(oldcontext);
3920  CurrentResourceOwner = oldowner;
3921 
3922  /* Punt the error to Perl */
3923  croak_cstr(edata->message);
3924 
3925  /* Can't get here, but keep compiler quiet */
3926  return NULL;
3927  }
3928  PG_END_TRY();
3929 
3930  return cursor;
3931 }
Definition: plperl.c:201
static Datum plperl_sv_to_datum(SV *sv, Oid typid, int32 typmod, FunctionCallInfo fcinfo, FmgrInfo *finfo, Oid typioparam, bool *isnull)
Definition: plperl.c:1310
HTAB * query_hash
Definition: plperl.c:89
SPIPlanPtr plan
Definition: plperl.c:192
ErrorData * CopyErrorData(void)
Definition: elog.c:1584
Oid * argtypioparams
Definition: plperl.c:196
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
void ReleaseCurrentSubTransaction(void)
Definition: xact.c:4430
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static plperl_interp_desc * plperl_active_interp
Definition: plperl.c:227
Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only)
Definition: spi.c:1221
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:906
void FlushErrorState(void)
Definition: elog.c:1678
int SPI_result
Definition: spi.c:47
void pfree(void *pointer)
Definition: mcxt.c:1056
const char * name
Definition: portal.h:117
#define ERROR
Definition: elog.h:43
const char * SPI_result_code_string(int code)
Definition: spi.c:1705
void RollbackAndReleaseCurrentSubTransaction(void)
Definition: xact.c:4464
void PinPortal(Portal portal)
Definition: portalmem.c:368
Definition: type.h:130
Oid * argtypes
Definition: plperl.c:194
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
uintptr_t Datum
Definition: postgres.h:367
FmgrInfo * arginfuncs
Definition: plperl.c:195
static void croak_cstr(const char *str)
static SV * cstr2sv(const char *str)
bool fn_readonly
Definition: plperl.c:111
#define PG_CATCH()
Definition: elog.h:332
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4359
static void check_spi_usage_allowed(void)
Definition: plperl.c:3097
void * palloc(Size size)
Definition: mcxt.c:949
#define elog(elevel,...)
Definition: elog.h:228
int i
plperl_proc_desc * prodesc
Definition: plperl.c:175
#define PG_TRY()
Definition: elog.h:322
static plperl_call_data * current_call_data
Definition: plperl.c:243
#define PG_END_TRY()
Definition: elog.h:347
char * message
Definition: elog.h:392
plperl_query_desc * query_data
Definition: plperl.c:204

◆ plperl_spi_rollback()

void plperl_spi_rollback ( void  )

Definition at line 3990 of file plperl.c.

References CopyErrorData(), croak_cstr(), CurrentMemoryContext, FlushErrorState(), MemoryContextSwitchTo(), ErrorData::message, PG_CATCH, PG_END_TRY, PG_TRY, SPI_rollback(), and SPI_start_transaction().

3991 {
3992  MemoryContext oldcontext = CurrentMemoryContext;
3993 
3994  PG_TRY();
3995  {
3996  SPI_rollback();
3998  }
3999  PG_CATCH();
4000  {
4001  ErrorData *edata;
4002 
4003  /* Save error info */
4004  MemoryContextSwitchTo(oldcontext);
4005  edata = CopyErrorData();
4006  FlushErrorState();
4007 
4008  /* Punt the error to Perl */
4009  croak_cstr(edata->message);
4010  }
4011  PG_END_TRY();
4012 }
ErrorData * CopyErrorData(void)
Definition: elog.c:1584
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void SPI_rollback(void)
Definition: spi.c:333
void FlushErrorState(void)
Definition: elog.c:1678
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
static void croak_cstr(const char *str)
#define PG_CATCH()
Definition: elog.h:332
void SPI_start_transaction(void)
Definition: spi.c:212
#define PG_TRY()
Definition: elog.h:322
#define PG_END_TRY()
Definition: elog.h:347
char * message
Definition: elog.h:392

◆ plperl_sv_to_literal()

char* plperl_sv_to_literal ( SV *  ,
char *   
)

Definition at line 1431 of file plperl.c.

References CStringGetDatum, DirectFunctionCall1, ereport, errcode(), errmsg(), ERROR, getTypeOutputInfo(), InvalidOid, OidIsValid, OidOutputFunctionCall(), plperl_sv_to_datum(), regtypein(), and generate_unaccent_rules::str.

1432 {
1433  Datum str = CStringGetDatum(fqtypename);
1434  Oid typid = DirectFunctionCall1(regtypein, str);
1435  Oid typoutput;
1436  Datum datum;
1437  bool typisvarlena,
1438  isnull;
1439 
1440  if (!OidIsValid(typid))
1441  ereport(ERROR,
1442  (errcode(ERRCODE_UNDEFINED_OBJECT),
1443  errmsg("lookup failed for type %s", fqtypename)));
1444 
1445  datum = plperl_sv_to_datum(sv,
1446  typid, -1,
1447  NULL, NULL, InvalidOid,
1448  &isnull);
1449 
1450  if (isnull)
1451  return NULL;
1452 
1453  getTypeOutputInfo(typid,
1454  &typoutput, &typisvarlena);
1455 
1456  return OidOutputFunctionCall(typoutput, datum);
1457 }
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2674
static Datum plperl_sv_to_datum(SV *sv, Oid typid, int32 typmod, FunctionCallInfo fcinfo, FmgrInfo *finfo, Oid typioparam, bool *isnull)
Definition: plperl.c:1310
int errcode(int sqlerrcode)
Definition: elog.c:608
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:615
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:645
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:578
#define ereport(elevel, rest)
Definition: elog.h:141
Datum regtypein(PG_FUNCTION_ARGS)
Definition: regproc.c:1061
uintptr_t Datum
Definition: postgres.h:367
#define InvalidOid
Definition: postgres_ext.h:36
char * OidOutputFunctionCall(Oid functionId, Datum val)
Definition: fmgr.c:1655
int errmsg(const char *fmt,...)
Definition: elog.c:822

◆ plperl_util_elog()

void plperl_util_elog ( int  level,
SV *  msg 
)

Definition at line 4026 of file plperl.c.

References CopyErrorData(), croak_cstr(), CurrentMemoryContext, elog, FlushErrorState(), MemoryContextSwitchTo(), ErrorData::message, pfree(), PG_CATCH, PG_END_TRY, PG_TRY, and sv2cstr().

4027 {
4028  MemoryContext oldcontext = CurrentMemoryContext;
4029  char *volatile cmsg = NULL;
4030 
4031  PG_TRY();
4032  {
4033  cmsg = sv2cstr(msg);
4034  elog(level, "%s", cmsg);
4035  pfree(cmsg);
4036  }
4037  PG_CATCH();
4038  {
4039  ErrorData *edata;
4040 
4041  /* Must reset elog.c's state */
4042  MemoryContextSwitchTo(oldcontext);
4043  edata = CopyErrorData();
4044  FlushErrorState();
4045 
4046  if (cmsg)
4047  pfree(cmsg);
4048 
4049  /* Punt the error to Perl */
4050  croak_cstr(edata->message);
4051  }
4052  PG_END_TRY();
4053 }
ErrorData * CopyErrorData(void)
Definition: elog.c:1584
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void FlushErrorState(void)
Definition: elog.c:1678
void pfree(void *pointer)
Definition: mcxt.c:1056
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
static void croak_cstr(const char *str)
#define PG_CATCH()
Definition: elog.h:332
#define elog(elevel,...)
Definition: elog.h:228
#define PG_TRY()
Definition: elog.h:322
#define PG_END_TRY()
Definition: elog.h:347
char * message
Definition: elog.h:392
static char * sv2cstr(SV *sv)