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

3217 {
3218  MemoryContext oldcontext = CurrentMemoryContext;
3219 
3220  PG_TRY();
3221  {
3223  }
3224  PG_CATCH();
3225  {
3226  ErrorData *edata;
3227 
3228  /* Must reset elog.c's state */
3229  MemoryContextSwitchTo(oldcontext);
3230  edata = CopyErrorData();
3231  FlushErrorState();
3232 
3233  /* Punt the error to Perl */
3234  croak_cstr(edata->message);
3235  }
3236  PG_END_TRY();
3237 }
ErrorData * CopyErrorData(void)
Definition: elog.c:1474
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void FlushErrorState(void)
Definition: elog.c:1568
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
static void plperl_return_next_internal(SV *sv)
Definition: plperl.c:3244
static void croak_cstr(const char *str)
#define PG_CATCH()
Definition: elog.h:305
#define PG_TRY()
Definition: elog.h:295
#define PG_END_TRY()
Definition: elog.h:320
char * message
Definition: elog.h:365

◆ plperl_spi_commit()

void plperl_spi_commit ( void  )

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

3961 {
3962  MemoryContext oldcontext = CurrentMemoryContext;
3963 
3964  PG_TRY();
3965  {
3966  SPI_commit();
3968  }
3969  PG_CATCH();
3970  {
3971  ErrorData *edata;
3972 
3973  /* Save error info */
3974  MemoryContextSwitchTo(oldcontext);
3975  edata = CopyErrorData();
3976  FlushErrorState();
3977 
3978  /* Punt the error to Perl */
3979  croak_cstr(edata->message);
3980  }
3981  PG_END_TRY();
3982 }
ErrorData * CopyErrorData(void)
Definition: elog.c:1474
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void FlushErrorState(void)
Definition: elog.c:1568
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:305
void SPI_start_transaction(void)
Definition: spi.c:212
#define PG_TRY()
Definition: elog.h:295
#define PG_END_TRY()
Definition: elog.h:320
char * message
Definition: elog.h:365

◆ plperl_spi_cursor_close()

void plperl_spi_cursor_close ( char *  )

Definition at line 3520 of file plperl.c.

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

3521 {
3522  Portal p;
3523 
3525 
3526  p = SPI_cursor_find(cursor);
3527 
3528  if (p)
3529  {
3530  UnpinPortal(p);
3531  SPI_cursor_close(p);
3532  }
3533 }
void UnpinPortal(Portal portal)
Definition: portalmem.c:379
Portal SPI_cursor_find(const char *name)
Definition: spi.c:1521
Definition: type.h:130
static void check_spi_usage_allowed(void)
Definition: plperl.c:3092
void SPI_cursor_close(Portal portal)
Definition: spi.c:1589

◆ plperl_spi_exec()

HV* plperl_spi_exec ( char *  ,
int   
)

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

