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 3238 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().

3239 {
3240  MemoryContext oldcontext = CurrentMemoryContext;
3241 
3242  PG_TRY();
3243  {
3245  }
3246  PG_CATCH();
3247  {
3248  ErrorData *edata;
3249 
3250  /* Must reset elog.c's state */
3251  MemoryContextSwitchTo(oldcontext);
3252  edata = CopyErrorData();
3253  FlushErrorState();
3254 
3255  /* Punt the error to Perl */
3256  croak_cstr(edata->message);
3257  }
3258  PG_END_TRY();
3259 }
ErrorData * CopyErrorData(void)
Definition: elog.c:1484
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void FlushErrorState(void)
Definition: elog.c:1574
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
static void plperl_return_next_internal(SV *sv)
Definition: plperl.c:3266
static void croak_cstr(const char *str)
#define PG_CATCH()
Definition: elog.h:310
#define PG_TRY()
Definition: elog.h:301
#define PG_END_TRY()
Definition: elog.h:317
char * message
Definition: elog.h:360

◆ plperl_spi_commit()

void plperl_spi_commit ( void  )

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

3983 {
3984  MemoryContext oldcontext = CurrentMemoryContext;
3985 
3986  PG_TRY();
3987  {
3988  SPI_commit();
3990  }
3991  PG_CATCH();
3992  {
3993  ErrorData *edata;
3994 
3995  /* Save error info */
3996  MemoryContextSwitchTo(oldcontext);
3997  edata = CopyErrorData();
3998  FlushErrorState();
3999 
4000  /* Punt the error to Perl */
4001  croak_cstr(edata->message);
4002  }
4003  PG_END_TRY();
4004 }
ErrorData * CopyErrorData(void)
Definition: elog.c:1484
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void FlushErrorState(void)
Definition: elog.c:1574
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:310
void SPI_start_transaction(void)
Definition: spi.c:212
#define PG_TRY()
Definition: elog.h:301
#define PG_END_TRY()
Definition: elog.h:317
char * message
Definition: elog.h:360

◆ plperl_spi_cursor_close()

void plperl_spi_cursor_close ( char *  )

Definition at line 3542 of file plperl.c.

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

3543 {
3544  Portal p;
3545 
3547 
3548  p = SPI_cursor_find(cursor);
3549 
3550  if (p)
3551  {
3552  UnpinPortal(p);
3553  SPI_cursor_close(p);
3554  }
3555 }
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:3114
void SPI_cursor_close(Portal portal)
Definition: spi.c:1595

◆ plperl_spi_exec()

HV* plperl_spi_exec ( char *  ,
int   
)

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

3127 {
3128  HV *ret_hv;
3129 
3130  /*
3131  * Execute the query inside a sub-transaction, so we can cope with errors
3132  * sanely
3133  */
3134  MemoryContext oldcontext = CurrentMemoryContext;
3136 
3138 
3140  /* Want to run inside function's memory context */
3141  MemoryContextSwitchTo(oldcontext);
3142 
3143  PG_TRY();
3144  {
3145  int spi_rv;
3146 
3147  pg_verifymbstr(query, strlen(query), false);
3148 
3150  limit);
3152  spi_rv);
3153 
3154  /* Commit the inner transaction, return to outer xact context */
3156  MemoryContextSwitchTo(oldcontext);
3157  CurrentResourceOwner = oldowner;
3158  }
3159  PG_CATCH();
3160  {
3161  ErrorData *edata;
3162 
3163  /* Save error info */
3164  MemoryContextSwitchTo(oldcontext);
3165  edata = CopyErrorData();
3166  FlushErrorState();
3167 
3168  /* Abort the inner transaction */
3170  MemoryContextSwitchTo(oldcontext);
3171  CurrentResourceOwner = oldowner;
3172 
3173  /* Punt the error to Perl */
3174  croak_cstr(edata->message);
3175 
3176  /* Can't get here, but keep compiler quiet */
3177  return NULL;
3178  }
3179  PG_END_TRY();
3180 
3181  return ret_hv;
3182 }
ErrorData * CopyErrorData(void)
Definition: elog.c:1484
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
void ReleaseCurrentSubTransaction(void)
Definition: xact.c:4428
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
SPITupleTable * SPI_tuptable
Definition: spi.c:46
void FlushErrorState(void)
Definition: elog.c:1574
uint64 SPI_processed
Definition: spi.c:45
void RollbackAndReleaseCurrentSubTransaction(void)
Definition: xact.c:4462
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
static void croak_cstr(const char *str)
bool fn_readonly
Definition: plperl.c:112
#define PG_CATCH()
Definition: elog.h:310
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4357
static void check_spi_usage_allowed(void)
Definition: plperl.c:3114
static HV * plperl_spi_execute_fetch_result(SPITupleTable *, uint64, int)
Definition: plperl.c:3186
bool pg_verifymbstr(const char *mbstr, int len, bool noError)
Definition: wchar.c:1914
plperl_proc_desc * prodesc
Definition: plperl.c:176
#define PG_TRY()
Definition: elog.h:301
static plperl_call_data * current_call_data
Definition: plperl.c:244
#define PG_END_TRY()
Definition: elog.h:317
char * message
Definition: elog.h:360
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 3706 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.

