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 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 157 of file plperl.h.

◆ AV_SIZE_MAX

#define AV_SIZE_MAX   I32_MAX

Definition at line 198 of file plperl.h.

Referenced by plperl_spi_execute_fetch_result().

◆ fprintf

#define fprintf   pg_fprintf

Definition at line 145 of file plperl.h.

◆ GvCV_set

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

Definition at line 191 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))
#define SvUTF8(sv)
Definition: ppport.h:16992
#define HEf_SVKEY
Definition: ppport.h:12118

Definition at line 184 of file plperl.h.

Referenced by hek2cstr().

◆ 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 147 of file plperl.h.

◆ snprintf

#define snprintf   pg_snprintf

Definition at line 141 of file plperl.h.

◆ sprintf

#define sprintf   pg_sprintf

Definition at line 143 of file plperl.h.

◆ vfprintf

#define vfprintf   pg_vfprintf

Definition at line 144 of file plperl.h.

◆ vprintf

#define vprintf   pg_vprintf

Definition at line 146 of file plperl.h.

◆ vsnprintf

#define vsnprintf   pg_vsnprintf

Definition at line 140 of file plperl.h.

◆ vsprintf

#define vsprintf   pg_vsprintf

Definition at line 142 of file plperl.h.

Function Documentation

◆ plperl_return_next()

void plperl_return_next ( SV *  )

Definition at line 3211 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().

3212 {
3213  MemoryContext oldcontext = CurrentMemoryContext;
3214 
3215  PG_TRY();
3216  {
3218  }
3219  PG_CATCH();
3220  {
3221  ErrorData *edata;
3222 
3223  /* Must reset elog.c's state */
3224  MemoryContextSwitchTo(oldcontext);
3225  edata = CopyErrorData();
3226  FlushErrorState();
3227 
3228  /* Punt the error to Perl */
3229  croak_cstr(edata->message);
3230  }
3231  PG_END_TRY();
3232 }
ErrorData * CopyErrorData(void)
Definition: elog.c:1560
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void FlushErrorState(void)
Definition: elog.c:1654
MemoryContext CurrentMemoryContext
Definition: mcxt.c:42
static void plperl_return_next_internal(SV *sv)
Definition: plperl.c:3239
static void croak_cstr(const char *str)
#define PG_CATCH()
Definition: elog.h:323
#define PG_TRY()
Definition: elog.h:313
#define PG_END_TRY()
Definition: elog.h:338
char * message
Definition: elog.h:382

◆ plperl_spi_commit()

void plperl_spi_commit ( void  )

Definition at line 3955 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().

3956 {
3957  MemoryContext oldcontext = CurrentMemoryContext;
3958 
3959  PG_TRY();
3960  {
3961  SPI_commit();
3963  }
3964  PG_CATCH();
3965  {
3966  ErrorData *edata;
3967 
3968  /* Save error info */
3969  MemoryContextSwitchTo(oldcontext);
3970  edata = CopyErrorData();
3971  FlushErrorState();
3972 
3973  /* Punt the error to Perl */
3974  croak_cstr(edata->message);
3975  }
3976  PG_END_TRY();
3977 }
ErrorData * CopyErrorData(void)
Definition: elog.c:1560
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void FlushErrorState(void)
Definition: elog.c:1654
MemoryContext CurrentMemoryContext
Definition: mcxt.c:42
void SPI_commit(void)
Definition: spi.c:280
static void croak_cstr(const char *str)
#define PG_CATCH()
Definition: elog.h:323
void SPI_start_transaction(void)
Definition: spi.c:218
#define PG_TRY()
Definition: elog.h:313
#define PG_END_TRY()
Definition: elog.h:338
char * message
Definition: elog.h:382

◆ plperl_spi_cursor_close()

void plperl_spi_cursor_close ( char *  )

Definition at line 3515 of file plperl.c.

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

3516 {
3517  Portal p;
3518 
3520 
3521  p = SPI_cursor_find(cursor);
3522 
3523  if (p)
3524  {
3525  UnpinPortal(p);
3526  SPI_cursor_close(p);
3527  }
3528 }
void UnpinPortal(Portal portal)
Definition: portalmem.c:380
Portal SPI_cursor_find(const char *name)
Definition: spi.c:1699
Definition: type.h:130
static void check_spi_usage_allowed(void)
Definition: plperl.c:3087
void SPI_cursor_close(Portal portal)
Definition: spi.c:1767

◆ plperl_spi_exec()

HV* plperl_spi_exec ( char *  ,
int   
)

Definition at line 3099 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.