3105 {
3106  HV *ret_hv;
3107 
3108  /*
3109  * Execute the query inside a sub-transaction, so we can cope with errors
3110  * sanely
3111  */
3112  MemoryContext oldcontext = CurrentMemoryContext;
3114 
3116 
3118  /* Want to run inside function's memory context */
3119  MemoryContextSwitchTo(oldcontext);
3120 
3121  PG_TRY();
3122  {
3123  int spi_rv;
3124 
3125  pg_verifymbstr(query, strlen(query), false);
3126 
3128  limit);
3130  spi_rv);
3131 
3132  /* Commit the inner transaction, return to outer xact context */
3134  MemoryContextSwitchTo(oldcontext);
3135  CurrentResourceOwner = oldowner;
3136  }
3137  PG_CATCH();
3138  {
3139  ErrorData *edata;
3140 
3141  /* Save error info */
3142  MemoryContextSwitchTo(oldcontext);
3143  edata = CopyErrorData();
3144  FlushErrorState();
3145 
3146  /* Abort the inner transaction */
3148  MemoryContextSwitchTo(oldcontext);
3149  CurrentResourceOwner = oldowner;
3150 
3151  /* Punt the error to Perl */
3152  croak_cstr(edata->message);
3153 
3154  /* Can't get here, but keep compiler quiet */
3155  return NULL;
3156  }
3157  PG_END_TRY();
3158 
3159  return ret_hv;
3160 }
ErrorData * CopyErrorData(void)
Definition: elog.c:1474
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
void ReleaseCurrentSubTransaction(void)
Definition: xact.c:4449
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
SPITupleTable * SPI_tuptable
Definition: spi.c:46
void FlushErrorState(void)
Definition: elog.c:1568
uint64 SPI_processed
Definition: spi.c:45
void RollbackAndReleaseCurrentSubTransaction(void)
Definition: xact.c:4483
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
static void croak_cstr(const char *str)
bool pg_verifymbstr(const char *mbstr, int len, bool noError)
Definition: mbutils.c:1446
bool fn_readonly
Definition: plperl.c:111
#define PG_CATCH()
Definition: elog.h:305
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4378
static void check_spi_usage_allowed(void)
Definition: plperl.c:3092
static HV * plperl_spi_execute_fetch_result(SPITupleTable *, uint64, int)
Definition: plperl.c:3164
plperl_proc_desc * prodesc
Definition: plperl.c:175
#define PG_TRY()
Definition: elog.h:295
static plperl_call_data * current_call_data
Definition: plperl.c:243
#define PG_END_TRY()
Definition: elog.h:320
char * message
Definition: elog.h:365
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 3684 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.