3707 {
3708  HV *ret_hv;
3709  SV **sv;
3710  int i,
3711  limit,
3712  spi_rv;
3713  char *nulls;
3714  Datum *argvalues;
3715  plperl_query_desc *qdesc;
3716  plperl_query_entry *hash_entry;
3717 
3718  /*
3719  * Execute the query inside a sub-transaction, so we can cope with errors
3720  * sanely
3721  */
3722  MemoryContext oldcontext = CurrentMemoryContext;
3724 
3726 
3728  /* Want to run inside function's memory context */
3729  MemoryContextSwitchTo(oldcontext);
3730 
3731  PG_TRY();
3732  {
3733  dTHX;
3734 
3735  /************************************************************
3736  * Fetch the saved plan descriptor, see if it's o.k.
3737  ************************************************************/
3738  hash_entry = hash_search(plperl_active_interp->query_hash, query,
3739  HASH_FIND, NULL);
3740  if (hash_entry == NULL)
3741  elog(ERROR, "spi_exec_prepared: Invalid prepared query passed");
3742 
3743  qdesc = hash_entry->query_data;
3744  if (qdesc == NULL)
3745  elog(ERROR, "spi_exec_prepared: plperl query_hash value vanished");
3746 
3747  if (qdesc->nargs != argc)
3748  elog(ERROR, "spi_exec_prepared: expected %d argument(s), %d passed",
3749  qdesc->nargs, argc);
3750 
3751  /************************************************************
3752  * Parse eventual attributes
3753  ************************************************************/
3754  limit = 0;
3755  if (attr != NULL)
3756  {
3757  sv = hv_fetch_string(attr, "limit");
3758  if (sv && *sv && SvIOK(*sv))
3759  limit = SvIV(*sv);
3760  }
3761  /************************************************************
3762  * Set up arguments
3763  ************************************************************/
3764  if (argc > 0)
3765  {
3766  nulls = (char *) palloc(argc);
3767  argvalues = (Datum *) palloc(argc * sizeof(Datum));
3768  }
3769  else
3770  {
3771  nulls = NULL;
3772  argvalues = NULL;
3773  }
3774 
3775  for (i = 0; i < argc; i++)
3776  {
3777  bool isnull;
3778 
3779  argvalues[i] = plperl_sv_to_datum(argv[i],
3780  qdesc->argtypes[i],
3781  -1,
3782  NULL,
3783  &qdesc->arginfuncs[i],
3784  qdesc->argtypioparams[i],
3785  &isnull);
3786  nulls[i] = isnull ? 'n' : ' ';
3787  }
3788 
3789  /************************************************************
3790  * go
3791  ************************************************************/
3792  spi_rv = SPI_execute_plan(qdesc->plan, argvalues, nulls,
3795  spi_rv);
3796  if (argc > 0)
3797  {
3798  pfree(argvalues);
3799  pfree(nulls);
3800  }
3801 
3802  /* Commit the inner transaction, return to outer xact context */
3804  MemoryContextSwitchTo(oldcontext);
3805  CurrentResourceOwner = oldowner;
3806  }
3807  PG_CATCH();
3808  {
3809  ErrorData *edata;
3810 
3811  /* Save error info */
3812  MemoryContextSwitchTo(oldcontext);
3813  edata = CopyErrorData();
3814  FlushErrorState();
3815 
3816  /* Abort the inner transaction */
3818  MemoryContextSwitchTo(oldcontext);
3819  CurrentResourceOwner = oldowner;
3820 
3821  /* Punt the error to Perl */
3822  croak_cstr(edata->message);
3823 
3824  /* Can't get here, but keep compiler quiet */
3825  return NULL;
3826  }
3827  PG_END_TRY();
3828 
3829  return ret_hv;
3830 }
Definition: plperl.c:202
static Datum plperl_sv_to_datum(SV *sv, Oid typid, int32 typmod, FunctionCallInfo fcinfo, FmgrInfo *finfo, Oid typioparam, bool *isnull)
Definition: plperl.c:1311
HTAB * query_hash
Definition: plperl.c:90
#define dTHX
Definition: ppport.h:3208
SPIPlanPtr plan
Definition: plperl.c:193
ErrorData * CopyErrorData(void)
Definition: elog.c:1484
Oid * argtypioparams
Definition: plperl.c:197
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
void ReleaseCurrentSubTransaction(void)
Definition: xact.c:4428
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:4104
static plperl_interp_desc * plperl_active_interp
Definition: plperl.c:228
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:906
void FlushErrorState(void)
Definition: elog.c:1574
uint64 SPI_processed
Definition: spi.c:45
void pfree(void *pointer)
Definition: mcxt.c:1031
#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:4462
Oid * argtypes
Definition: plperl.c:195
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
uintptr_t Datum
Definition: postgres.h:367
FmgrInfo * arginfuncs
Definition: plperl.c:196
static void croak_cstr(const char *str)
bool fn_readonly
Definition: plperl.c:112
#define PG_CATCH()
Definition: elog.h:310
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4357
static void check_spi_usage_allowed(void)
Definition: plperl.c:3114
void * palloc(Size size)
Definition: mcxt.c:924
#define elog(elevel,...)
Definition: elog.h:226
int i
static HV * plperl_spi_execute_fetch_result(SPITupleTable *, uint64, int)
Definition: plperl.c:3186
plperl_proc_desc * prodesc
Definition: plperl.c:176
#define PG_TRY()
Definition: elog.h:301
static plperl_call_data * current_call_data
Definition: plperl.c:244
#define PG_END_TRY()
Definition: elog.h:317
char * message
Definition: elog.h:360
plperl_query_desc * query_data
Definition: plperl.c:205

