-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathshow_eudc.c
93 lines (75 loc) · 2.62 KB
/
show_eudc.c
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
/*
* Filename: eudc_show.c
* Description: Function showing eudc installation
* status.
*/
#include "postgres.h"
#include "funcapi.h"
#include "executor/spi.h"
#define sql "SELECT conproc::text,\n"\
" pg_catalog.pg_encoding_to_char(conforencoding)::text,\n"\
" pg_catalog.pg_encoding_to_char(contoencoding)::text,\n" \
" CASE WHEN condefault::bool THEN 'yes' ELSE 'no' END \n" \
"FROM pg_conversion \n" \
"WHERE conproc::text like '%eudc%'"
/* Prototypes to prevent potential gcc warnings. */
Datum show_eudc(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(show_eudc);
Datum
show_eudc(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
HeapTupleHeader *values = NULL;
/* Stuff done only on the first call of the function. */
if (SRF_IS_FIRSTCALL()) {
MemoryContext oldcontext, spicontext;
int ret, i;
TupleDesc tupdesc;
SPITupleTable *tuptable = NULL;
/* create a function context for cross-call persistence */
funcctx = SRF_FIRSTCALL_INIT();
/* switch to memory context appropriate for multiple function calls */
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
SPI_connect();
ret = SPI_exec(sql, 0);
if (ret == SPI_OK_SELECT) {
tupdesc = SPI_tuptable->tupdesc;
tuptable = SPI_tuptable;
} else {
funcctx->max_calls = 0;
elog(WARNING, "UNEXPECTED EXECUTION RESULT: %s %d\n%s",
__FILE__, __LINE__, sql);
}
if(SPI_processed > 0){
funcctx->max_calls = SPI_processed;
/* Dont want allocate memory in SPI context */
spicontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
values = (HeapTupleHeader *)
palloc(SPI_processed * sizeof(HeapTupleHeader));
MemoryContextSwitchTo(spicontext);
for(i=0; i < SPI_processed; i++)
values[i] = SPI_returntuple(tuptable->vals[i], tupdesc);
}
/* Build a tuple descriptor for our result type */
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) {
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("function returning record called in context "
"that cannot accept type record")));
}
/* Preserved result during sub-sequnce call */
funcctx->user_fctx = values;
SPI_finish();
MemoryContextSwitchTo(oldcontext);
}/* End if(SRF_IS_FIRSTCALL) */
/* stuff done on every call of the function */
funcctx = SRF_PERCALL_SETUP();
if (funcctx->call_cntr < funcctx->max_calls) {
values = (HeapTupleHeader *) funcctx->user_fctx;
SRF_RETURN_NEXT(funcctx,
PointerGetDatum(values[funcctx->call_cntr - 1]));
} else {
/* Do when there is no more left. */
SRF_RETURN_DONE(funcctx);
}
}/* end show_eudc */