3685 {
3686  HV *ret_hv;
3687  SV **sv;
3688  int i,
3689  limit,
3690  spi_rv;
3691  char *nulls;
3692  Datum *argvalues;
3693  plperl_query_desc *qdesc;
3694  plperl_query_entry *hash_entry;
3695 
3696  /*
3697  * Execute the query inside a sub-transaction, so we can cope with errors
3698  * sanely
3699  */
3700  MemoryContext oldcontext = CurrentMemoryContext;
3702 
3704 
3706  /* Want to run inside function's memory context */
3707  MemoryContextSwitchTo(oldcontext);
3708 
3709  PG_TRY();
3710  {
3711  dTHX;
3712 
3713  /************************************************************
3714  * Fetch the saved plan descriptor, see if it's o.k.
3715  ************************************************************/
3716  hash_entry = hash_search(plperl_active_interp->query_hash, query,
3717  HASH_FIND, NULL);
3718  if (hash_entry == NULL)
3719  elog(ERROR, "spi_exec_prepared: Invalid prepared query passed");
3720 
3721  qdesc = hash_entry->query_data;
3722  if (qdesc == NULL)
3723  elog(ERROR, "spi_exec_prepared: plperl query_hash value vanished");
3724 
3725  if (qdesc->nargs != argc)
3726  elog(ERROR, "spi_exec_prepared: expected %d argument(s), %d passed",
3727  qdesc->nargs, argc);
3728 
3729  /************************************************************
3730  * Parse eventual attributes
3731  ************************************************************/
3732  limit = 0;
3733  if (attr != NULL)
3734  {
3735  sv = hv_fetch_string(attr, "limit");
3736  if (sv && *sv && SvIOK(*sv))
3737  limit = SvIV(*sv);
3738  }
3739  /************************************************************
3740  * Set up arguments
3741  ************************************************************/
3742  if (argc > 0)
3743  {
3744  nulls = (char *) palloc(argc);
3745  argvalues = (Datum *) palloc(argc * sizeof(Datum));
3746  }
3747  else
3748  {
3749  nulls = NULL;
3750  argvalues = NULL;
3751  }
3752 
3753  for (i = 0; i < argc; i++)
3754  {
3755  bool isnull;
3756 
3757  argvalues[i] = plperl_sv_to_datum(argv[i],
3758  qdesc->argtypes[i],
3759  -1,
3760  NULL,
3761  &qdesc->arginfuncs[i],
3762  qdesc->argtypioparams[i],
3763  &isnull);
3764  nulls[i] = isnull ? 'n' : ' ';
3765  }
3766 
3767  /************************************************************
3768  * go
3769  ************************************************************/
3770  spi_rv = SPI_execute_plan(qdesc->plan, argvalues, nulls,
3773  spi_rv);
3774  if (argc > 0)
3775  {
3776  pfree(argvalues);
3777  pfree(nulls);
3778  }
3779 
3780  /* Commit the inner transaction, return to outer xact context */
3782  MemoryContextSwitchTo(oldcontext);
3783  CurrentResourceOwner = oldowner;
3784  }
3785  PG_CATCH();
3786  {
3787  ErrorData *edata;
3788 
3789  /* Save error info */
3790  MemoryContextSwitchTo(oldcontext);
3791  edata = CopyErrorData();
3792  FlushErrorState();
3793 
3794  /* Abort the inner transaction */
3796  MemoryContextSwitchTo(oldcontext);
3797  CurrentResourceOwner = oldowner;
3798 
3799  /* Punt the error to Perl */
3800  croak_cstr(edata->message);
3801 
3802  /* Can't get here, but keep compiler quiet */
3803  return NULL;
3804  }
3805  PG_END_TRY();
3806 
3807  return ret_hv;
3808 }
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:1474
Oid * argtypioparams
Definition: plperl.c:196
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
void ReleaseCurrentSubTransaction(void)
Definition: xact.c:4449
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:4082
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:908
void FlushErrorState(void)
Definition: elog.c:1568
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:4483
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:305
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4378
static void check_spi_usage_allowed(void)
Definition: plperl.c:3092
void * palloc(Size size)
Definition: mcxt.c:949
#define elog(elevel,...)
Definition: elog.h:214
int i
static HV * plperl_spi_execute_fetch_result(SPITupleTable *, uint64, int)
Definition: plperl.c:3164
plperl_proc_desc * prodesc
Definition: plperl.c:175
#define PG_TRY()
Definition: elog.h:295
static plperl_call_data * current_call_data
Definition: plperl.c:243
#define PG_END_TRY()
Definition: elog.h:320
char * message
Definition: elog.h:365
plperl_query_desc * query_data
Definition: plperl.c:204

◆ plperl_spi_fetchrow()

SV* plperl_spi_fetchrow ( char *  )

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

3446 {
3447  SV *row;
3448 
3449  /*
3450  * Execute the FETCH inside a sub-transaction, so we can cope with errors
3451  * sanely
3452  */
3453  MemoryContext oldcontext = CurrentMemoryContext;
3455 
3457 
3459  /* Want to run inside function's memory context */
3460  MemoryContextSwitchTo(oldcontext);
3461 
3462  PG_TRY();
3463  {
3464  dTHX;
3466 
3467  if (!p)
3468  {
3469  row = &PL_sv_undef;
3470  }
3471  else
3472  {
3473  SPI_cursor_fetch(p, true, 1);
3474  if (SPI_processed == 0)
3475  {
3476  UnpinPortal(p);
3477  SPI_cursor_close(p);
3478  row = &PL_sv_undef;
3479  }
3480  else
3481  {
3484  true);
3485  }
3487  }
3488 
3489  /* Commit the inner transaction, return to outer xact context */
3491  MemoryContextSwitchTo(oldcontext);
3492  CurrentResourceOwner = oldowner;
3493  }
3494  PG_CATCH();
3495  {
3496  ErrorData *edata;
3497 
3498  /* Save error info */
3499  MemoryContextSwitchTo(oldcontext);
3500  edata = CopyErrorData();
3501  FlushErrorState();
3502 
3503  /* Abort the inner transaction */
3505  MemoryContextSwitchTo(oldcontext);
3506  CurrentResourceOwner = oldowner;
3507 
3508  /* Punt the error to Perl */
3509  croak_cstr(edata->message);
3510 
3511  /* Can't get here, but keep compiler quiet */
3512  return NULL;
3513  }
3514  PG_END_TRY();
3515 
3516  return row;
3517 }
void UnpinPortal(Portal portal)
Definition: portalmem.c:379
#define dTHX
Definition: ppport.h:3208
ErrorData * CopyErrorData(void)
Definition: elog.c:1474
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
void ReleaseCurrentSubTransaction(void)
Definition: xact.c:4449
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:1568
uint64 SPI_processed
Definition: spi.c:45
Portal SPI_cursor_find(const char *name)
Definition: spi.c:1521
void RollbackAndReleaseCurrentSubTransaction(void)
Definition: xact.c:4483
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:305
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4378
static void check_spi_usage_allowed(void)
Definition: plperl.c:3092
void SPI_cursor_close(Portal portal)
Definition: spi.c:1589
static SV * plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc, bool include_generated)
Definition: plperl.c:3012
void SPI_cursor_fetch(Portal portal, bool forward, long count)
Definition: spi.c:1533
#define PG_TRY()
Definition: elog.h:295
#define PG_END_TRY()
Definition: elog.h:320
char * message
Definition: elog.h:365