◆ plperl_spi_fetchrow()

SV* plperl_spi_fetchrow ( char *  )

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

3468 {
3469  SV *row;
3470 
3471  /*
3472  * Execute the FETCH inside a sub-transaction, so we can cope with errors
3473  * sanely
3474  */
3475  MemoryContext oldcontext = CurrentMemoryContext;
3477 
3479 
3481  /* Want to run inside function's memory context */
3482  MemoryContextSwitchTo(oldcontext);
3483 
3484  PG_TRY();
3485  {
3486  dTHX;
3488 
3489  if (!p)
3490  {
3491  row = &PL_sv_undef;
3492  }
3493  else
3494  {
3495  SPI_cursor_fetch(p, true, 1);
3496  if (SPI_processed == 0)
3497  {
3498  UnpinPortal(p);
3499  SPI_cursor_close(p);
3500  row = &PL_sv_undef;
3501  }
3502  else
3503  {
3506  true);
3507  }
3509  }
3510 
3511  /* Commit the inner transaction, return to outer xact context */
3513  MemoryContextSwitchTo(oldcontext);
3514  CurrentResourceOwner = oldowner;
3515  }
3516  PG_CATCH();
3517  {
3518  ErrorData *edata;
3519 
3520  /* Save error info */
3521  MemoryContextSwitchTo(oldcontext);
3522  edata = CopyErrorData();
3523  FlushErrorState();
3524 
3525  /* Abort the inner transaction */
3527  MemoryContextSwitchTo(oldcontext);
3528  CurrentResourceOwner = oldowner;
3529 
3530  /* Punt the error to Perl */
3531  croak_cstr(edata->message);
3532 
3533  /* Can't get here, but keep compiler quiet */
3534  return NULL;
3535  }
3536  PG_END_TRY();
3537 
3538  return row;
3539 }
void UnpinPortal(Portal portal)
Definition: portalmem.c:377
#define dTHX
Definition: ppport.h:3208
ErrorData * CopyErrorData(void)
Definition: elog.c:1484
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
void ReleaseCurrentSubTransaction(void)
Definition: xact.c:4428
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:1574
uint64 SPI_processed
Definition: spi.c:45
Portal SPI_cursor_find(const char *name)
Definition: spi.c:1527
void RollbackAndReleaseCurrentSubTransaction(void)
Definition: xact.c:4462
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:310
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4357
static void check_spi_usage_allowed(void)
Definition: plperl.c:3114
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:3034
void SPI_cursor_fetch(Portal portal, bool forward, long count)
Definition: spi.c:1539
#define PG_TRY()
Definition: elog.h:301
#define PG_END_TRY()
Definition: elog.h:317
char * message
Definition: elog.h:360