3100 {
3101  HV *ret_hv;
3102 
3103  /*
3104  * Execute the query inside a sub-transaction, so we can cope with errors
3105  * sanely
3106  */
3107  MemoryContext oldcontext = CurrentMemoryContext;
3109 
3111 
3113  /* Want to run inside function's memory context */
3114  MemoryContextSwitchTo(oldcontext);
3115 
3116  PG_TRY();
3117  {
3118  int spi_rv;
3119 
3120  pg_verifymbstr(query, strlen(query), false);
3121 
3123  limit);
3125  spi_rv);
3126 
3127  /* Commit the inner transaction, return to outer xact context */
3129  MemoryContextSwitchTo(oldcontext);
3130  CurrentResourceOwner = oldowner;
3131  }
3132  PG_CATCH();
3133  {
3134  ErrorData *edata;
3135 
3136  /* Save error info */
3137  MemoryContextSwitchTo(oldcontext);
3138  edata = CopyErrorData();
3139  FlushErrorState();
3140 
3141  /* Abort the inner transaction */
3143  MemoryContextSwitchTo(oldcontext);
3144  CurrentResourceOwner = oldowner;
3145 
3146  /* Punt the error to Perl */
3147  croak_cstr(edata->message);
3148 
3149  /* Can't get here, but keep compiler quiet */
3150  return NULL;
3151  }
3152  PG_END_TRY();
3153 
3154  return ret_hv;
3155 }
ErrorData * CopyErrorData(void)
Definition: elog.c:1560
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
void ReleaseCurrentSubTransaction(void)
Definition: xact.c:4488
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
SPITupleTable * SPI_tuptable
Definition: spi.c:46
void FlushErrorState(void)
Definition: elog.c:1654
uint64 SPI_processed
Definition: spi.c:45
void RollbackAndReleaseCurrentSubTransaction(void)
Definition: xact.c:4522
MemoryContext CurrentMemoryContext
Definition: mcxt.c:42
static void croak_cstr(const char *str)
bool pg_verifymbstr(const char *mbstr, int len, bool noError)
Definition: mbutils.c:1505
bool fn_readonly
Definition: plperl.c:111
#define PG_CATCH()
Definition: elog.h:323
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4417
static void check_spi_usage_allowed(void)
Definition: plperl.c:3087
static HV * plperl_spi_execute_fetch_result(SPITupleTable *, uint64, int)
Definition: plperl.c:3159
plperl_proc_desc * prodesc
Definition: plperl.c:175
#define PG_TRY()
Definition: elog.h:313
static plperl_call_data * current_call_data
Definition: plperl.c:243
#define PG_END_TRY()
Definition: elog.h:338
char * message
Definition: elog.h:382
int SPI_execute(const char *src, bool read_only, long tcount)
Definition: spi.c:501

◆ plperl_spi_exec_prepared()

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

Definition at line 3679 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.