◆ plperl_spi_freeplan()

void plperl_spi_freeplan ( char *  )

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

3930 {
3931  SPIPlanPtr plan;
3932  plperl_query_desc *qdesc;
3933  plperl_query_entry *hash_entry;
3934 
3936 
3937  hash_entry = hash_search(plperl_active_interp->query_hash, query,
3938  HASH_FIND, NULL);
3939  if (hash_entry == NULL)
3940  elog(ERROR, "spi_freeplan: Invalid prepared query passed");
3941 
3942  qdesc = hash_entry->query_data;
3943  if (qdesc == NULL)
3944  elog(ERROR, "spi_freeplan: plperl query_hash value vanished");
3945  plan = qdesc->plan;
3946 
3947  /*
3948  * free all memory before SPI_freeplan, so if it dies, nothing will be
3949  * left over
3950  */
3952  HASH_REMOVE, NULL);
3953 
3954  MemoryContextDelete(qdesc->plan_cxt);
3955 
3956  SPI_freeplan(plan);
3957 }
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:908
#define ERROR
Definition: elog.h:43
MemoryContext plan_cxt
Definition: plperl.c:191
static void check_spi_usage_allowed(void)
Definition: plperl.c:3092
int SPI_freeplan(SPIPlanPtr plan)
Definition: spi.c:801
#define elog(elevel,...)
Definition: elog.h:214
plperl_query_desc * query_data
Definition: plperl.c:204

◆ plperl_spi_prepare()

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

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