◆ plperl_spi_freeplan()

void plperl_spi_freeplan ( char *  )

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

3952 {
3953  SPIPlanPtr plan;
3954  plperl_query_desc *qdesc;
3955  plperl_query_entry *hash_entry;
3956 
3958 
3959  hash_entry = hash_search(plperl_active_interp->query_hash, query,
3960  HASH_FIND, NULL);
3961  if (hash_entry == NULL)
3962  elog(ERROR, "spi_freeplan: Invalid prepared query passed");
3963 
3964  qdesc = hash_entry->query_data;
3965  if (qdesc == NULL)
3966  elog(ERROR, "spi_freeplan: plperl query_hash value vanished");
3967  plan = qdesc->plan;
3968 
3969  /*
3970  * free all memory before SPI_freeplan, so if it dies, nothing will be
3971  * left over
3972  */
3974  HASH_REMOVE, NULL);
3975 
3976  MemoryContextDelete(qdesc->plan_cxt);
3977 
3978  SPI_freeplan(plan);
3979 }
Definition: plperl.c:202
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:211
HTAB * query_hash
Definition: plperl.c:90
SPIPlanPtr plan
Definition: plperl.c:193
static plperl_interp_desc * plperl_active_interp
Definition: plperl.c:228
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:192
static void check_spi_usage_allowed(void)
Definition: plperl.c:3114
int SPI_freeplan(SPIPlanPtr plan)
Definition: spi.c:801
#define elog(elevel,...)
Definition: elog.h:226
plperl_query_desc * query_data
Definition: plperl.c:205

◆ plperl_spi_prepare()

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

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