3680 {
3681  HV *ret_hv;
3682  SV **sv;
3683  int i,
3684  limit,
3685  spi_rv;
3686  char *nulls;
3687  Datum *argvalues;
3688  plperl_query_desc *qdesc;
3689  plperl_query_entry *hash_entry;
3690 
3691  /*
3692  * Execute the query inside a sub-transaction, so we can cope with errors
3693  * sanely
3694  */
3695  MemoryContext oldcontext = CurrentMemoryContext;
3697 
3699 
3701  /* Want to run inside function's memory context */
3702  MemoryContextSwitchTo(oldcontext);
3703 
3704  PG_TRY();
3705  {
3706  dTHX;
3707 
3708  /************************************************************
3709  * Fetch the saved plan descriptor, see if it's o.k.
3710  ************************************************************/
3711  hash_entry = hash_search(plperl_active_interp->query_hash, query,
3712  HASH_FIND, NULL);
3713  if (hash_entry == NULL)
3714  elog(ERROR, "spi_exec_prepared: Invalid prepared query passed");
3715 
3716  qdesc = hash_entry->query_data;
3717  if (qdesc == NULL)
3718  elog(ERROR, "spi_exec_prepared: plperl query_hash value vanished");
3719 
3720  if (qdesc->nargs != argc)
3721  elog(ERROR, "spi_exec_prepared: expected %d argument(s), %d passed",
3722  qdesc->nargs, argc);
3723 
3724  /************************************************************
3725  * Parse eventual attributes
3726  ************************************************************/
3727  limit = 0;
3728  if (attr != NULL)
3729  {
3730  sv = hv_fetch_string(attr, "limit");
3731  if (sv && *sv && SvIOK(*sv))
3732  limit = SvIV(*sv);
3733  }
3734  /************************************************************
3735  * Set up arguments
3736  ************************************************************/
3737  if (argc > 0)
3738  {
3739  nulls = (char *) palloc(argc);
3740  argvalues = (Datum *) palloc(argc * sizeof(Datum));
3741  }
3742  else
3743  {
3744  nulls = NULL;
3745  argvalues = NULL;
3746  }
3747 
3748  for (i = 0; i < argc; i++)
3749  {
3750  bool isnull;
3751 
3752  argvalues[i] = plperl_sv_to_datum(argv[i],
3753  qdesc->argtypes[i],
3754  -1,
3755  NULL,
3756  &qdesc->arginfuncs[i],
3757  qdesc->argtypioparams[i],
3758  &isnull);
3759  nulls[i] = isnull ? 'n' : ' ';
3760  }
3761 
3762  /************************************************************
3763  * go
3764  ************************************************************/
3765  spi_rv = SPI_execute_plan(qdesc->plan, argvalues, nulls,
3768  spi_rv);
3769  if (argc > 0)
3770  {
3771  pfree(argvalues);
3772  pfree(nulls);
3773  }
3774 
3775  /* Commit the inner transaction, return to outer xact context */
3777  MemoryContextSwitchTo(oldcontext);
3778  CurrentResourceOwner = oldowner;
3779  }
3780  PG_CATCH();
3781  {
3782  ErrorData *edata;
3783 
3784  /* Save error info */
3785  MemoryContextSwitchTo(oldcontext);
3786  edata = CopyErrorData();
3787  FlushErrorState();
3788 
3789  /* Abort the inner transaction */
3791  MemoryContextSwitchTo(oldcontext);
3792  CurrentResourceOwner = oldowner;
3793 
3794  /* Punt the error to Perl */
3795  croak_cstr(edata->message);
3796 
3797  /* Can't get here, but keep compiler quiet */
3798  return NULL;
3799  }
3800  PG_END_TRY();
3801 
3802  return ret_hv;
3803 }
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:1307
HTAB * query_hash
Definition: plperl.c:89
#define dTHX
Definition: ppport.h:11306
SPIPlanPtr plan
Definition: plperl.c:192
ErrorData * CopyErrorData(void)
Definition: elog.c:1560
Oid * argtypioparams
Definition: plperl.c:196
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
void ReleaseCurrentSubTransaction(void)
Definition: xact.c:4488
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:4077
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:954
void FlushErrorState(void)
Definition: elog.c:1654
uint64 SPI_processed
Definition: spi.c:45
void pfree(void *pointer)
Definition: mcxt.c:1169
#define ERROR
Definition: elog.h:46
int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only, long tcount)
Definition: spi.c:577
void RollbackAndReleaseCurrentSubTransaction(void)
Definition: xact.c:4522
Oid * argtypes
Definition: plperl.c:194
MemoryContext CurrentMemoryContext
Definition: mcxt.c:42
uintptr_t Datum
Definition: postgres.h:411
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:323
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4417
static void check_spi_usage_allowed(void)
Definition: plperl.c:3087
void * palloc(Size size)
Definition: mcxt.c:1062
#define elog(elevel,...)
Definition: elog.h:232
int i
static HV * plperl_spi_execute_fetch_result(SPITupleTable *, uint64, int)
Definition: plperl.c:3159
plperl_proc_desc * prodesc
Definition: plperl.c:175
#define PG_TRY()
Definition: elog.h:313
static plperl_call_data * current_call_data
Definition: plperl.c:243
#define PG_END_TRY()
Definition: elog.h:338
char * message
Definition: elog.h:382
plperl_query_desc * query_data
Definition: plperl.c:204

◆ plperl_spi_fetchrow()

SV* plperl_spi_fetchrow ( char *  )

Definition at line 3440 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.