3537 {
3538  volatile SPIPlanPtr plan = NULL;
3539  volatile MemoryContext plan_cxt = NULL;
3540  plperl_query_desc *volatile qdesc = NULL;
3541  plperl_query_entry *volatile hash_entry = NULL;
3542  MemoryContext oldcontext = CurrentMemoryContext;
3544  MemoryContext work_cxt;
3545  bool found;
3546  int i;
3547 
3549 
3551  MemoryContextSwitchTo(oldcontext);
3552 
3553  PG_TRY();
3554  {
3556 
3557  /************************************************************
3558  * Allocate the new querydesc structure
3559  *
3560  * The qdesc struct, as well as all its subsidiary data, lives in its
3561  * plan_cxt. But note that the SPIPlan does not.
3562  ************************************************************/
3564  "PL/Perl spi_prepare query",
3566  MemoryContextSwitchTo(plan_cxt);
3567  qdesc = (plperl_query_desc *) palloc0(sizeof(plperl_query_desc));
3568  snprintf(qdesc->qname, sizeof(qdesc->qname), "%p", qdesc);
3569  qdesc->plan_cxt = plan_cxt;
3570  qdesc->nargs = argc;
3571  qdesc->argtypes = (Oid *) palloc(argc * sizeof(Oid));
3572  qdesc->arginfuncs = (FmgrInfo *) palloc(argc * sizeof(FmgrInfo));
3573  qdesc->argtypioparams = (Oid *) palloc(argc * sizeof(Oid));
3574  MemoryContextSwitchTo(oldcontext);
3575 
3576  /************************************************************
3577  * Do the following work in a short-lived context so that we don't
3578  * leak a lot of memory in the PL/Perl function's SPI Proc context.
3579  ************************************************************/
3581  "PL/Perl spi_prepare workspace",
3583  MemoryContextSwitchTo(work_cxt);
3584 
3585  /************************************************************
3586  * Resolve argument type names and then look them up by oid
3587  * in the system cache, and remember the required information
3588  * for input conversion.
3589  ************************************************************/
3590  for (i = 0; i < argc; i++)
3591  {
3592  Oid typId,
3593  typInput,
3594  typIOParam;
3595  int32 typmod;
3596  char *typstr;
3597 
3598  typstr = sv2cstr(argv[i]);
3599  parseTypeString(typstr, &typId, &typmod, false);
3600  pfree(typstr);
3601 
3602  getTypeInputInfo(typId, &typInput, &typIOParam);
3603 
3604  qdesc->argtypes[i] = typId;
3605  fmgr_info_cxt(typInput, &(qdesc->arginfuncs[i]), plan_cxt);
3606  qdesc->argtypioparams[i] = typIOParam;
3607  }
3608 
3609  /* Make sure the query is validly encoded */
3610  pg_verifymbstr(query, strlen(query), false);
3611 
3612  /************************************************************
3613  * Prepare the plan and check for errors
3614  ************************************************************/
3615  plan = SPI_prepare(query, argc, qdesc->argtypes);
3616 
3617  if (plan == NULL)
3618  elog(ERROR, "SPI_prepare() failed:%s",
3620 
3621  /************************************************************
3622  * Save the plan into permanent memory (right now it's in the
3623  * SPI procCxt, which will go away at function end).
3624  ************************************************************/
3625  if (SPI_keepplan(plan))
3626  elog(ERROR, "SPI_keepplan() failed");
3627  qdesc->plan = plan;
3628 
3629  /************************************************************
3630  * Insert a hashtable entry for the plan.
3631  ************************************************************/
3633  qdesc->qname,
3634  HASH_ENTER, &found);
3635  hash_entry->query_data = qdesc;
3636 
3637  /* Get rid of workspace */
3638  MemoryContextDelete(work_cxt);
3639 
3640  /* Commit the inner transaction, return to outer xact context */
3642  MemoryContextSwitchTo(oldcontext);
3643  CurrentResourceOwner = oldowner;
3644  }
3645  PG_CATCH();
3646  {
3647  ErrorData *edata;
3648 
3649  /* Save error info */
3650  MemoryContextSwitchTo(oldcontext);
3651  edata = CopyErrorData();
3652  FlushErrorState();
3653 
3654  /* Drop anything we managed to allocate */
3655  if (hash_entry)
3657  qdesc->qname,
3658  HASH_REMOVE, NULL);
3659  if (plan_cxt)
3660  MemoryContextDelete(plan_cxt);
3661  if (plan)
3662  SPI_freeplan(plan);
3663 
3664  /* Abort the inner transaction */
3666  MemoryContextSwitchTo(oldcontext);
3667  CurrentResourceOwner = oldowner;
3668 
3669  /* Punt the error to Perl */
3670  croak_cstr(edata->message);
3671 
3672  /* Can't get here, but keep compiler quiet */
3673  return NULL;
3674  }
3675  PG_END_TRY();
3676 
3677  /************************************************************
3678  * Return the query's hash key to the caller.
3679  ************************************************************/
3680  return cstr2sv(qdesc->qname);
3681 }
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:1474
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:4449
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:908
unsigned int Oid
Definition: postgres_ext.h:31
void FlushErrorState(void)
Definition: elog.c:1568
signed int int32
Definition: c.h:355
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:1699
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:192
int SPI_keepplan(SPIPlanPtr plan)
Definition: spi.c:752
void RollbackAndReleaseCurrentSubTransaction(void)
Definition: xact.c:4483
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:136
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition: lsyscache.c:2702
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
bool pg_verifymbstr(const char *mbstr, int len, bool noError)
Definition: mbutils.c:1446
#define PG_CATCH()
Definition: elog.h:305
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4378
static void check_spi_usage_allowed(void)
Definition: plperl.c:3092
int SPI_freeplan(SPIPlanPtr plan)
Definition: spi.c:801
void * palloc(Size size)
Definition: mcxt.c:949
#define elog(elevel,...)
Definition: elog.h:214
int i
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
#define PG_TRY()
Definition: elog.h:295
#define snprintf
Definition: port.h:193
#define PG_END_TRY()
Definition: elog.h:320
char * message
Definition: elog.h:365
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 3373 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().