3559 {
3560  volatile SPIPlanPtr plan = NULL;
3561  volatile MemoryContext plan_cxt = NULL;
3562  plperl_query_desc *volatile qdesc = NULL;
3563  plperl_query_entry *volatile hash_entry = NULL;
3564  MemoryContext oldcontext = CurrentMemoryContext;
3566  MemoryContext work_cxt;
3567  bool found;
3568  int i;
3569 
3571 
3573  MemoryContextSwitchTo(oldcontext);
3574 
3575  PG_TRY();
3576  {
3578 
3579  /************************************************************
3580  * Allocate the new querydesc structure
3581  *
3582  * The qdesc struct, as well as all its subsidiary data, lives in its
3583  * plan_cxt. But note that the SPIPlan does not.
3584  ************************************************************/
3586  "PL/Perl spi_prepare query",
3588  MemoryContextSwitchTo(plan_cxt);
3589  qdesc = (plperl_query_desc *) palloc0(sizeof(plperl_query_desc));
3590  snprintf(qdesc->qname, sizeof(qdesc->qname), "%p", qdesc);
3591  qdesc->plan_cxt = plan_cxt;
3592  qdesc->nargs = argc;
3593  qdesc->argtypes = (Oid *) palloc(argc * sizeof(Oid));
3594  qdesc->arginfuncs = (FmgrInfo *) palloc(argc * sizeof(FmgrInfo));
3595  qdesc->argtypioparams = (Oid *) palloc(argc * sizeof(Oid));
3596  MemoryContextSwitchTo(oldcontext);
3597 
3598  /************************************************************
3599  * Do the following work in a short-lived context so that we don't
3600  * leak a lot of memory in the PL/Perl function's SPI Proc context.
3601  ************************************************************/
3603  "PL/Perl spi_prepare workspace",
3605  MemoryContextSwitchTo(work_cxt);
3606 
3607  /************************************************************
3608  * Resolve argument type names and then look them up by oid
3609  * in the system cache, and remember the required information
3610  * for input conversion.
3611  ************************************************************/
3612  for (i = 0; i < argc; i++)
3613  {
3614  Oid typId,
3615  typInput,
3616  typIOParam;
3617  int32 typmod;
3618  char *typstr;
3619 
3620  typstr = sv2cstr(argv[i]);
3621  parseTypeString(typstr, &typId, &typmod, false);
3622  pfree(typstr);
3623 
3624  getTypeInputInfo(typId, &typInput, &typIOParam);
3625 
3626  qdesc->argtypes[i] = typId;
3627  fmgr_info_cxt(typInput, &(qdesc->arginfuncs[i]), plan_cxt);
3628  qdesc->argtypioparams[i] = typIOParam;
3629  }
3630 
3631  /* Make sure the query is validly encoded */
3632  pg_verifymbstr(query, strlen(query), false);
3633 
3634  /************************************************************
3635  * Prepare the plan and check for errors
3636  ************************************************************/
3637  plan = SPI_prepare(query, argc, qdesc->argtypes);
3638 
3639  if (plan == NULL)
3640  elog(ERROR, "SPI_prepare() failed:%s",
3642 
3643  /************************************************************
3644  * Save the plan into permanent memory (right now it's in the
3645  * SPI procCxt, which will go away at function end).
3646  ************************************************************/
3647  if (SPI_keepplan(plan))
3648  elog(ERROR, "SPI_keepplan() failed");
3649  qdesc->plan = plan;
3650 
3651  /************************************************************
3652  * Insert a hashtable entry for the plan.
3653  ************************************************************/
3655  qdesc->qname,
3656  HASH_ENTER, &found);
3657  hash_entry->query_data = qdesc;
3658 
3659  /* Get rid of workspace */
3660  MemoryContextDelete(work_cxt);
3661 
3662  /* Commit the inner transaction, return to outer xact context */
3664  MemoryContextSwitchTo(oldcontext);
3665  CurrentResourceOwner = oldowner;
3666  }
3667  PG_CATCH();
3668  {
3669  ErrorData *edata;
3670 
3671  /* Save error info */
3672  MemoryContextSwitchTo(oldcontext);
3673  edata = CopyErrorData();
3674  FlushErrorState();
3675 
3676  /* Drop anything we managed to allocate */
3677  if (hash_entry)
3679  qdesc->qname,
3680  HASH_REMOVE, NULL);
3681  if (plan_cxt)
3682  MemoryContextDelete(plan_cxt);
3683  if (plan)
3684  SPI_freeplan(plan);
3685 
3686  /* Abort the inner transaction */
3688  MemoryContextSwitchTo(oldcontext);
3689  CurrentResourceOwner = oldowner;
3690 
3691  /* Punt the error to Perl */
3692  croak_cstr(edata->message);
3693 
3694  /* Can't get here, but keep compiler quiet */
3695  return NULL;
3696  }
3697  PG_END_TRY();
3698 
3699  /************************************************************
3700  * Return the query's hash key to the caller.
3701  ************************************************************/
3702  return cstr2sv(qdesc->qname);
3703 }
Definition: fmgr.h:56
Definition: plperl.c:202
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:211
#define AllocSetContextCreate
Definition: memutils.h:169
HTAB * query_hash
Definition: plperl.c:90
SPIPlanPtr plan
Definition: plperl.c:193
ErrorData * CopyErrorData(void)
Definition: elog.c:1484
Oid * argtypioparams
Definition: plperl.c:197
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:201
void ReleaseCurrentSubTransaction(void)
Definition: xact.c:4428
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static plperl_interp_desc * plperl_active_interp
Definition: plperl.c:228
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:1574
signed int int32
Definition: c.h:346
int SPI_result
Definition: spi.c:47
void pfree(void *pointer)
Definition: mcxt.c:1031
#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:191
int SPI_keepplan(SPIPlanPtr plan)
Definition: spi.c:752
void RollbackAndReleaseCurrentSubTransaction(void)
Definition: xact.c:4462
Oid * argtypes
Definition: plperl.c:195
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
MemoryContext plan_cxt
Definition: plperl.c:192
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:955
char qname[24]
Definition: plperl.c:191
FmgrInfo * arginfuncs
Definition: plperl.c:196
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:833
#define PG_CATCH()
Definition: elog.h:310
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4357
static void check_spi_usage_allowed(void)
Definition: plperl.c:3114
int SPI_freeplan(SPIPlanPtr plan)
Definition: spi.c:801
void * palloc(Size size)
Definition: mcxt.c:924
#define elog(elevel,...)
Definition: elog.h:226
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:301
#define snprintf
Definition: port.h:192
#define PG_END_TRY()
Definition: elog.h:317
char * message
Definition: elog.h:360
static char * sv2cstr(SV *sv)
plperl_query_desc * query_data
Definition: plperl.c:205