3441 {
3442  SV *row;
3443 
3444  /*
3445  * Execute the FETCH inside a sub-transaction, so we can cope with errors
3446  * sanely
3447  */
3448  MemoryContext oldcontext = CurrentMemoryContext;
3450 
3452 
3454  /* Want to run inside function's memory context */
3455  MemoryContextSwitchTo(oldcontext);
3456 
3457  PG_TRY();
3458  {
3459  dTHX;
3461 
3462  if (!p)
3463  {
3464  row = &PL_sv_undef;
3465  }
3466  else
3467  {
3468  SPI_cursor_fetch(p, true, 1);
3469  if (SPI_processed == 0)
3470  {
3471  UnpinPortal(p);
3472  SPI_cursor_close(p);
3473  row = &PL_sv_undef;
3474  }
3475  else
3476  {
3479  true);
3480  }
3482  }
3483 
3484  /* Commit the inner transaction, return to outer xact context */
3486  MemoryContextSwitchTo(oldcontext);
3487  CurrentResourceOwner = oldowner;
3488  }
3489  PG_CATCH();
3490  {
3491  ErrorData *edata;
3492 
3493  /* Save error info */
3494  MemoryContextSwitchTo(oldcontext);
3495  edata = CopyErrorData();
3496  FlushErrorState();
3497 
3498  /* Abort the inner transaction */
3500  MemoryContextSwitchTo(oldcontext);
3501  CurrentResourceOwner = oldowner;
3502 
3503  /* Punt the error to Perl */
3504  croak_cstr(edata->message);
3505 
3506  /* Can't get here, but keep compiler quiet */
3507  return NULL;
3508  }
3509  PG_END_TRY();
3510 
3511  return row;
3512 }
void UnpinPortal(Portal portal)
Definition: portalmem.c:380
#define dTHX
Definition: ppport.h:11306
ErrorData * CopyErrorData(void)
Definition: elog.c:1560
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
void ReleaseCurrentSubTransaction(void)
Definition: xact.c:4488
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
SPITupleTable * SPI_tuptable
Definition: spi.c:46
#define PL_sv_undef
Definition: ppport.h:11780
HeapTuple * vals
Definition: spi.h:26
void FlushErrorState(void)
Definition: elog.c:1654
uint64 SPI_processed
Definition: spi.c:45
Portal SPI_cursor_find(const char *name)
Definition: spi.c:1699
void RollbackAndReleaseCurrentSubTransaction(void)
Definition: xact.c:4522
Definition: type.h:130
MemoryContext CurrentMemoryContext
Definition: mcxt.c:42
void SPI_freetuptable(SPITupleTable *tuptable)
Definition: spi.c:1291
static void croak_cstr(const char *str)
TupleDesc tupdesc
Definition: spi.h:25
#define PG_CATCH()
Definition: elog.h:323
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4417
static void check_spi_usage_allowed(void)
Definition: plperl.c:3087
void SPI_cursor_close(Portal portal)
Definition: spi.c:1767
static SV * plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc, bool include_generated)
Definition: plperl.c:3007
void SPI_cursor_fetch(Portal portal, bool forward, long count)
Definition: spi.c:1711
#define PG_TRY()
Definition: elog.h:313
#define PG_END_TRY()
Definition: elog.h:338
char * message
Definition: elog.h:382

◆ plperl_spi_freeplan()

void plperl_spi_freeplan ( char *  )

Definition at line 3924 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().

3925 {
3926  SPIPlanPtr plan;
3927  plperl_query_desc *qdesc;
3928  plperl_query_entry *hash_entry;
3929 
3931 
3932  hash_entry = hash_search(plperl_active_interp->query_hash, query,
3933  HASH_FIND, NULL);
3934  if (hash_entry == NULL)
3935  elog(ERROR, "spi_freeplan: Invalid prepared query passed");
3936 
3937  qdesc = hash_entry->query_data;
3938  if (qdesc == NULL)
3939  elog(ERROR, "spi_freeplan: plperl query_hash value vanished");
3940  plan = qdesc->plan;
3941 
3942  /*
3943  * free all memory before SPI_freeplan, so if it dies, nothing will be
3944  * left over
3945  */
3947  HASH_REMOVE, NULL);
3948 
3949  MemoryContextDelete(qdesc->plan_cxt);
3950 
3951  SPI_freeplan(plan);
3952 }
Definition: plperl.c:201
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:218
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:954
#define ERROR
Definition: elog.h:46
MemoryContext plan_cxt
Definition: plperl.c:191
static void check_spi_usage_allowed(void)
Definition: plperl.c:3087
int SPI_freeplan(SPIPlanPtr plan)
Definition: spi.c:930
#define elog(elevel,...)
Definition: elog.h:232
plperl_query_desc * query_data
Definition: plperl.c:204

◆ plperl_spi_prepare()

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

Definition at line 3531 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.

