aboutsummaryrefslogtreecommitdiff
path: root/src/pl/plperl/SPI.xs
blob: d1bab6d39b75e574282f70d9bdb5a9f87a942f93 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/* this must be first: */
#include "postgres.h"
/* Defined by Perl */
#undef _

/* perl stuff */
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"

#include "spi_internal.h"


/*
 * Implementation of plperl's elog() function
 *
 * If the error level is less than ERROR, we'll just emit the message and
 * return.  When it is ERROR, elog() will longjmp, which we catch and
 * turn into a Perl croak().  Note we are assuming that elog() can't have
 * any internal failures that are so bad as to require a transaction abort.
 *
 * This is out-of-line to suppress "might be clobbered by longjmp" warnings.
 */
static void
do_spi_elog(int level, char *message)
{
	MemoryContext oldcontext = CurrentMemoryContext;

	PG_TRY();
	{
		elog(level, "%s", message);
	}
	PG_CATCH();
	{
		ErrorData  *edata;

		/* Must reset elog.c's state */
		MemoryContextSwitchTo(oldcontext);
		edata = CopyErrorData();
		FlushErrorState();

		/* Punt the error to Perl */
		croak("%s", edata->message);
	}
	PG_END_TRY();
}


MODULE = SPI PREFIX = spi_

PROTOTYPES: ENABLE
VERSIONCHECK: DISABLE

void
spi_elog(level, message)
	int level
	char* message
	CODE:
		if (level > ERROR)		/* no PANIC allowed thanks */
			level = ERROR;
		if (level < DEBUG5)
			level = DEBUG5;
		do_spi_elog(level, message);

int
spi_DEBUG()

int
spi_LOG()

int
spi_INFO()

int
spi_NOTICE()

int
spi_WARNING()

int
spi_ERROR()

SV*
spi_spi_exec_query(query, ...)
	char* query;
	PREINIT:
		HV *ret_hash;
		int limit = 0;
	CODE:
		if (items > 2)
			croak("Usage: spi_exec_query(query, limit) or spi_exec_query(query)");
		if (items == 2)
			limit = SvIV(ST(1));
		ret_hash = plperl_spi_exec(query, limit);
		RETVAL = newRV_noinc((SV*) ret_hash);
	OUTPUT:
		RETVAL

void
spi_return_next(rv)
	SV *rv;
	CODE:
		plperl_return_next(rv);

BOOT:
    items = 0;  /* avoid 'unused variable' warning */