pg_query 1.0.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CHANGELOG.md +162 -40
- data/README.md +80 -69
- data/Rakefile +85 -4
- data/ext/pg_query/extconf.rb +4 -32
- data/ext/pg_query/guc-file.c +0 -0
- data/ext/pg_query/pg_query.c +104 -0
- data/ext/pg_query/pg_query.pb-c.c +37628 -0
- data/ext/pg_query/pg_query_deparse.c +9953 -0
- data/ext/pg_query/pg_query_fingerprint.c +292 -0
- data/ext/pg_query/pg_query_fingerprint.h +8 -0
- data/ext/pg_query/pg_query_internal.h +24 -0
- data/ext/pg_query/pg_query_json_plpgsql.c +738 -0
- data/ext/pg_query/pg_query_json_plpgsql.h +9 -0
- data/ext/pg_query/pg_query_normalize.c +437 -0
- data/ext/pg_query/pg_query_outfuncs.h +10 -0
- data/ext/pg_query/pg_query_outfuncs_json.c +297 -0
- data/ext/pg_query/pg_query_outfuncs_protobuf.c +237 -0
- data/ext/pg_query/pg_query_parse.c +148 -0
- data/ext/pg_query/pg_query_parse_plpgsql.c +460 -0
- data/ext/pg_query/pg_query_readfuncs.h +11 -0
- data/ext/pg_query/pg_query_readfuncs_protobuf.c +142 -0
- data/ext/pg_query/pg_query_ruby.c +108 -12
- data/ext/pg_query/pg_query_scan.c +173 -0
- data/ext/pg_query/pg_query_split.c +221 -0
- data/ext/pg_query/protobuf-c.c +3660 -0
- data/ext/pg_query/src_backend_catalog_namespace.c +1051 -0
- data/ext/pg_query/src_backend_catalog_pg_proc.c +142 -0
- data/ext/pg_query/src_backend_commands_define.c +117 -0
- data/ext/pg_query/src_backend_libpq_pqcomm.c +651 -0
- data/ext/pg_query/src_backend_nodes_bitmapset.c +513 -0
- data/ext/pg_query/src_backend_nodes_copyfuncs.c +6013 -0
- data/ext/pg_query/src_backend_nodes_equalfuncs.c +4003 -0
- data/ext/pg_query/src_backend_nodes_extensible.c +99 -0
- data/ext/pg_query/src_backend_nodes_list.c +922 -0
- data/ext/pg_query/src_backend_nodes_makefuncs.c +417 -0
- data/ext/pg_query/src_backend_nodes_nodeFuncs.c +1363 -0
- data/ext/pg_query/src_backend_nodes_value.c +84 -0
- data/ext/pg_query/src_backend_parser_gram.c +47456 -0
- data/ext/pg_query/src_backend_parser_parse_expr.c +313 -0
- data/ext/pg_query/src_backend_parser_parser.c +497 -0
- data/ext/pg_query/src_backend_parser_scan.c +7091 -0
- data/ext/pg_query/src_backend_parser_scansup.c +160 -0
- data/ext/pg_query/src_backend_postmaster_postmaster.c +2230 -0
- data/ext/pg_query/src_backend_storage_ipc_ipc.c +192 -0
- data/ext/pg_query/src_backend_storage_lmgr_s_lock.c +370 -0
- data/ext/pg_query/src_backend_tcop_postgres.c +776 -0
- data/ext/pg_query/src_backend_utils_adt_datum.c +326 -0
- data/ext/pg_query/src_backend_utils_adt_expandeddatum.c +98 -0
- data/ext/pg_query/src_backend_utils_adt_format_type.c +136 -0
- data/ext/pg_query/src_backend_utils_adt_ruleutils.c +1683 -0
- data/ext/pg_query/src_backend_utils_error_assert.c +74 -0
- data/ext/pg_query/src_backend_utils_error_elog.c +1748 -0
- data/ext/pg_query/src_backend_utils_fmgr_fmgr.c +570 -0
- data/ext/pg_query/src_backend_utils_hash_dynahash.c +1086 -0
- data/ext/pg_query/src_backend_utils_init_globals.c +168 -0
- data/ext/pg_query/src_backend_utils_mb_mbutils.c +839 -0
- data/ext/pg_query/src_backend_utils_misc_guc.c +1831 -0
- data/ext/pg_query/src_backend_utils_mmgr_aset.c +1560 -0
- data/ext/pg_query/src_backend_utils_mmgr_mcxt.c +1006 -0
- data/ext/pg_query/src_common_encnames.c +158 -0
- data/ext/pg_query/src_common_keywords.c +39 -0
- data/ext/pg_query/src_common_kwlist_d.h +1081 -0
- data/ext/pg_query/src_common_kwlookup.c +91 -0
- data/ext/pg_query/src_common_psprintf.c +158 -0
- data/ext/pg_query/src_common_string.c +86 -0
- data/ext/pg_query/src_common_stringinfo.c +336 -0
- data/ext/pg_query/src_common_wchar.c +1651 -0
- data/ext/pg_query/src_pl_plpgsql_src_pl_comp.c +1133 -0
- data/ext/pg_query/src_pl_plpgsql_src_pl_funcs.c +877 -0
- data/ext/pg_query/src_pl_plpgsql_src_pl_gram.c +6533 -0
- data/ext/pg_query/src_pl_plpgsql_src_pl_handler.c +107 -0
- data/ext/pg_query/src_pl_plpgsql_src_pl_reserved_kwlist_d.h +123 -0
- data/ext/pg_query/src_pl_plpgsql_src_pl_scanner.c +671 -0
- data/ext/pg_query/src_pl_plpgsql_src_pl_unreserved_kwlist_d.h +255 -0
- data/ext/pg_query/src_port_erand48.c +127 -0
- data/ext/pg_query/src_port_pg_bitutils.c +246 -0
- data/ext/pg_query/src_port_pgsleep.c +69 -0
- data/ext/pg_query/src_port_pgstrcasecmp.c +83 -0
- data/ext/pg_query/src_port_qsort.c +240 -0
- data/ext/pg_query/src_port_random.c +31 -0
- data/ext/pg_query/src_port_snprintf.c +1449 -0
- data/ext/pg_query/src_port_strerror.c +324 -0
- data/ext/pg_query/src_port_strnlen.c +39 -0
- data/ext/pg_query/xxhash.c +43 -0
- data/lib/pg_query.rb +7 -4
- data/lib/pg_query/constants.rb +21 -0
- data/lib/pg_query/deparse.rb +16 -991
- data/lib/pg_query/filter_columns.rb +86 -85
- data/lib/pg_query/fingerprint.rb +122 -87
- data/lib/pg_query/json_field_names.rb +1402 -0
- data/lib/pg_query/node.rb +31 -0
- data/lib/pg_query/param_refs.rb +42 -37
- data/lib/pg_query/parse.rb +220 -200
- data/lib/pg_query/parse_error.rb +1 -1
- data/lib/pg_query/pg_query_pb.rb +3211 -0
- data/lib/pg_query/scan.rb +23 -0
- data/lib/pg_query/treewalker.rb +24 -40
- data/lib/pg_query/truncate.rb +64 -43
- data/lib/pg_query/version.rb +2 -2
- metadata +102 -11
- data/ext/pg_query/pg_query_ruby.h +0 -10
- data/lib/pg_query/deep_dup.rb +0 -16
- data/lib/pg_query/deparse/alter_table.rb +0 -42
- data/lib/pg_query/deparse/interval.rb +0 -105
- data/lib/pg_query/legacy_parsetree.rb +0 -109
- data/lib/pg_query/node_types.rb +0 -282
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
#include "pg_query_outfuncs.h"
|
|
2
|
+
|
|
3
|
+
#include "postgres.h"
|
|
4
|
+
|
|
5
|
+
#include <ctype.h>
|
|
6
|
+
|
|
7
|
+
#include "access/relation.h"
|
|
8
|
+
#include "nodes/parsenodes.h"
|
|
9
|
+
#include "nodes/plannodes.h"
|
|
10
|
+
#include "nodes/value.h"
|
|
11
|
+
#include "utils/datum.h"
|
|
12
|
+
|
|
13
|
+
#include "pg_query_json_helper.c"
|
|
14
|
+
|
|
15
|
+
#define OUT_TYPE(typename, typename_c) StringInfo
|
|
16
|
+
|
|
17
|
+
#define OUT_NODE(typename, typename_c, typename_underscore, typename_underscore_upcase, typename_cast, fldname) \
|
|
18
|
+
{ \
|
|
19
|
+
WRITE_NODE_TYPE(CppAsString(typename)); \
|
|
20
|
+
_out##typename_c(out, (const typename_cast *) obj); \
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/* Write the label for the node type */
|
|
24
|
+
#define WRITE_NODE_TYPE(nodelabel) \
|
|
25
|
+
appendStringInfoString(out, "\"" nodelabel "\":{")
|
|
26
|
+
|
|
27
|
+
/* Write an integer field */
|
|
28
|
+
#define WRITE_INT_FIELD(outname, outname_json, fldname) \
|
|
29
|
+
if (node->fldname != 0) { \
|
|
30
|
+
appendStringInfo(out, "\"" CppAsString(outname_json) "\":%d,", node->fldname); \
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/* Write an unsigned integer field */
|
|
34
|
+
#define WRITE_UINT_FIELD(outname, outname_json, fldname) \
|
|
35
|
+
if (node->fldname != 0) { \
|
|
36
|
+
appendStringInfo(out, "\"" CppAsString(outname_json) "\":%u,", node->fldname); \
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/* Write a long-integer field */
|
|
40
|
+
#define WRITE_LONG_FIELD(outname, outname_json, fldname) \
|
|
41
|
+
if (node->fldname != 0) { \
|
|
42
|
+
appendStringInfo(out, "\"" CppAsString(outname_json) "\":%ld,", node->fldname); \
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* Write a char field (ie, one ascii character) */
|
|
46
|
+
#define WRITE_CHAR_FIELD(outname, outname_json, fldname) \
|
|
47
|
+
if (node->fldname != 0) { \
|
|
48
|
+
appendStringInfo(out, "\"" CppAsString(outname_json) "\":\"%c\",", node->fldname); \
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/* Write an enumerated-type field */
|
|
52
|
+
#define WRITE_ENUM_FIELD(typename, outname, outname_json, fldname) \
|
|
53
|
+
appendStringInfo(out, "\"" CppAsString(outname_json) "\":\"%s\",", \
|
|
54
|
+
_enumToString##typename(node->fldname));
|
|
55
|
+
|
|
56
|
+
/* Write a float field */
|
|
57
|
+
#define WRITE_FLOAT_FIELD(outname, outname_json, fldname) \
|
|
58
|
+
appendStringInfo(out, "\"" CppAsString(outname_json) "\":%f,", node->fldname)
|
|
59
|
+
|
|
60
|
+
/* Write a boolean field */
|
|
61
|
+
#define WRITE_BOOL_FIELD(outname, outname_json, fldname) \
|
|
62
|
+
if (node->fldname) { \
|
|
63
|
+
appendStringInfo(out, "\"" CppAsString(outname_json) "\":%s,", \
|
|
64
|
+
booltostr(node->fldname)); \
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/* Write a character-string (possibly NULL) field */
|
|
68
|
+
#define WRITE_STRING_FIELD(outname, outname_json, fldname) \
|
|
69
|
+
if (node->fldname != NULL) { \
|
|
70
|
+
appendStringInfo(out, "\"" CppAsString(outname_json) "\":"); \
|
|
71
|
+
_outToken(out, node->fldname); \
|
|
72
|
+
appendStringInfo(out, ","); \
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
#define WRITE_LIST_FIELD(outname, outname_json, fldname) \
|
|
76
|
+
if (node->fldname != NULL) { \
|
|
77
|
+
const ListCell *lc; \
|
|
78
|
+
appendStringInfo(out, "\"" CppAsString(outname_json) "\":"); \
|
|
79
|
+
appendStringInfoChar(out, '['); \
|
|
80
|
+
foreach(lc, node->fldname) { \
|
|
81
|
+
if (lfirst(lc) == NULL) \
|
|
82
|
+
appendStringInfoString(out, "{}"); \
|
|
83
|
+
else \
|
|
84
|
+
_outNode(out, lfirst(lc)); \
|
|
85
|
+
if (lnext(node->fldname, lc)) \
|
|
86
|
+
appendStringInfoString(out, ","); \
|
|
87
|
+
} \
|
|
88
|
+
appendStringInfo(out, "],"); \
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
#define WRITE_NODE_FIELD(outname, outname_json, fldname) \
|
|
92
|
+
if (true) { \
|
|
93
|
+
appendStringInfo(out, "\"" CppAsString(outname_json) "\":"); \
|
|
94
|
+
_outNode(out, &node->fldname); \
|
|
95
|
+
appendStringInfo(out, ","); \
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
#define WRITE_NODE_PTR_FIELD(outname, outname_json, fldname) \
|
|
99
|
+
if (node->fldname != NULL) { \
|
|
100
|
+
appendStringInfo(out, "\"" CppAsString(outname_json) "\":"); \
|
|
101
|
+
_outNode(out, node->fldname); \
|
|
102
|
+
appendStringInfo(out, ","); \
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
#define WRITE_SPECIFIC_NODE_FIELD(typename, typename_underscore, outname, outname_json, fldname) \
|
|
106
|
+
{ \
|
|
107
|
+
appendStringInfo(out, "\"" CppAsString(outname_json) "\":{"); \
|
|
108
|
+
_out##typename(out, &node->fldname); \
|
|
109
|
+
removeTrailingDelimiter(out); \
|
|
110
|
+
appendStringInfo(out, "},"); \
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
#define WRITE_SPECIFIC_NODE_PTR_FIELD(typename, typename_underscore, outname, outname_json, fldname) \
|
|
114
|
+
if (node->fldname != NULL) { \
|
|
115
|
+
appendStringInfo(out, "\"" CppAsString(outname_json) "\":{"); \
|
|
116
|
+
_out##typename(out, node->fldname); \
|
|
117
|
+
removeTrailingDelimiter(out); \
|
|
118
|
+
appendStringInfo(out, "},"); \
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
#define WRITE_BITMAPSET_FIELD(outname, outname_json, fldname) \
|
|
122
|
+
if (!bms_is_empty(node->fldname)) \
|
|
123
|
+
{ \
|
|
124
|
+
int x = 0; \
|
|
125
|
+
appendStringInfo(out, "\"" CppAsString(outname_json) "\":["); \
|
|
126
|
+
while ((x = bms_next_member(node->fldname, x)) >= 0) \
|
|
127
|
+
appendStringInfo(out, "%d,", x); \
|
|
128
|
+
removeTrailingDelimiter(out); \
|
|
129
|
+
appendStringInfo(out, "],"); \
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
static void _outNode(StringInfo out, const void *obj);
|
|
133
|
+
|
|
134
|
+
static void
|
|
135
|
+
_outList(StringInfo out, const List *node)
|
|
136
|
+
{
|
|
137
|
+
const ListCell *lc;
|
|
138
|
+
|
|
139
|
+
appendStringInfo(out, "\"items\":");
|
|
140
|
+
appendStringInfoChar(out, '[');
|
|
141
|
+
|
|
142
|
+
foreach(lc, node)
|
|
143
|
+
{
|
|
144
|
+
if (lfirst(lc) == NULL)
|
|
145
|
+
appendStringInfoString(out, "{}");
|
|
146
|
+
else
|
|
147
|
+
_outNode(out, lfirst(lc));
|
|
148
|
+
|
|
149
|
+
if (lnext(node, lc))
|
|
150
|
+
appendStringInfoString(out, ",");
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
appendStringInfoChar(out, ']');
|
|
154
|
+
appendStringInfo(out, ",");
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
static void
|
|
158
|
+
_outIntList(StringInfo out, const List *node)
|
|
159
|
+
{
|
|
160
|
+
const ListCell *lc;
|
|
161
|
+
|
|
162
|
+
appendStringInfo(out, "\"items\":");
|
|
163
|
+
appendStringInfoChar(out, '[');
|
|
164
|
+
|
|
165
|
+
foreach(lc, node)
|
|
166
|
+
{
|
|
167
|
+
appendStringInfo(out, "%d", lfirst_int(lc));
|
|
168
|
+
|
|
169
|
+
if (lnext(node, lc))
|
|
170
|
+
appendStringInfoString(out, ",");
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
appendStringInfoChar(out, ']');
|
|
174
|
+
appendStringInfo(out, ",");
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
static void
|
|
178
|
+
_outOidList(StringInfo out, const List *node)
|
|
179
|
+
{
|
|
180
|
+
const ListCell *lc;
|
|
181
|
+
|
|
182
|
+
appendStringInfo(out, "\"items\":");
|
|
183
|
+
appendStringInfoChar(out, '[');
|
|
184
|
+
|
|
185
|
+
foreach(lc, node)
|
|
186
|
+
{
|
|
187
|
+
appendStringInfo(out, "%u", lfirst_oid(lc));
|
|
188
|
+
|
|
189
|
+
if (lnext(node, lc))
|
|
190
|
+
appendStringInfoString(out, ",");
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
appendStringInfoChar(out, ']');
|
|
194
|
+
appendStringInfo(out, ",");
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
static void
|
|
198
|
+
_outInteger(StringInfo out, const Value *node)
|
|
199
|
+
{
|
|
200
|
+
appendStringInfo(out, "\"ival\":%d,", node->val.ival);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
static void
|
|
204
|
+
_outFloat(StringInfo out, const Value *node)
|
|
205
|
+
{
|
|
206
|
+
appendStringInfo(out, "\"str\":");
|
|
207
|
+
_outToken(out, node->val.str);
|
|
208
|
+
appendStringInfo(out, ",");
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
static void
|
|
212
|
+
_outString(StringInfo out, const Value *node)
|
|
213
|
+
{
|
|
214
|
+
appendStringInfo(out, "\"str\":");
|
|
215
|
+
_outToken(out, node->val.str);
|
|
216
|
+
appendStringInfo(out, ",");
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
static void
|
|
220
|
+
_outBitString(StringInfo out, const Value *node)
|
|
221
|
+
{
|
|
222
|
+
appendStringInfo(out, "\"str\":");
|
|
223
|
+
_outToken(out, node->val.str);
|
|
224
|
+
appendStringInfo(out, ",");
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
static void
|
|
228
|
+
_outNull(StringInfo out, const Value *node)
|
|
229
|
+
{
|
|
230
|
+
// No fields
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
#include "pg_query_enum_defs.c"
|
|
234
|
+
#include "pg_query_outfuncs_defs.c"
|
|
235
|
+
|
|
236
|
+
static void
|
|
237
|
+
_outNode(StringInfo out, const void *obj)
|
|
238
|
+
{
|
|
239
|
+
if (obj == NULL)
|
|
240
|
+
{
|
|
241
|
+
appendStringInfoString(out, "null");
|
|
242
|
+
}
|
|
243
|
+
else
|
|
244
|
+
{
|
|
245
|
+
appendStringInfoChar(out, '{');
|
|
246
|
+
switch (nodeTag(obj))
|
|
247
|
+
{
|
|
248
|
+
#include "pg_query_outfuncs_conds.c"
|
|
249
|
+
|
|
250
|
+
default:
|
|
251
|
+
elog(WARNING, "could not dump unrecognized node type: %d",
|
|
252
|
+
(int) nodeTag(obj));
|
|
253
|
+
|
|
254
|
+
appendStringInfo(out, "}");
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
removeTrailingDelimiter(out);
|
|
258
|
+
appendStringInfo(out, "}}");
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
char *
|
|
263
|
+
pg_query_nodes_to_json(const void *obj)
|
|
264
|
+
{
|
|
265
|
+
StringInfoData out;
|
|
266
|
+
const ListCell *lc;
|
|
267
|
+
|
|
268
|
+
initStringInfo(&out);
|
|
269
|
+
|
|
270
|
+
if (obj == NULL) /* Make sure we generate valid JSON for empty queries */
|
|
271
|
+
{
|
|
272
|
+
appendStringInfo(&out, "{\"version\":%d,\"stmts\":[]}", PG_VERSION_NUM);
|
|
273
|
+
}
|
|
274
|
+
else
|
|
275
|
+
{
|
|
276
|
+
appendStringInfoString(&out, "{");
|
|
277
|
+
appendStringInfo(&out, "\"version\":%d,", PG_VERSION_NUM);
|
|
278
|
+
appendStringInfoString(&out, "\"stmts\":");
|
|
279
|
+
appendStringInfoChar(&out, '[');
|
|
280
|
+
|
|
281
|
+
foreach(lc, obj)
|
|
282
|
+
{
|
|
283
|
+
appendStringInfoChar(&out, '{');
|
|
284
|
+
_outRawStmt(&out, lfirst(lc));
|
|
285
|
+
removeTrailingDelimiter(&out);
|
|
286
|
+
appendStringInfoChar(&out, '}');
|
|
287
|
+
|
|
288
|
+
if (lnext(obj, lc))
|
|
289
|
+
appendStringInfoString(&out, ",");
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
appendStringInfoChar(&out, ']');
|
|
293
|
+
appendStringInfoString(&out, "}");
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return out.data;
|
|
297
|
+
}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
#include "pg_query_outfuncs.h"
|
|
2
|
+
|
|
3
|
+
#include "postgres.h"
|
|
4
|
+
#include <ctype.h>
|
|
5
|
+
#include "access/relation.h"
|
|
6
|
+
#include "nodes/parsenodes.h"
|
|
7
|
+
#include "nodes/plannodes.h"
|
|
8
|
+
#include "nodes/value.h"
|
|
9
|
+
#include "utils/datum.h"
|
|
10
|
+
|
|
11
|
+
#include "protobuf/pg_query.pb-c.h"
|
|
12
|
+
|
|
13
|
+
#define OUT_TYPE(typename, typename_c) PgQuery__##typename_c*
|
|
14
|
+
|
|
15
|
+
#define OUT_NODE(typename, typename_c, typename_underscore, typename_underscore_upcase, typename_cast, fldname) \
|
|
16
|
+
{ \
|
|
17
|
+
PgQuery__##typename_c *__node = palloc(sizeof(PgQuery__##typename_c)); \
|
|
18
|
+
pg_query__##typename_underscore##__init(__node); \
|
|
19
|
+
_out##typename_c(__node, (const typename_cast *) obj); \
|
|
20
|
+
out->fldname = __node; \
|
|
21
|
+
out->node_case = PG_QUERY__NODE__NODE_##typename_underscore_upcase; \
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
#define WRITE_INT_FIELD(outname, outname_json, fldname) out->outname = node->fldname;
|
|
25
|
+
#define WRITE_UINT_FIELD(outname, outname_json, fldname) out->outname = node->fldname;
|
|
26
|
+
#define WRITE_LONG_FIELD(outname, outname_json, fldname) out->outname = node->fldname;
|
|
27
|
+
#define WRITE_FLOAT_FIELD(outname, outname_json, fldname) out->outname = node->fldname;
|
|
28
|
+
#define WRITE_BOOL_FIELD(outname, outname_json, fldname) out->outname = node->fldname;
|
|
29
|
+
|
|
30
|
+
#define WRITE_CHAR_FIELD(outname, outname_json, fldname) \
|
|
31
|
+
if (node->fldname != 0) { \
|
|
32
|
+
out->outname = palloc(sizeof(char) * 2); \
|
|
33
|
+
out->outname[0] = node->fldname; \
|
|
34
|
+
out->outname[1] = '\0'; \
|
|
35
|
+
}
|
|
36
|
+
#define WRITE_STRING_FIELD(outname, outname_json, fldname) \
|
|
37
|
+
if (node->fldname != NULL) { \
|
|
38
|
+
out->outname = pstrdup(node->fldname); \
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
#define WRITE_ENUM_FIELD(typename, outname, outname_json, fldname) \
|
|
42
|
+
out->outname = _enumToInt##typename(node->fldname);
|
|
43
|
+
|
|
44
|
+
#define WRITE_LIST_FIELD(outname, outname_json, fldname) \
|
|
45
|
+
if (node->fldname != NULL) { \
|
|
46
|
+
out->n_##outname = list_length(node->fldname); \
|
|
47
|
+
out->outname = palloc(sizeof(PgQuery__Node*) * out->n_##outname); \
|
|
48
|
+
for (int i = 0; i < out->n_##outname; i++) \
|
|
49
|
+
{ \
|
|
50
|
+
PgQuery__Node *__node = palloc(sizeof(PgQuery__Node)); \
|
|
51
|
+
pg_query__node__init(__node); \
|
|
52
|
+
out->outname[i] = __node; \
|
|
53
|
+
_outNode(out->outname[i], list_nth(node->fldname, i)); \
|
|
54
|
+
} \
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
#define WRITE_BITMAPSET_FIELD(outname, outname_json, fldname) \
|
|
58
|
+
if (!bms_is_empty(node->fldname)) \
|
|
59
|
+
{ \
|
|
60
|
+
int x = 0; \
|
|
61
|
+
int i = 0; \
|
|
62
|
+
out->n_##outname = bms_num_members(node->fldname); \
|
|
63
|
+
out->outname = palloc(sizeof(PgQuery__Node*) * out->n_##outname); \
|
|
64
|
+
while ((x = bms_first_member(node->fldname)) >= 0) \
|
|
65
|
+
out->outname[i++] = x; \
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
#define WRITE_NODE_FIELD(outname, outname_json, fldname) \
|
|
69
|
+
{ \
|
|
70
|
+
PgQuery__Node *__node = palloc(sizeof(PgQuery__Node)); \
|
|
71
|
+
pg_query__node__init(__node); \
|
|
72
|
+
out->outname = __node; \
|
|
73
|
+
_outNode(out->outname, &node->fldname); \
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
#define WRITE_NODE_PTR_FIELD(outname, outname_json, fldname) \
|
|
77
|
+
if (node->fldname != NULL) { \
|
|
78
|
+
PgQuery__Node *__node = palloc(sizeof(PgQuery__Node)); \
|
|
79
|
+
pg_query__node__init(__node); \
|
|
80
|
+
out->outname = __node; \
|
|
81
|
+
_outNode(out->outname, node->fldname); \
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
#define WRITE_SPECIFIC_NODE_FIELD(typename, typename_underscore, outname, outname_json, fldname) \
|
|
85
|
+
{ \
|
|
86
|
+
PgQuery__##typename *__node = palloc(sizeof(PgQuery__##typename)); \
|
|
87
|
+
pg_query__##typename_underscore##__init(__node); \
|
|
88
|
+
_out##typename(__node, &node->fldname); \
|
|
89
|
+
out->outname = __node; \
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
#define WRITE_SPECIFIC_NODE_PTR_FIELD(typename, typename_underscore, outname, outname_json, fldname) \
|
|
93
|
+
if (node->fldname != NULL) { \
|
|
94
|
+
PgQuery__##typename *__node = palloc(sizeof(PgQuery__##typename)); \
|
|
95
|
+
pg_query__##typename_underscore##__init(__node); \
|
|
96
|
+
_out##typename(__node, node->fldname); \
|
|
97
|
+
out->outname = __node; \
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
static void _outNode(PgQuery__Node* out, const void *obj);
|
|
101
|
+
|
|
102
|
+
static void
|
|
103
|
+
_outList(PgQuery__List* out, const List *node)
|
|
104
|
+
{
|
|
105
|
+
const ListCell *lc;
|
|
106
|
+
int i = 0;
|
|
107
|
+
out->n_items = list_length(node);
|
|
108
|
+
out->items = palloc(sizeof(PgQuery__Node*) * out->n_items);
|
|
109
|
+
foreach(lc, node)
|
|
110
|
+
{
|
|
111
|
+
out->items[i] = palloc(sizeof(PgQuery__Node));
|
|
112
|
+
pg_query__node__init(out->items[i]);
|
|
113
|
+
_outNode(out->items[i], lfirst(lc));
|
|
114
|
+
i++;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
static void
|
|
119
|
+
_outIntList(PgQuery__IntList* out, const List *node)
|
|
120
|
+
{
|
|
121
|
+
const ListCell *lc;
|
|
122
|
+
int i = 0;
|
|
123
|
+
out->n_items = list_length(node);
|
|
124
|
+
out->items = palloc(sizeof(PgQuery__Node*) * out->n_items);
|
|
125
|
+
foreach(lc, node)
|
|
126
|
+
{
|
|
127
|
+
out->items[i] = palloc(sizeof(PgQuery__Node));
|
|
128
|
+
pg_query__node__init(out->items[i]);
|
|
129
|
+
_outNode(out->items[i], lfirst(lc));
|
|
130
|
+
i++;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
static void
|
|
135
|
+
_outOidList(PgQuery__OidList* out, const List *node)
|
|
136
|
+
{
|
|
137
|
+
const ListCell *lc;
|
|
138
|
+
int i = 0;
|
|
139
|
+
out->n_items = list_length(node);
|
|
140
|
+
out->items = palloc(sizeof(PgQuery__Node*) * out->n_items);
|
|
141
|
+
foreach(lc, node)
|
|
142
|
+
{
|
|
143
|
+
out->items[i] = palloc(sizeof(PgQuery__Node));
|
|
144
|
+
pg_query__node__init(out->items[i]);
|
|
145
|
+
_outNode(out->items[i], lfirst(lc));
|
|
146
|
+
i++;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// TODO: Add Bitmapset
|
|
151
|
+
|
|
152
|
+
static void
|
|
153
|
+
_outInteger(PgQuery__Integer* out, const Value *node)
|
|
154
|
+
{
|
|
155
|
+
out->ival = node->val.ival;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
static void
|
|
159
|
+
_outFloat(PgQuery__Float* out, const Value *node)
|
|
160
|
+
{
|
|
161
|
+
out->str = node->val.str;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
static void
|
|
165
|
+
_outString(PgQuery__String* out, const Value *node)
|
|
166
|
+
{
|
|
167
|
+
out->str = node->val.str;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
static void
|
|
171
|
+
_outBitString(PgQuery__BitString* out, const Value *node)
|
|
172
|
+
{
|
|
173
|
+
out->str = node->val.str;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
static void
|
|
177
|
+
_outNull(PgQuery__Null* out, const Value *node)
|
|
178
|
+
{
|
|
179
|
+
// Null has no fields
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
#include "pg_query_enum_defs.c"
|
|
183
|
+
#include "pg_query_outfuncs_defs.c"
|
|
184
|
+
|
|
185
|
+
static void
|
|
186
|
+
_outNode(PgQuery__Node* out, const void *obj)
|
|
187
|
+
{
|
|
188
|
+
if (obj == NULL)
|
|
189
|
+
return; // Keep out as NULL
|
|
190
|
+
|
|
191
|
+
switch (nodeTag(obj))
|
|
192
|
+
{
|
|
193
|
+
#include "pg_query_outfuncs_conds.c"
|
|
194
|
+
|
|
195
|
+
default:
|
|
196
|
+
printf("could not dump unrecognized node type: %d", (int) nodeTag(obj));
|
|
197
|
+
elog(WARNING, "could not dump unrecognized node type: %d",
|
|
198
|
+
(int) nodeTag(obj));
|
|
199
|
+
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
PgQueryProtobuf
|
|
205
|
+
pg_query_nodes_to_protobuf(const void *obj)
|
|
206
|
+
{
|
|
207
|
+
PgQueryProtobuf protobuf;
|
|
208
|
+
const ListCell *lc;
|
|
209
|
+
int i = 0;
|
|
210
|
+
PgQuery__ParseResult parse_result = PG_QUERY__PARSE_RESULT__INIT;
|
|
211
|
+
|
|
212
|
+
parse_result.version = PG_VERSION_NUM;
|
|
213
|
+
|
|
214
|
+
if (obj == NULL) {
|
|
215
|
+
parse_result.n_stmts = 0;
|
|
216
|
+
parse_result.stmts = NULL;
|
|
217
|
+
}
|
|
218
|
+
else
|
|
219
|
+
{
|
|
220
|
+
parse_result.n_stmts = list_length(obj);
|
|
221
|
+
parse_result.stmts = palloc(sizeof(PgQuery__RawStmt*) * parse_result.n_stmts);
|
|
222
|
+
foreach(lc, obj)
|
|
223
|
+
{
|
|
224
|
+
parse_result.stmts[i] = palloc(sizeof(PgQuery__RawStmt));
|
|
225
|
+
pg_query__raw_stmt__init(parse_result.stmts[i]);
|
|
226
|
+
_outRawStmt(parse_result.stmts[i], lfirst(lc));
|
|
227
|
+
i++;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
protobuf.len = pg_query__parse_result__get_packed_size(&parse_result);
|
|
232
|
+
// Note: This is intentionally malloc so exiting the memory context doesn't free this
|
|
233
|
+
protobuf.data = malloc(sizeof(char) * protobuf.len);
|
|
234
|
+
pg_query__parse_result__pack(&parse_result, (void*) protobuf.data);
|
|
235
|
+
|
|
236
|
+
return protobuf;
|
|
237
|
+
}
|