3532 {
3533  volatile SPIPlanPtr plan = NULL;
3534  volatile MemoryContext plan_cxt = NULL;
3535  plperl_query_desc *volatile qdesc = NULL;
3536  plperl_query_entry *volatile hash_entry = NULL;
3537  MemoryContext oldcontext = CurrentMemoryContext;
3539  MemoryContext work_cxt;
3540  bool found;
3541  int i;
3542 
3544 
3546  MemoryContextSwitchTo(oldcontext);
3547 
3548  PG_TRY();
3549  {
3551 
3552  /************************************************************
3553  * Allocate the new querydesc structure
3554  *
3555  * The qdesc struct, as well as all its subsidiary data, lives in its
3556  * plan_cxt. But note that the SPIPlan does not.
3557  ************************************************************/
3559  "PL/Perl spi_prepare query",
3561  MemoryContextSwitchTo(plan_cxt);
3562  qdesc = (plperl_query_desc *) palloc0(sizeof(plperl_query_desc));
3563  snprintf(qdesc->qname, sizeof(qdesc->qname), "%p", qdesc);
3564  qdesc->plan_cxt = plan_cxt;
3565  qdesc->nargs = argc;
3566  qdesc->argtypes = (Oid *) palloc(argc * sizeof(Oid));
3567  qdesc->arginfuncs = (FmgrInfo *) palloc(argc * sizeof(FmgrInfo));
3568  qdesc->argtypioparams = (Oid *) palloc(argc * sizeof(Oid));
3569  MemoryContextSwitchTo(oldcontext);
3570 
3571  /************************************************************
3572  * Do the following work in a short-lived context so that we don't
3573  * leak a lot of memory in the PL/Perl function's SPI Proc context.
3574  ************************************************************/
3576  "PL/Perl spi_prepare workspace",
3578  MemoryContextSwitchTo(work_cxt);
3579 
3580  /************************************************************
3581  * Resolve argument type names and then look them up by oid
3582  * in the system cache, and remember the required information
3583  * for input conversion.
3584  ************************************************************/
3585  for (i = 0; i < argc; i++)
3586  {
3587  Oid typId,
3588  typInput,
3589  typIOParam;
3590  int32 typmod;
3591  char *typstr;
3592 
3593  typstr = sv2cstr(argv[i]);
3594  parseTypeString(typstr, &typId, &typmod, false);
3595  pfree(typstr);
3596 
3597  getTypeInputInfo(typId, &typInput, &typIOParam);
3598 
3599  qdesc->argtypes[i] = typId;
3600  fmgr_info_cxt(typInput, &(qdesc->arginfuncs[i]), plan_cxt);
3601  qdesc->argtypioparams[i] = typIOParam;
3602  }
3603 
3604  /* Make sure the query is validly encoded */
3605  pg_verifymbstr(query, strlen(query), false);
3606 
3607  /************************************************************
3608  * Prepare the plan and check for errors
3609  ************************************************************/
3610  plan = SPI_prepare(query, argc, qdesc->argtypes);
3611 
3612  if (plan == NULL)
3613  elog(ERROR, "SPI_prepare() failed:%s",
3615 
3616  /************************************************************
3617  * Save the plan into permanent memory (right now it's in the
3618  * SPI procCxt, which will go away at function end).
3619  ************************************************************/
3620  if (SPI_keepplan(plan))
3621  elog(ERROR, "SPI_keepplan() failed");
3622  qdesc->plan = plan;
3623 
3624  /************************************************************
3625  * Insert a hashtable entry for the plan.
3626  ************************************************************/
3628  qdesc->qname,
3629  HASH_ENTER, &found);
3630  hash_entry->query_data = qdesc;
3631 
3632  /* Get rid of workspace */
3633  MemoryContextDelete(work_cxt);
3634 
3635  /* Commit the inner transaction, return to outer xact context */
3637  MemoryContextSwitchTo(oldcontext);
3638  CurrentResourceOwner = oldowner;
3639  }
3640  PG_CATCH();
3641  {
3642  ErrorData *edata;
3643 
3644  /* Save error info */
3645  MemoryContextSwitchTo(oldcontext);
3646  edata = CopyErrorData();
3647  FlushErrorState();
3648 
3649  /* Drop anything we managed to allocate */
3650  if (hash_entry)
3652  qdesc->qname,
3653  HASH_REMOVE, NULL);
3654  if (plan_cxt)
3655  MemoryContextDelete(plan_cxt);
3656  if (plan)
3657  SPI_freeplan(plan);
3658 
3659  /* Abort the inner transaction */
3661  MemoryContextSwitchTo(oldcontext);
3662  CurrentResourceOwner = oldowner;
3663 
3664  /* Punt the error to Perl */
3665  croak_cstr(edata->message);
3666 
3667  /* Can't get here, but keep compiler quiet */
3668  return NULL;
3669  }
3670  PG_END_TRY();
3671 
3672  /************************************************************
3673  * Return the query's hash key to the caller.
3674  ************************************************************/
3675  return cstr2sv(qdesc->qname);
3676 }
Definition: fmgr.h:56
Definition: plperl.c:201
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:218
#define AllocSetContextCreate
Definition: memutils.h:173
HTAB * query_hash
Definition: plperl.c:89
SPIPlanPtr plan
Definition: plperl.c:192
ErrorData * CopyErrorData(void)
Definition: elog.c:1560
Oid * argtypioparams
Definition: plperl.c:196
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes)
Definition: spi.c:765
#define ALLOCSET_SMALL_SIZES
Definition: memutils.h:205
void ReleaseCurrentSubTransaction(void)
Definition: xact.c:4488
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:954
unsigned int Oid
Definition: postgres_ext.h:31
void FlushErrorState(void)
Definition: elog.c:1654
signed int int32
Definition: c.h:429
int SPI_result
Definition: spi.c:47
void pfree(void *pointer)
Definition: mcxt.c:1169
#define ERROR
Definition: elog.h:46
const char * SPI_result_code_string(int code)
Definition: spi.c:1877
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:195
int SPI_keepplan(SPIPlanPtr plan)
Definition: spi.c:881
void RollbackAndReleaseCurrentSubTransaction(void)
Definition: xact.c:4522
Oid * argtypes
Definition: plperl.c:194
MemoryContext CurrentMemoryContext
Definition: mcxt.c:42
MemoryContext plan_cxt
Definition: plperl.c:191
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:136
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition: lsyscache.c:2821
MemoryContext TopMemoryContext
Definition: mcxt.c:48
void * palloc0(Size size)
Definition: mcxt.c:1093
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:782
bool pg_verifymbstr(const char *mbstr, int len, bool noError)
Definition: mbutils.c:1505
#define PG_CATCH()
Definition: elog.h:323
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4417
static void check_spi_usage_allowed(void)
Definition: plperl.c:3087
int SPI_freeplan(SPIPlanPtr plan)
Definition: spi.c:930
void * palloc(Size size)
Definition: mcxt.c:1062
#define elog(elevel,...)
Definition: elog.h:232
int i
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:120
#define PG_TRY()
Definition: elog.h:313
#define snprintf
Definition: port.h:217
#define PG_END_TRY()
Definition: elog.h:338
char * message
Definition: elog.h:382
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 3368 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().