3374 {
3375  SV *cursor;
3376 
3377  /*
3378  * Execute the query inside a sub-transaction, so we can cope with errors
3379  * sanely
3380  */
3381  MemoryContext oldcontext = CurrentMemoryContext;
3383 
3385 
3387  /* Want to run inside function's memory context */
3388  MemoryContextSwitchTo(oldcontext);
3389 
3390  PG_TRY();
3391  {
3392  SPIPlanPtr plan;
3393  Portal portal;
3394 
3395  /* Make sure the query is validly encoded */
3396  pg_verifymbstr(query, strlen(query), false);
3397 
3398  /* Create a cursor for the query */
3399  plan = SPI_prepare(query, 0, NULL);
3400  if (plan == NULL)
3401  elog(ERROR, "SPI_prepare() failed:%s",
3403 
3404  portal = SPI_cursor_open(NULL, plan, NULL, NULL, false);
3405  SPI_freeplan(plan);
3406  if (portal == NULL)
3407  elog(ERROR, "SPI_cursor_open() failed:%s",
3409  cursor = cstr2sv(portal->name);
3410 
3411  PinPortal(portal);
3412 
3413  /* Commit the inner transaction, return to outer xact context */
3415  MemoryContextSwitchTo(oldcontext);
3416  CurrentResourceOwner = oldowner;
3417  }
3418  PG_CATCH();
3419  {
3420  ErrorData *edata;
3421 
3422  /* Save error info */
3423  MemoryContextSwitchTo(oldcontext);
3424  edata = CopyErrorData();
3425  FlushErrorState();
3426 
3427  /* Abort the inner transaction */
3429  MemoryContextSwitchTo(oldcontext);
3430  CurrentResourceOwner = oldowner;
3431 
3432  /* Punt the error to Perl */
3433  croak_cstr(edata->message);
3434 
3435  /* Can't get here, but keep compiler quiet */
3436  return NULL;
3437  }
3438  PG_END_TRY();
3439 
3440  return cursor;
3441 }
ErrorData * CopyErrorData(void)
Definition: elog.c:1474
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:4449
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:1568
int SPI_result
Definition: spi.c:47
const char * name
Definition: portal.h:118
#define ERROR
Definition: elog.h:43
const char * SPI_result_code_string(int code)
Definition: spi.c:1699
void RollbackAndReleaseCurrentSubTransaction(void)
Definition: xact.c:4483
void PinPortal(Portal portal)
Definition: portalmem.c:370
Definition: type.h:130
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
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:1446
#define PG_CATCH()
Definition: elog.h:305
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4378
static void check_spi_usage_allowed(void)
Definition: plperl.c:3092
int SPI_freeplan(SPIPlanPtr plan)
Definition: spi.c:801
#define elog(elevel,...)
Definition: elog.h:214
#define PG_TRY()
Definition: elog.h:295
#define PG_END_TRY()
Definition: elog.h:320
char * message
Definition: elog.h:365

◆ plperl_spi_query_prepared()

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

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

3812 {
3813  int i;
3814  char *nulls;
3815  Datum *argvalues;
3816  plperl_query_desc *qdesc;
3817  plperl_query_entry *hash_entry;
3818  SV *cursor;
3819  Portal portal = NULL;
3820 
3821  /*
3822  * Execute the query inside a sub-transaction, so we can cope with errors
3823  * sanely
3824  */
3825  MemoryContext oldcontext = CurrentMemoryContext;
3827 
3829 
3831  /* Want to run inside function's memory context */
3832  MemoryContextSwitchTo(oldcontext);
3833 
3834  PG_TRY();
3835  {
3836  /************************************************************
3837  * Fetch the saved plan descriptor, see if it's o.k.
3838  ************************************************************/
3839  hash_entry = hash_search(plperl_active_interp->query_hash, query,
3840  HASH_FIND, NULL);
3841  if (hash_entry == NULL)
3842  elog(ERROR, "spi_query_prepared: Invalid prepared query passed");
3843 
3844  qdesc = hash_entry->query_data;
3845  if (qdesc == NULL)
3846  elog(ERROR, "spi_query_prepared: plperl query_hash value vanished");
3847 
3848  if (qdesc->nargs != argc)
3849  elog(ERROR, "spi_query_prepared: expected %d argument(s), %d passed",
3850  qdesc->nargs, argc);
3851 
3852  /************************************************************
3853  * Set up arguments
3854  ************************************************************/
3855  if (argc > 0)
3856  {
3857  nulls = (char *) palloc(argc);
3858  argvalues = (Datum *) palloc(argc * sizeof(Datum));
3859  }
3860  else
3861  {
3862  nulls = NULL;
3863  argvalues = NULL;
3864  }
3865 
3866  for (i = 0; i < argc; i++)
3867  {
3868  bool isnull;
3869 
3870  argvalues[i] = plperl_sv_to_datum(argv[i],
3871  qdesc->argtypes[i],
3872  -1,
3873  NULL,
3874  &qdesc->arginfuncs[i],
3875  qdesc->argtypioparams[i],
3876  &isnull);
3877  nulls[i] = isnull ? 'n' : ' ';
3878  }
3879 
3880  /************************************************************
3881  * go
3882  ************************************************************/
3883  portal = SPI_cursor_open(NULL, qdesc->plan, argvalues, nulls,
3885  if (argc > 0)
3886  {
3887  pfree(argvalues);
3888  pfree(nulls);
3889  }
3890  if (portal == NULL)
3891  elog(ERROR, "SPI_cursor_open() failed:%s",
3893 
3894  cursor = cstr2sv(portal->name);
3895 
3896  PinPortal(portal);
3897 
3898  /* Commit the inner transaction, return to outer xact context */
3900  MemoryContextSwitchTo(oldcontext);
3901  CurrentResourceOwner = oldowner;
3902  }
3903  PG_CATCH();
3904  {
3905  ErrorData *edata;
3906 
3907  /* Save error info */
3908  MemoryContextSwitchTo(oldcontext);
3909  edata = CopyErrorData();
3910  FlushErrorState();
3911 
3912  /* Abort the inner transaction */
3914  MemoryContextSwitchTo(oldcontext);
3915  CurrentResourceOwner = oldowner;
3916 
3917  /* Punt the error to Perl */
3918  croak_cstr(edata->message);
3919 
3920  /* Can't get here, but keep compiler quiet */
3921  return NULL;
3922  }
3923  PG_END_TRY();
3924 
3925  return cursor;
3926 }
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:1474
Oid * argtypioparams
Definition: plperl.c:196
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
void ReleaseCurrentSubTransaction(void)
Definition: xact.c:4449
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:908
void FlushErrorState(void)
Definition: elog.c:1568
int SPI_result
Definition: spi.c:47
void pfree(void *pointer)
Definition: mcxt.c:1056
const char * name
Definition: portal.h:118
#define ERROR
Definition: elog.h:43
const char * SPI_result_code_string(int code)
Definition: spi.c:1699
void RollbackAndReleaseCurrentSubTransaction(void)
Definition: xact.c:4483
void PinPortal(Portal portal)
Definition: portalmem.c:370
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:305
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4378
static void check_spi_usage_allowed(void)
Definition: plperl.c:3092
void * palloc(Size size)
Definition: mcxt.c:949
#define elog(elevel,...)
Definition: elog.h:214
int i
plperl_proc_desc * prodesc
Definition: plperl.c:175
#define PG_TRY()
Definition: elog.h:295
static plperl_call_data * current_call_data
Definition: plperl.c:243
#define PG_END_TRY()
Definition: elog.h:320
char * message
Definition: elog.h:365
plperl_query_desc * query_data
Definition: plperl.c:204

◆ plperl_spi_rollback()

void plperl_spi_rollback ( void  )

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

3986 {
3987  MemoryContext oldcontext = CurrentMemoryContext;
3988 
3989  PG_TRY();
3990  {
3991  SPI_rollback();
3993  }
3994  PG_CATCH();
3995  {
3996  ErrorData *edata;
3997 
3998  /* Save error info */
3999  MemoryContextSwitchTo(oldcontext);
4000  edata = CopyErrorData();
4001  FlushErrorState();
4002 
4003  /* Punt the error to Perl */
4004  croak_cstr(edata->message);
4005  }
4006  PG_END_TRY();
4007 }
ErrorData * CopyErrorData(void)
Definition: elog.c:1474
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void SPI_rollback(void)
Definition: spi.c:333
void FlushErrorState(void)
Definition: elog.c:1568
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
static void croak_cstr(const char *str)
#define PG_CATCH()
Definition: elog.h:305
void SPI_start_transaction(void)
Definition: spi.c:212
#define PG_TRY()
Definition: elog.h:295
#define PG_END_TRY()
Definition: elog.h:320
char * message
Definition: elog.h:365

◆ 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:2735
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:610
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:624
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:578
Datum regtypein(PG_FUNCTION_ARGS)
Definition: regproc.c:1214
uintptr_t Datum
Definition: postgres.h:367
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
char * OidOutputFunctionCall(Oid functionId, Datum val)
Definition: fmgr.c:1657
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ plperl_util_elog()

void plperl_util_elog ( int  level,
SV *  msg 
)

Definition at line 4021 of file plperl.c.

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

4022 {
4023  MemoryContext oldcontext = CurrentMemoryContext;
4024  char *volatile cmsg = NULL;
4025 
4026  PG_TRY();
4027  {
4028  cmsg = sv2cstr(msg);
4029  elog(level, "%s", cmsg);
4030  pfree(cmsg);
4031  }
4032  PG_CATCH();
4033  {
4034  ErrorData *edata;
4035 
4036  /* Must reset elog.c's state */
4037  MemoryContextSwitchTo(oldcontext);
4038  edata = CopyErrorData();
4039  FlushErrorState();
4040 
4041  if (cmsg)
4042  pfree(cmsg);
4043 
4044  /* Punt the error to Perl */
4045  croak_cstr(edata->message);
4046  }
4047  PG_END_TRY();
4048 }
ErrorData * CopyErrorData(void)
Definition: elog.c:1474
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void FlushErrorState(void)
Definition: elog.c:1568
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:305
#define elog(elevel,...)
Definition: elog.h:214
#define PG_TRY()
Definition: elog.h:295
#define PG_END_TRY()
Definition: elog.h:320
char * message
Definition: elog.h:365
static char * sv2cstr(SV *sv)