◆ plperl_spi_query()

SV* plperl_spi_query ( char *  )

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

3396 {
3397  SV *cursor;
3398 
3399  /*
3400  * Execute the query inside a sub-transaction, so we can cope with errors
3401  * sanely
3402  */
3403  MemoryContext oldcontext = CurrentMemoryContext;
3405 
3407 
3409  /* Want to run inside function's memory context */
3410  MemoryContextSwitchTo(oldcontext);
3411 
3412  PG_TRY();
3413  {
3414  SPIPlanPtr plan;
3415  Portal portal;
3416 
3417  /* Make sure the query is validly encoded */
3418  pg_verifymbstr(query, strlen(query), false);
3419 
3420  /* Create a cursor for the query */
3421  plan = SPI_prepare(query, 0, NULL);
3422  if (plan == NULL)
3423  elog(ERROR, "SPI_prepare() failed:%s",
3425 
3426  portal = SPI_cursor_open(NULL, plan, NULL, NULL, false);
3427  SPI_freeplan(plan);
3428  if (portal == NULL)
3429  elog(ERROR, "SPI_cursor_open() failed:%s",
3431  cursor = cstr2sv(portal->name);
3432 
3433  PinPortal(portal);
3434 
3435  /* Commit the inner transaction, return to outer xact context */
3437  MemoryContextSwitchTo(oldcontext);
3438  CurrentResourceOwner = oldowner;
3439  }
3440  PG_CATCH();
3441  {
3442  ErrorData *edata;
3443 
3444  /* Save error info */
3445  MemoryContextSwitchTo(oldcontext);
3446  edata = CopyErrorData();
3447  FlushErrorState();
3448 
3449  /* Abort the inner transaction */
3451  MemoryContextSwitchTo(oldcontext);
3452  CurrentResourceOwner = oldowner;
3453 
3454  /* Punt the error to Perl */
3455  croak_cstr(edata->message);
3456 
3457  /* Can't get here, but keep compiler quiet */
3458  return NULL;
3459  }
3460  PG_END_TRY();
3461 
3462  return cursor;
3463 }
ErrorData * CopyErrorData(void)
Definition: elog.c:1484
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:4428
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:1574
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:4462
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:310
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4357
static void check_spi_usage_allowed(void)
Definition: plperl.c:3114
int SPI_freeplan(SPIPlanPtr plan)
Definition: spi.c:801
#define elog(elevel,...)
Definition: elog.h:226
bool pg_verifymbstr(const char *mbstr, int len, bool noError)
Definition: wchar.c:1914
#define PG_TRY()
Definition: elog.h:301
#define PG_END_TRY()
Definition: elog.h:317
char * message
Definition: elog.h:360

◆ plperl_spi_query_prepared()

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

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

3834 {
3835  int i;
3836  char *nulls;
3837  Datum *argvalues;
3838  plperl_query_desc *qdesc;
3839  plperl_query_entry *hash_entry;
3840  SV *cursor;
3841  Portal portal = NULL;
3842 
3843  /*
3844  * Execute the query inside a sub-transaction, so we can cope with errors
3845  * sanely
3846  */
3847  MemoryContext oldcontext = CurrentMemoryContext;
3849 
3851 
3853  /* Want to run inside function's memory context */
3854  MemoryContextSwitchTo(oldcontext);
3855 
3856  PG_TRY();
3857  {
3858  /************************************************************
3859  * Fetch the saved plan descriptor, see if it's o.k.
3860  ************************************************************/
3861  hash_entry = hash_search(plperl_active_interp->query_hash, query,
3862  HASH_FIND, NULL);
3863  if (hash_entry == NULL)
3864  elog(ERROR, "spi_query_prepared: Invalid prepared query passed");
3865 
3866  qdesc = hash_entry->query_data;
3867  if (qdesc == NULL)
3868  elog(ERROR, "spi_query_prepared: plperl query_hash value vanished");
3869 
3870  if (qdesc->nargs != argc)
3871  elog(ERROR, "spi_query_prepared: expected %d argument(s), %d passed",
3872  qdesc->nargs, argc);
3873 
3874  /************************************************************
3875  * Set up arguments
3876  ************************************************************/
3877  if (argc > 0)
3878  {
3879  nulls = (char *) palloc(argc);
3880  argvalues = (Datum *) palloc(argc * sizeof(Datum));
3881  }
3882  else
3883  {
3884  nulls = NULL;
3885  argvalues = NULL;
3886  }
3887 
3888  for (i = 0; i < argc; i++)
3889  {
3890  bool isnull;
3891 
3892  argvalues[i] = plperl_sv_to_datum(argv[i],
3893  qdesc->argtypes[i],
3894  -1,
3895  NULL,
3896  &qdesc->arginfuncs[i],
3897  qdesc->argtypioparams[i],
3898  &isnull);
3899  nulls[i] = isnull ? 'n' : ' ';
3900  }
3901 
3902  /************************************************************
3903  * go
3904  ************************************************************/
3905  portal = SPI_cursor_open(NULL, qdesc->plan, argvalues, nulls,
3907  if (argc > 0)
3908  {
3909  pfree(argvalues);
3910  pfree(nulls);
3911  }
3912  if (portal == NULL)
3913  elog(ERROR, "SPI_cursor_open() failed:%s",
3915 
3916  cursor = cstr2sv(portal->name);
3917 
3918  PinPortal(portal);
3919 
3920  /* Commit the inner transaction, return to outer xact context */
3922  MemoryContextSwitchTo(oldcontext);
3923  CurrentResourceOwner = oldowner;
3924  }
3925  PG_CATCH();
3926  {
3927  ErrorData *edata;
3928 
3929  /* Save error info */
3930  MemoryContextSwitchTo(oldcontext);
3931  edata = CopyErrorData();
3932  FlushErrorState();
3933 
3934  /* Abort the inner transaction */
3936  MemoryContextSwitchTo(oldcontext);
3937  CurrentResourceOwner = oldowner;
3938 
3939  /* Punt the error to Perl */
3940  croak_cstr(edata->message);
3941 
3942  /* Can't get here, but keep compiler quiet */
3943  return NULL;
3944  }
3945  PG_END_TRY();
3946 
3947  return cursor;
3948 }
Definition: plperl.c:202
static Datum plperl_sv_to_datum(SV *sv, Oid typid, int32 typmod, FunctionCallInfo fcinfo, FmgrInfo *finfo, Oid typioparam, bool *isnull)
Definition: plperl.c:1311
HTAB * query_hash
Definition: plperl.c:90
SPIPlanPtr plan
Definition: plperl.c:193
ErrorData * CopyErrorData(void)
Definition: elog.c:1484
Oid * argtypioparams
Definition: plperl.c:197
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
void ReleaseCurrentSubTransaction(void)
Definition: xact.c:4428
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static plperl_interp_desc * plperl_active_interp
Definition: plperl.c:228
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:1574
int SPI_result
Definition: spi.c:47
void pfree(void *pointer)
Definition: mcxt.c:1031
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:4462
void PinPortal(Portal portal)
Definition: portalmem.c:368
Definition: type.h:130
Oid * argtypes
Definition: plperl.c:195
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
uintptr_t Datum
Definition: postgres.h:367
FmgrInfo * arginfuncs
Definition: plperl.c:196
static void croak_cstr(const char *str)
static SV * cstr2sv(const char *str)
bool fn_readonly
Definition: plperl.c:112
#define PG_CATCH()
Definition: elog.h:310
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4357
static void check_spi_usage_allowed(void)
Definition: plperl.c:3114
void * palloc(Size size)
Definition: mcxt.c:924
#define elog(elevel,...)
Definition: elog.h:226
int i
plperl_proc_desc * prodesc
Definition: plperl.c:176
#define PG_TRY()
Definition: elog.h:301
static plperl_call_data * current_call_data
Definition: plperl.c:244
#define PG_END_TRY()
Definition: elog.h:317
char * message
Definition: elog.h:360
plperl_query_desc * query_data
Definition: plperl.c:205

◆ plperl_spi_rollback()

void plperl_spi_rollback ( void  )

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

4008 {
4009  MemoryContext oldcontext = CurrentMemoryContext;
4010 
4011  PG_TRY();
4012  {
4013  SPI_rollback();
4015  }
4016  PG_CATCH();
4017  {
4018  ErrorData *edata;
4019 
4020  /* Save error info */
4021  MemoryContextSwitchTo(oldcontext);
4022  edata = CopyErrorData();
4023  FlushErrorState();
4024 
4025  /* Punt the error to Perl */
4026  croak_cstr(edata->message);
4027  }
4028  PG_END_TRY();
4029 }
ErrorData * CopyErrorData(void)
Definition: elog.c:1484
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void SPI_rollback(void)
Definition: spi.c:333
void FlushErrorState(void)
Definition: elog.c:1574
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
static void croak_cstr(const char *str)
#define PG_CATCH()
Definition: elog.h:310
void SPI_start_transaction(void)
Definition: spi.c:212
#define PG_TRY()
Definition: elog.h:301
#define PG_END_TRY()
Definition: elog.h:317
char * message
Definition: elog.h:360

◆ plperl_sv_to_literal()

char* plperl_sv_to_literal ( SV *  ,
char *   
)

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

1433 {
1434  Datum str = CStringGetDatum(fqtypename);
1435  Oid typid = DirectFunctionCall1(regtypein, str);
1436  Oid typoutput;
1437  Datum datum;
1438  bool typisvarlena,
1439  isnull;
1440 
1441  if (!OidIsValid(typid))
1442  ereport(ERROR,
1443  (errcode(ERRCODE_UNDEFINED_OBJECT),
1444  errmsg("lookup failed for type %s", fqtypename)));
1445 
1446  datum = plperl_sv_to_datum(sv,
1447  typid, -1,
1448  NULL, NULL, InvalidOid,
1449  &isnull);
1450 
1451  if (isnull)
1452  return NULL;
1453 
1454  getTypeOutputInfo(typid,
1455  &typoutput, &typisvarlena);
1456 
1457  return OidOutputFunctionCall(typoutput, datum);
1458 }
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:1311
int errcode(int sqlerrcode)
Definition: elog.c:570
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:617
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
#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:784

◆ plperl_util_elog()

void plperl_util_elog ( int  level,
SV *  msg 
)

Definition at line 4043 of file plperl.c.

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

4044 {
4045  MemoryContext oldcontext = CurrentMemoryContext;
4046  char *volatile cmsg = NULL;
4047 
4048  PG_TRY();
4049  {
4050  cmsg = sv2cstr(msg);
4051  elog(level, "%s", cmsg);
4052  pfree(cmsg);
4053  }
4054  PG_CATCH();
4055  {
4056  ErrorData *edata;
4057 
4058  /* Must reset elog.c's state */
4059  MemoryContextSwitchTo(oldcontext);
4060  edata = CopyErrorData();
4061  FlushErrorState();
4062 
4063  if (cmsg)
4064  pfree(cmsg);
4065 
4066  /* Punt the error to Perl */
4067  croak_cstr(edata->message);
4068  }
4069  PG_END_TRY();
4070 }
ErrorData * CopyErrorData(void)
Definition: elog.c:1484
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void FlushErrorState(void)
Definition: elog.c:1574
void pfree(void *pointer)
Definition: mcxt.c:1031
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
static void croak_cstr(const char *str)
#define PG_CATCH()
Definition: elog.h:310
#define elog(elevel,...)
Definition: elog.h:226
#define PG_TRY()
Definition: elog.h:301
#define PG_END_TRY()
Definition: elog.h:317
char * message
Definition: elog.h:360
static char * sv2cstr(SV *sv)