3369 {
3370  SV *cursor;
3371 
3372  /*
3373  * Execute the query inside a sub-transaction, so we can cope with errors
3374  * sanely
3375  */
3376  MemoryContext oldcontext = CurrentMemoryContext;
3378 
3380 
3382  /* Want to run inside function's memory context */
3383  MemoryContextSwitchTo(oldcontext);
3384 
3385  PG_TRY();
3386  {
3387  SPIPlanPtr plan;
3388  Portal portal;
3389 
3390  /* Make sure the query is validly encoded */
3391  pg_verifymbstr(query, strlen(query), false);
3392 
3393  /* Create a cursor for the query */
3394  plan = SPI_prepare(query, 0, NULL);
3395  if (plan == NULL)
3396  elog(ERROR, "SPI_prepare() failed:%s",
3398 
3399  portal = SPI_cursor_open(NULL, plan, NULL, NULL, false);
3400  SPI_freeplan(plan);
3401  if (portal == NULL)
3402  elog(ERROR, "SPI_cursor_open() failed:%s",
3404  cursor = cstr2sv(portal->name);
3405 
3406  PinPortal(portal);
3407 
3408  /* Commit the inner transaction, return to outer xact context */
3410  MemoryContextSwitchTo(oldcontext);
3411  CurrentResourceOwner = oldowner;
3412  }
3413  PG_CATCH();
3414  {
3415  ErrorData *edata;
3416 
3417  /* Save error info */
3418  MemoryContextSwitchTo(oldcontext);
3419  edata = CopyErrorData();
3420  FlushErrorState();
3421 
3422  /* Abort the inner transaction */
3424  MemoryContextSwitchTo(oldcontext);
3425  CurrentResourceOwner = oldowner;
3426 
3427  /* Punt the error to Perl */
3428  croak_cstr(edata->message);
3429 
3430  /* Can't get here, but keep compiler quiet */
3431  return NULL;
3432  }
3433  PG_END_TRY();
3434 
3435  return cursor;
3436 }
ErrorData * CopyErrorData(void)
Definition: elog.c:1560
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes)
Definition: spi.c:765
void ReleaseCurrentSubTransaction(void)
Definition: xact.c:4488
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:1350
void FlushErrorState(void)
Definition: elog.c:1654
int SPI_result
Definition: spi.c:47
const char * name
Definition: portal.h:118
#define ERROR
Definition: elog.h:46
const char * SPI_result_code_string(int code)
Definition: spi.c:1877
void RollbackAndReleaseCurrentSubTransaction(void)
Definition: xact.c:4522
void PinPortal(Portal portal)
Definition: portalmem.c:371
Definition: type.h:130
MemoryContext CurrentMemoryContext
Definition: mcxt.c:42
static void croak_cstr(const char *str)
static SV * cstr2sv(const char *str)
bool pg_verifymbstr(const char *mbstr, int len, bool noError)
Definition: mbutils.c:1505
#define PG_CATCH()
Definition: elog.h:323
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4417
static void check_spi_usage_allowed(void)
Definition: plperl.c:3087
int SPI_freeplan(SPIPlanPtr plan)
Definition: spi.c:930
#define elog(elevel,...)
Definition: elog.h:232
#define PG_TRY()
Definition: elog.h:313
#define PG_END_TRY()
Definition: elog.h:338
char * message
Definition: elog.h:382

◆ plperl_spi_query_prepared()

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

Definition at line 3806 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().

3807 {
3808  int i;
3809  char *nulls;
3810  Datum *argvalues;
3811  plperl_query_desc *qdesc;
3812  plperl_query_entry *hash_entry;
3813  SV *cursor;
3814  Portal portal = NULL;
3815 
3816  /*
3817  * Execute the query inside a sub-transaction, so we can cope with errors
3818  * sanely
3819  */
3820  MemoryContext oldcontext = CurrentMemoryContext;
3822 
3824 
3826  /* Want to run inside function's memory context */
3827  MemoryContextSwitchTo(oldcontext);
3828 
3829  PG_TRY();
3830  {
3831  /************************************************************
3832  * Fetch the saved plan descriptor, see if it's o.k.
3833  ************************************************************/
3834  hash_entry = hash_search(plperl_active_interp->query_hash, query,
3835  HASH_FIND, NULL);
3836  if (hash_entry == NULL)
3837  elog(ERROR, "spi_query_prepared: Invalid prepared query passed");
3838 
3839  qdesc = hash_entry->query_data;
3840  if (qdesc == NULL)
3841  elog(ERROR, "spi_query_prepared: plperl query_hash value vanished");
3842 
3843  if (qdesc->nargs != argc)
3844  elog(ERROR, "spi_query_prepared: expected %d argument(s), %d passed",
3845  qdesc->nargs, argc);
3846 
3847  /************************************************************
3848  * Set up arguments
3849  ************************************************************/
3850  if (argc > 0)
3851  {
3852  nulls = (char *) palloc(argc);
3853  argvalues = (Datum *) palloc(argc * sizeof(Datum));
3854  }
3855  else
3856  {
3857  nulls = NULL;
3858  argvalues = NULL;
3859  }
3860 
3861  for (i = 0; i < argc; i++)
3862  {
3863  bool isnull;
3864 
3865  argvalues[i] = plperl_sv_to_datum(argv[i],
3866  qdesc->argtypes[i],
3867  -1,
3868  NULL,
3869  &qdesc->arginfuncs[i],
3870  qdesc->argtypioparams[i],
3871  &isnull);
3872  nulls[i] = isnull ? 'n' : ' ';
3873  }
3874 
3875  /************************************************************
3876  * go
3877  ************************************************************/
3878  portal = SPI_cursor_open(NULL, qdesc->plan, argvalues, nulls,
3880  if (argc > 0)
3881  {
3882  pfree(argvalues);
3883  pfree(nulls);
3884  }
3885  if (portal == NULL)
3886  elog(ERROR, "SPI_cursor_open() failed:%s",
3888 
3889  cursor = cstr2sv(portal->name);
3890 
3891  PinPortal(portal);
3892 
3893  /* Commit the inner transaction, return to outer xact context */
3895  MemoryContextSwitchTo(oldcontext);
3896  CurrentResourceOwner = oldowner;
3897  }
3898  PG_CATCH();
3899  {
3900  ErrorData *edata;
3901 
3902  /* Save error info */
3903  MemoryContextSwitchTo(oldcontext);
3904  edata = CopyErrorData();
3905  FlushErrorState();
3906 
3907  /* Abort the inner transaction */
3909  MemoryContextSwitchTo(oldcontext);
3910  CurrentResourceOwner = oldowner;
3911 
3912  /* Punt the error to Perl */
3913  croak_cstr(edata->message);
3914 
3915  /* Can't get here, but keep compiler quiet */
3916  return NULL;
3917  }
3918  PG_END_TRY();
3919 
3920  return cursor;
3921 }
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:1307
HTAB * query_hash
Definition: plperl.c:89
SPIPlanPtr plan
Definition: plperl.c:192
ErrorData * CopyErrorData(void)
Definition: elog.c:1560
Oid * argtypioparams
Definition: plperl.c:196
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
void ReleaseCurrentSubTransaction(void)
Definition: xact.c:4488
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:1350
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:954
void FlushErrorState(void)
Definition: elog.c:1654
int SPI_result
Definition: spi.c:47
void pfree(void *pointer)
Definition: mcxt.c:1169
const char * name
Definition: portal.h:118
#define ERROR
Definition: elog.h:46
const char * SPI_result_code_string(int code)
Definition: spi.c:1877
void RollbackAndReleaseCurrentSubTransaction(void)
Definition: xact.c:4522
void PinPortal(Portal portal)
Definition: portalmem.c:371
Definition: type.h:130
Oid * argtypes
Definition: plperl.c:194
MemoryContext CurrentMemoryContext
Definition: mcxt.c:42
uintptr_t Datum
Definition: postgres.h:411
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:323
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4417
static void check_spi_usage_allowed(void)
Definition: plperl.c:3087
void * palloc(Size size)
Definition: mcxt.c:1062
#define elog(elevel,...)
Definition: elog.h:232
int i
plperl_proc_desc * prodesc
Definition: plperl.c:175
#define PG_TRY()
Definition: elog.h:313
static plperl_call_data * current_call_data
Definition: plperl.c:243
#define PG_END_TRY()
Definition: elog.h:338
char * message
Definition: elog.h:382
plperl_query_desc * query_data
Definition: plperl.c:204

◆ plperl_spi_rollback()

void plperl_spi_rollback ( void  )

Definition at line 3980 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().

3981 {
3982  MemoryContext oldcontext = CurrentMemoryContext;
3983 
3984  PG_TRY();
3985  {
3986  SPI_rollback();
3988  }
3989  PG_CATCH();
3990  {
3991  ErrorData *edata;
3992 
3993  /* Save error info */
3994  MemoryContextSwitchTo(oldcontext);
3995  edata = CopyErrorData();
3996  FlushErrorState();
3997 
3998  /* Punt the error to Perl */
3999  croak_cstr(edata->message);
4000  }
4001  PG_END_TRY();
4002 }
ErrorData * CopyErrorData(void)
Definition: elog.c:1560
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void SPI_rollback(void)
Definition: spi.c:338
void FlushErrorState(void)
Definition: elog.c:1654
MemoryContext CurrentMemoryContext
Definition: mcxt.c:42
static void croak_cstr(const char *str)
#define PG_CATCH()
Definition: elog.h:323
void SPI_start_transaction(void)
Definition: spi.c:218
#define PG_TRY()
Definition: elog.h:313
#define PG_END_TRY()
Definition: elog.h:338
char * message
Definition: elog.h:382

◆ plperl_sv_to_literal()

char* plperl_sv_to_literal ( SV *  ,
char *   
)

Definition at line 1428 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.

1429 {
1430  Datum str = CStringGetDatum(fqtypename);
1431  Oid typid = DirectFunctionCall1(regtypein, str);
1432  Oid typoutput;
1433  Datum datum;
1434  bool typisvarlena,
1435  isnull;
1436 
1437  if (!OidIsValid(typid))
1438  ereport(ERROR,
1439  (errcode(ERRCODE_UNDEFINED_OBJECT),
1440  errmsg("lookup failed for type %s", fqtypename)));
1441 
1442  datum = plperl_sv_to_datum(sv,
1443  typid, -1,
1444  NULL, NULL, InvalidOid,
1445  &isnull);
1446 
1447  if (isnull)
1448  return NULL;
1449 
1450  getTypeOutputInfo(typid,
1451  &typoutput, &typisvarlena);
1452 
1453  return OidOutputFunctionCall(typoutput, datum);
1454 }
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2854
static Datum plperl_sv_to_datum(SV *sv, Oid typid, int32 typmod, FunctionCallInfo fcinfo, FmgrInfo *finfo, Oid typioparam, bool *isnull)
Definition: plperl.c:1307
int errcode(int sqlerrcode)
Definition: elog.c:698
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:626
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
#define ERROR
Definition: elog.h:46
#define CStringGetDatum(X)
Definition: postgres.h:622
Datum regtypein(PG_FUNCTION_ARGS)
Definition: regproc.c:1251
uintptr_t Datum
Definition: postgres.h:411
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:157
char * OidOutputFunctionCall(Oid functionId, Datum val)
Definition: fmgr.c:1653
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ plperl_util_elog()

void plperl_util_elog ( int  level,
SV *  msg 
)

Definition at line 4016 of file plperl.c.

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

4017 {
4018  MemoryContext oldcontext = CurrentMemoryContext;
4019  char *volatile cmsg = NULL;
4020 
4021  PG_TRY();
4022  {
4023  cmsg = sv2cstr(msg);
4024  elog(level, "%s", cmsg);
4025  pfree(cmsg);
4026  }
4027  PG_CATCH();
4028  {
4029  ErrorData *edata;
4030 
4031  /* Must reset elog.c's state */
4032  MemoryContextSwitchTo(oldcontext);
4033  edata = CopyErrorData();
4034  FlushErrorState();
4035 
4036  if (cmsg)
4037  pfree(cmsg);
4038 
4039  /* Punt the error to Perl */
4040  croak_cstr(edata->message);
4041  }
4042  PG_END_TRY();
4043 }
ErrorData * CopyErrorData(void)
Definition: elog.c:1560
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void FlushErrorState(void)
Definition: elog.c:1654
void pfree(void *pointer)
Definition: mcxt.c:1169
MemoryContext CurrentMemoryContext
Definition: mcxt.c:42
static void croak_cstr(const char *str)
#define PG_CATCH()
Definition: elog.h:323
#define elog(elevel,...)
Definition: elog.h:232
#define PG_TRY()
Definition: elog.h:313
#define PG_END_TRY()
Definition: elog.h:338
char * message
Definition: elog.h:382
static char * sv2cstr(SV *sv)