PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
pg_config.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * pg_config.c
4  * Expose same output as pg_config except as an SRF
5  *
6  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  * IDENTIFICATION
10  * src/backend/utils/misc/pg_config.c
11  *
12  *-------------------------------------------------------------------------
13  */
14 
15 #include "postgres.h"
16 
17 #include "funcapi.h"
18 #include "miscadmin.h"
19 #include "catalog/pg_type.h"
20 #include "common/config_info.h"
21 #include "utils/builtins.h"
22 #include "utils/elog.h"
23 #include "port.h"
24 
25 Datum
27 {
28  ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
29  Tuplestorestate *tupstore;
30  HeapTuple tuple;
31  TupleDesc tupdesc;
32  AttInMetadata *attinmeta;
33  MemoryContext per_query_ctx;
34  MemoryContext oldcontext;
35  ConfigData *configdata;
36  size_t configdata_len;
37  char *values[2];
38  int i = 0;
39 
40  /* check to see if caller supports us returning a tuplestore */
41  if (!rsinfo || !(rsinfo->allowedModes & SFRM_Materialize))
42  ereport(ERROR,
43  (errcode(ERRCODE_SYNTAX_ERROR),
44  errmsg("materialize mode required, but it is not "
45  "allowed in this context")));
46 
47  per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
48  oldcontext = MemoryContextSwitchTo(per_query_ctx);
49 
50  /* get the requested return tuple description */
51  tupdesc = CreateTupleDescCopy(rsinfo->expectedDesc);
52 
53  /*
54  * Check to make sure we have a reasonable tuple descriptor
55  */
56  if (tupdesc->natts != 2 ||
57  TupleDescAttr(tupdesc, 0)->atttypid != TEXTOID ||
58  TupleDescAttr(tupdesc, 1)->atttypid != TEXTOID)
59  ereport(ERROR,
60  (errcode(ERRCODE_SYNTAX_ERROR),
61  errmsg("query-specified return tuple and "
62  "function return type are not compatible")));
63 
64  /* OK to use it */
65  attinmeta = TupleDescGetAttInMetadata(tupdesc);
66 
67  /* let the caller know we're sending back a tuplestore */
68  rsinfo->returnMode = SFRM_Materialize;
69 
70  /* initialize our tuplestore */
71  tupstore = tuplestore_begin_heap(true, false, work_mem);
72 
73  configdata = get_configdata(my_exec_path, &configdata_len);
74  for (i = 0; i < configdata_len; i++)
75  {
76  values[0] = configdata[i].name;
77  values[1] = configdata[i].setting;
78 
79  tuple = BuildTupleFromCStrings(attinmeta, values);
80  tuplestore_puttuple(tupstore, tuple);
81  }
82 
83  /*
84  * no longer need the tuple descriptor reference created by
85  * TupleDescGetAttInMetadata()
86  */
87  ReleaseTupleDesc(tupdesc);
88 
89  tuplestore_donestoring(tupstore);
90  rsinfo->setResult = tupstore;
91 
92  /*
93  * SFRM_Materialize mode expects us to return a NULL Datum. The actual
94  * tuples are in our tuplestore and passed back through rsinfo->setResult.
95  * rsinfo->setDesc is set to the tuple description that we actually used
96  * to build our tuples with, so the caller can verify we did what it was
97  * expecting.
98  */
99  rsinfo->setDesc = tupdesc;
100  MemoryContextSwitchTo(oldcontext);
101 
102  return (Datum) 0;
103 }
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:102
#define TEXTOID
Definition: pg_type.h:324
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:84
#define tuplestore_donestoring(state)
Definition: tuplestore.h:60
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
int errcode(int sqlerrcode)
Definition: elog.c:575
HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
Definition: execTuples.c:1118
TupleDesc expectedDesc
Definition: execnodes.h:267
#define ERROR
Definition: elog.h:43
void tuplestore_puttuple(Tuplestorestate *state, HeapTuple tuple)
Definition: tuplestore.c:730
Datum pg_config(PG_FUNCTION_ARGS)
Definition: pg_config.c:26
#define ereport(elevel, rest)
Definition: elog.h:122
Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
Definition: tuplestore.c:318
char my_exec_path[MAXPGPATH]
Definition: globals.c:64
uintptr_t Datum
Definition: postgres.h:372
AttInMetadata * TupleDescGetAttInMetadata(TupleDesc tupdesc)
Definition: execTuples.c:1069
int work_mem
Definition: globals.c:113
int allowedModes
Definition: execnodes.h:268
SetFunctionReturnMode returnMode
Definition: execnodes.h:270
ConfigData * get_configdata(const char *my_exec_path, size_t *configdata_len)
Definition: config_info.c:33
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:202
Tuplestorestate * setResult
Definition: execnodes.h:273
static Datum values[MAXATTR]
Definition: bootstrap.c:164
ExprContext * econtext
Definition: execnodes.h:266
TupleDesc setDesc
Definition: execnodes.h:274
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
#define PG_FUNCTION_ARGS
Definition: fmgr.h:158
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:115