pg_query 2.1.4 → 2.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +29 -0
- data/README.md +32 -0
- data/Rakefile +2 -2
- data/ext/pg_query/include/access/twophase.h +2 -0
- data/ext/pg_query/include/access/xact.h +6 -0
- data/ext/pg_query/include/access/xlog_internal.h +10 -1
- data/ext/pg_query/include/access/xlogreader.h +10 -0
- data/ext/pg_query/include/catalog/dependency.h +2 -0
- data/ext/pg_query/include/catalog/pg_class.h +1 -1
- data/ext/pg_query/include/catalog/pg_class_d.h +1 -1
- data/ext/pg_query/include/catalog/pg_control.h +2 -0
- data/ext/pg_query/include/catalog/pg_operator.h +3 -1
- data/ext/pg_query/include/catalog/pg_publication.h +3 -0
- data/ext/pg_query/include/catalog/pg_type.h +1 -0
- data/ext/pg_query/include/commands/async.h +1 -1
- data/ext/pg_query/include/commands/tablespace.h +2 -0
- data/ext/pg_query/include/commands/trigger.h +8 -0
- data/ext/pg_query/include/lib/simplehash.h +13 -13
- data/ext/pg_query/include/libpq/libpq.h +1 -0
- data/ext/pg_query/include/mb/pg_wchar.h +1 -0
- data/ext/pg_query/include/miscadmin.h +24 -11
- data/ext/pg_query/include/nodes/execnodes.h +2 -2
- data/ext/pg_query/include/nodes/parsenodes.h +5 -4
- data/ext/pg_query/include/nodes/pathnodes.h +2 -1
- data/ext/pg_query/include/nodes/pg_list.h +1 -0
- data/ext/pg_query/include/nodes/plannodes.h +18 -3
- data/ext/pg_query/include/optimizer/optimizer.h +0 -5
- data/ext/pg_query/include/parser/gram.h +2 -2
- data/ext/pg_query/include/parser/kwlist.h +1 -1
- data/ext/pg_query/include/parser/parse_coerce.h +1 -0
- data/ext/pg_query/include/pg_config.h +16 -13
- data/ext/pg_query/include/pg_query.h +2 -2
- data/ext/pg_query/include/pg_query_fingerprint_defs.c +286 -314
- data/ext/pg_query/include/pg_query_outfuncs_defs.c +1 -0
- data/ext/pg_query/include/pg_query_readfuncs_defs.c +1 -0
- data/ext/pg_query/include/pgstat.h +2 -1
- data/ext/pg_query/include/plpgsql.h +2 -2
- data/ext/pg_query/include/port/pg_bitutils.h +48 -2
- data/ext/pg_query/include/port.h +4 -0
- data/ext/pg_query/include/protobuf/pg_query.pb-c.h +4 -3
- data/ext/pg_query/include/replication/reorderbuffer.h +6 -5
- data/ext/pg_query/include/replication/slot.h +1 -1
- data/ext/pg_query/include/storage/block.h +1 -1
- data/ext/pg_query/include/storage/lock.h +6 -5
- data/ext/pg_query/include/storage/lwlock.h +1 -0
- data/ext/pg_query/include/storage/proc.h +14 -0
- data/ext/pg_query/include/storage/s_lock.h +24 -0
- data/ext/pg_query/include/tcop/pquery.h +6 -0
- data/ext/pg_query/include/utils/builtins.h +1 -0
- data/ext/pg_query/include/utils/inval.h +1 -0
- data/ext/pg_query/include/utils/portal.h +13 -0
- data/ext/pg_query/include/utils/rel.h +0 -1
- data/ext/pg_query/include/utils/relcache.h +1 -2
- data/ext/pg_query/include/utils/snapmgr.h +1 -0
- data/ext/pg_query/pg_query.pb-c.c +18 -5
- data/ext/pg_query/pg_query_deparse.c +8 -8
- data/ext/pg_query/pg_query_fingerprint.c +1 -0
- data/ext/pg_query/pg_query_json_plpgsql.c +68 -0
- data/ext/pg_query/pg_query_normalize.c +43 -7
- data/ext/pg_query/pg_query_outfuncs.h +1 -0
- data/ext/pg_query/pg_query_outfuncs_json.c +11 -0
- data/ext/pg_query/pg_query_parse_plpgsql.c +58 -15
- data/ext/pg_query/src_backend_catalog_namespace.c +1 -0
- data/ext/pg_query/src_backend_libpq_pqcomm.c +8 -0
- data/ext/pg_query/src_backend_nodes_copyfuncs.c +23 -33
- data/ext/pg_query/src_backend_nodes_equalfuncs.c +1 -0
- data/ext/pg_query/src_backend_nodes_list.c +12 -0
- data/ext/pg_query/src_backend_parser_gram.c +18 -3
- data/ext/pg_query/src_backend_parser_scan.c +493 -253
- data/ext/pg_query/src_backend_tcop_postgres.c +11 -1
- data/ext/pg_query/src_backend_utils_adt_ruleutils.c +38 -10
- data/ext/pg_query/src_backend_utils_misc_guc.c +1 -0
- data/ext/pg_query/src_common_wchar.c +11 -0
- data/ext/pg_query/src_pl_plpgsql_src_pl_comp.c +4 -2
- data/ext/pg_query/src_pl_plpgsql_src_pl_gram.c +1 -1
- data/ext/pg_query/src_port_pg_bitutils.c +1 -22
- data/ext/pg_query/src_port_snprintf.c +9 -7
- data/lib/pg_query/deparse.rb +7 -1
- data/lib/pg_query/fingerprint.rb +13 -2
- data/lib/pg_query/parse.rb +5 -3
- data/lib/pg_query/pg_query_pb.rb +2 -1
- data/lib/pg_query/treewalker.rb +6 -0
- data/lib/pg_query/version.rb +1 -1
- metadata +2 -2
@@ -8,6 +8,8 @@
|
|
8
8
|
#include "mb/pg_wchar.h"
|
9
9
|
#include "nodes/nodeFuncs.h"
|
10
10
|
|
11
|
+
#include "pg_query_outfuncs.h"
|
12
|
+
|
11
13
|
/*
|
12
14
|
* Struct for tracking locations/lengths of constants during normalization
|
13
15
|
*/
|
@@ -331,6 +333,27 @@ static void RecordConstLocation(pgssConstLocations *jstate, int location)
|
|
331
333
|
}
|
332
334
|
}
|
333
335
|
|
336
|
+
static void record_defelem_arg_location(pgssConstLocations *jstate, int location)
|
337
|
+
{
|
338
|
+
for (int i = location; i < jstate->query_len; i++) {
|
339
|
+
if (jstate->query[i] == '\'' || jstate->query[i] == '$') {
|
340
|
+
RecordConstLocation(jstate, i);
|
341
|
+
break;
|
342
|
+
}
|
343
|
+
}
|
344
|
+
}
|
345
|
+
|
346
|
+
static void record_matching_string(pgssConstLocations *jstate, const char *str)
|
347
|
+
{
|
348
|
+
char *loc = NULL;
|
349
|
+
if (str == NULL)
|
350
|
+
return;
|
351
|
+
|
352
|
+
loc = strstr(jstate->query, str);
|
353
|
+
if (loc != NULL)
|
354
|
+
RecordConstLocation(jstate, loc - jstate->query - 1);
|
355
|
+
}
|
356
|
+
|
334
357
|
static bool const_record_walker(Node *node, pgssConstLocations *jstate)
|
335
358
|
{
|
336
359
|
bool result;
|
@@ -362,13 +385,12 @@ static bool const_record_walker(Node *node, pgssConstLocations *jstate)
|
|
362
385
|
case T_DefElem:
|
363
386
|
{
|
364
387
|
DefElem * defElem = (DefElem *) node;
|
365
|
-
if (defElem->arg
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
}
|
388
|
+
if (defElem->arg == NULL) {
|
389
|
+
// No argument
|
390
|
+
} else if (IsA(defElem->arg, String)) {
|
391
|
+
record_defelem_arg_location(jstate, defElem->location);
|
392
|
+
} else if (IsA(defElem->arg, List) && list_length((List *) defElem->arg) == 1 && IsA(linitial((List *) defElem->arg), String)) {
|
393
|
+
record_defelem_arg_location(jstate, defElem->location);
|
372
394
|
}
|
373
395
|
return const_record_walker((Node *) ((DefElem *) node)->arg, jstate);
|
374
396
|
}
|
@@ -387,6 +409,20 @@ static bool const_record_walker(Node *node, pgssConstLocations *jstate)
|
|
387
409
|
return const_record_walker((Node *) ((AlterRoleStmt *) node)->options, jstate);
|
388
410
|
case T_DeclareCursorStmt:
|
389
411
|
return const_record_walker((Node *) ((DeclareCursorStmt *) node)->query, jstate);
|
412
|
+
case T_CreateFunctionStmt:
|
413
|
+
return const_record_walker((Node *) ((CreateFunctionStmt *) node)->options, jstate);
|
414
|
+
case T_DoStmt:
|
415
|
+
return const_record_walker((Node *) ((DoStmt *) node)->args, jstate);
|
416
|
+
case T_CreateSubscriptionStmt:
|
417
|
+
record_matching_string(jstate, ((CreateSubscriptionStmt *) node)->conninfo);
|
418
|
+
break;
|
419
|
+
case T_AlterSubscriptionStmt:
|
420
|
+
record_matching_string(jstate, ((CreateSubscriptionStmt *) node)->conninfo);
|
421
|
+
break;
|
422
|
+
case T_CreateUserMappingStmt:
|
423
|
+
return const_record_walker((Node *) ((CreateUserMappingStmt *) node)->options, jstate);
|
424
|
+
case T_AlterUserMappingStmt:
|
425
|
+
return const_record_walker((Node *) ((AlterUserMappingStmt *) node)->options, jstate);
|
390
426
|
case T_TypeName:
|
391
427
|
/* Don't normalize constants in typmods or arrayBounds */
|
392
428
|
return false;
|
@@ -259,6 +259,17 @@ _outNode(StringInfo out, const void *obj)
|
|
259
259
|
}
|
260
260
|
}
|
261
261
|
|
262
|
+
char *
|
263
|
+
pg_query_node_to_json(const void *obj)
|
264
|
+
{
|
265
|
+
StringInfoData out;
|
266
|
+
|
267
|
+
initStringInfo(&out);
|
268
|
+
_outNode(&out, obj);
|
269
|
+
|
270
|
+
return out.data;
|
271
|
+
}
|
272
|
+
|
262
273
|
char *
|
263
274
|
pg_query_nodes_to_json(const void *obj)
|
264
275
|
{
|
@@ -18,7 +18,7 @@ typedef struct {
|
|
18
18
|
PgQueryError* error;
|
19
19
|
} PgQueryInternalPlpgsqlFuncAndError;
|
20
20
|
|
21
|
-
static PgQueryInternalPlpgsqlFuncAndError pg_query_raw_parse_plpgsql(
|
21
|
+
static PgQueryInternalPlpgsqlFuncAndError pg_query_raw_parse_plpgsql(Node* stmt);
|
22
22
|
|
23
23
|
static void add_dummy_return(PLpgSQL_function *function)
|
24
24
|
{
|
@@ -73,6 +73,36 @@ static void plpgsql_compile_error_callback(void *arg)
|
|
73
73
|
plpgsql_error_funcname, plpgsql_latest_lineno());
|
74
74
|
}
|
75
75
|
|
76
|
+
static PLpgSQL_function *compile_do_stmt(DoStmt* stmt)
|
77
|
+
{
|
78
|
+
char *proc_source = NULL;
|
79
|
+
const ListCell *lc;
|
80
|
+
char *language = "plpgsql";
|
81
|
+
|
82
|
+
assert(IsA(stmt, DoStmt));
|
83
|
+
|
84
|
+
foreach(lc, stmt->args)
|
85
|
+
{
|
86
|
+
DefElem* elem = (DefElem*) lfirst(lc);
|
87
|
+
|
88
|
+
if (strcmp(elem->defname, "as") == 0) {
|
89
|
+
|
90
|
+
assert(IsA(elem->arg, String));
|
91
|
+
proc_source = strVal(elem->arg);
|
92
|
+
} else if (strcmp(elem->defname, "language") == 0) {
|
93
|
+
language = strVal(elem->arg);
|
94
|
+
}
|
95
|
+
}
|
96
|
+
|
97
|
+
assert(proc_source != NULL);
|
98
|
+
|
99
|
+
if(strcmp(language, "plpgsql") != 0) {
|
100
|
+
return (PLpgSQL_function *) palloc0(sizeof(PLpgSQL_function));
|
101
|
+
}
|
102
|
+
return plpgsql_compile_inline(proc_source);
|
103
|
+
|
104
|
+
}
|
105
|
+
|
76
106
|
static PLpgSQL_function *compile_create_function_stmt(CreateFunctionStmt* stmt)
|
77
107
|
{
|
78
108
|
char *func_name;
|
@@ -87,6 +117,7 @@ static PLpgSQL_function *compile_create_function_stmt(CreateFunctionStmt* stmt)
|
|
87
117
|
const ListCell *lc, *lc2, *lc3;
|
88
118
|
bool is_trigger = false;
|
89
119
|
bool is_setof = false;
|
120
|
+
char *language = "plpgsql";
|
90
121
|
|
91
122
|
assert(IsA(stmt, CreateFunctionStmt));
|
92
123
|
|
@@ -105,11 +136,17 @@ static PLpgSQL_function *compile_create_function_stmt(CreateFunctionStmt* stmt)
|
|
105
136
|
{
|
106
137
|
proc_source = strVal(lfirst(lc2));
|
107
138
|
}
|
139
|
+
} else if (strcmp(elem->defname, "language") == 0) {
|
140
|
+
language = strVal(elem->arg);
|
108
141
|
}
|
109
142
|
}
|
110
143
|
|
111
144
|
assert(proc_source != NULL);
|
112
145
|
|
146
|
+
if(strcmp(language, "plpgsql") != 0) {
|
147
|
+
return (PLpgSQL_function *) palloc0(sizeof(PLpgSQL_function));
|
148
|
+
}
|
149
|
+
|
113
150
|
if (stmt->returnType != NULL) {
|
114
151
|
foreach(lc3, stmt->returnType->names)
|
115
152
|
{
|
@@ -273,7 +310,7 @@ static PLpgSQL_function *compile_create_function_stmt(CreateFunctionStmt* stmt)
|
|
273
310
|
return function;
|
274
311
|
}
|
275
312
|
|
276
|
-
PgQueryInternalPlpgsqlFuncAndError pg_query_raw_parse_plpgsql(
|
313
|
+
PgQueryInternalPlpgsqlFuncAndError pg_query_raw_parse_plpgsql(Node* stmt)
|
277
314
|
{
|
278
315
|
PgQueryInternalPlpgsqlFuncAndError result = {0};
|
279
316
|
MemoryContext cctx = CurrentMemoryContext;
|
@@ -306,7 +343,13 @@ PgQueryInternalPlpgsqlFuncAndError pg_query_raw_parse_plpgsql(CreateFunctionStmt
|
|
306
343
|
|
307
344
|
PG_TRY();
|
308
345
|
{
|
309
|
-
|
346
|
+
if (IsA(stmt, CreateFunctionStmt)) {
|
347
|
+
result.func = compile_create_function_stmt((CreateFunctionStmt *) stmt);
|
348
|
+
} else if (IsA(stmt, DoStmt)){
|
349
|
+
result.func = compile_do_stmt((DoStmt *) stmt);
|
350
|
+
} else {
|
351
|
+
elog(ERROR, "Unexpected node type for PL/pgSQL parsing: %d", nodeTag(stmt));
|
352
|
+
}
|
310
353
|
|
311
354
|
#ifndef DEBUG
|
312
355
|
// Save stderr for result
|
@@ -354,36 +397,36 @@ PgQueryInternalPlpgsqlFuncAndError pg_query_raw_parse_plpgsql(CreateFunctionStmt
|
|
354
397
|
return result;
|
355
398
|
}
|
356
399
|
|
357
|
-
typedef struct
|
400
|
+
typedef struct plStmts
|
358
401
|
{
|
359
|
-
|
402
|
+
Node **stmts;
|
360
403
|
int stmts_buf_size;
|
361
404
|
int stmts_count;
|
362
|
-
}
|
405
|
+
} plStmts;
|
363
406
|
|
364
|
-
static bool
|
407
|
+
static bool stmts_walker(Node *node, plStmts *state)
|
365
408
|
{
|
366
409
|
bool result;
|
367
410
|
MemoryContext ccxt = CurrentMemoryContext;
|
368
411
|
|
369
412
|
if (node == NULL) return false;
|
370
413
|
|
371
|
-
if (IsA(node, CreateFunctionStmt))
|
414
|
+
if (IsA(node, CreateFunctionStmt) || IsA(node, DoStmt))
|
372
415
|
{
|
373
416
|
if (state->stmts_count >= state->stmts_buf_size)
|
374
417
|
{
|
375
418
|
state->stmts_buf_size *= 2;
|
376
|
-
state->stmts = (
|
419
|
+
state->stmts = (Node**) repalloc(state->stmts, state->stmts_buf_size * sizeof(Node*));
|
377
420
|
}
|
378
|
-
state->stmts[state->stmts_count] = (
|
421
|
+
state->stmts[state->stmts_count] = (Node *) node;
|
379
422
|
state->stmts_count++;
|
380
423
|
} else if (IsA(node, RawStmt)) {
|
381
|
-
return
|
424
|
+
return stmts_walker((Node *) ((RawStmt *) node)->stmt, state);
|
382
425
|
}
|
383
426
|
|
384
427
|
PG_TRY();
|
385
428
|
{
|
386
|
-
result = raw_expression_tree_walker(node,
|
429
|
+
result = raw_expression_tree_walker(node, stmts_walker, (void*) state);
|
387
430
|
}
|
388
431
|
PG_CATCH();
|
389
432
|
{
|
@@ -401,7 +444,7 @@ PgQueryPlpgsqlParseResult pg_query_parse_plpgsql(const char* input)
|
|
401
444
|
MemoryContext ctx = NULL;
|
402
445
|
PgQueryPlpgsqlParseResult result = {0};
|
403
446
|
PgQueryInternalParsetreeAndError parse_result;
|
404
|
-
|
447
|
+
plStmts statements;
|
405
448
|
size_t i;
|
406
449
|
|
407
450
|
ctx = pg_query_enter_memory_context();
|
@@ -414,10 +457,10 @@ PgQueryPlpgsqlParseResult pg_query_parse_plpgsql(const char* input)
|
|
414
457
|
}
|
415
458
|
|
416
459
|
statements.stmts_buf_size = 100;
|
417
|
-
statements.stmts = (
|
460
|
+
statements.stmts = (Node**) palloc(statements.stmts_buf_size * sizeof(Node*));
|
418
461
|
statements.stmts_count = 0;
|
419
462
|
|
420
|
-
|
463
|
+
stmts_walker((Node*) parse_result.tree, &statements);
|
421
464
|
|
422
465
|
if (statements.stmts_count == 0) {
|
423
466
|
result.plpgsql_funcs = strdup("[]");
|
@@ -404,6 +404,14 @@ const PQcommMethods *PqCommMethods = NULL;
|
|
404
404
|
*/
|
405
405
|
|
406
406
|
|
407
|
+
/* --------------------------------
|
408
|
+
* pq_buffer_has_data - is any buffered data available to read?
|
409
|
+
*
|
410
|
+
* This will *not* attempt to read more data.
|
411
|
+
* --------------------------------
|
412
|
+
*/
|
413
|
+
|
414
|
+
|
407
415
|
|
408
416
|
/* --------------------------------
|
409
417
|
* pq_startmsgread - begin reading a message from the client.
|
@@ -345,8 +345,11 @@
|
|
345
345
|
#define COPY_POINTER_FIELD(fldname, sz) \
|
346
346
|
do { \
|
347
347
|
Size _size = (sz); \
|
348
|
-
|
349
|
-
|
348
|
+
if (_size > 0) \
|
349
|
+
{ \
|
350
|
+
newnode->fldname = palloc(_size); \
|
351
|
+
memcpy(newnode->fldname, from->fldname, _size); \
|
352
|
+
} \
|
350
353
|
} while (0)
|
351
354
|
|
352
355
|
/* Copy a parse location field (for Copy, this is same as scalar case) */
|
@@ -584,12 +587,9 @@ _copyRecursiveUnion(const RecursiveUnion *from)
|
|
584
587
|
*/
|
585
588
|
COPY_SCALAR_FIELD(wtParam);
|
586
589
|
COPY_SCALAR_FIELD(numCols);
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
COPY_POINTER_FIELD(dupOperators, from->numCols * sizeof(Oid));
|
591
|
-
COPY_POINTER_FIELD(dupCollations, from->numCols * sizeof(Oid));
|
592
|
-
}
|
590
|
+
COPY_POINTER_FIELD(dupColIdx, from->numCols * sizeof(AttrNumber));
|
591
|
+
COPY_POINTER_FIELD(dupOperators, from->numCols * sizeof(Oid));
|
592
|
+
COPY_POINTER_FIELD(dupCollations, from->numCols * sizeof(Oid));
|
593
593
|
COPY_SCALAR_FIELD(numGroups);
|
594
594
|
|
595
595
|
return newnode;
|
@@ -803,6 +803,7 @@ _copyIndexOnlyScan(const IndexOnlyScan *from)
|
|
803
803
|
*/
|
804
804
|
COPY_SCALAR_FIELD(indexid);
|
805
805
|
COPY_NODE_FIELD(indexqual);
|
806
|
+
COPY_NODE_FIELD(recheckqual);
|
806
807
|
COPY_NODE_FIELD(indexorderby);
|
807
808
|
COPY_NODE_FIELD(indextlist);
|
808
809
|
COPY_SCALAR_FIELD(indexorderdir);
|
@@ -1162,13 +1163,10 @@ _copyMergeJoin(const MergeJoin *from)
|
|
1162
1163
|
COPY_SCALAR_FIELD(skip_mark_restore);
|
1163
1164
|
COPY_NODE_FIELD(mergeclauses);
|
1164
1165
|
numCols = list_length(from->mergeclauses);
|
1165
|
-
|
1166
|
-
|
1167
|
-
|
1168
|
-
|
1169
|
-
COPY_POINTER_FIELD(mergeStrategies, numCols * sizeof(int));
|
1170
|
-
COPY_POINTER_FIELD(mergeNullsFirst, numCols * sizeof(bool));
|
1171
|
-
}
|
1166
|
+
COPY_POINTER_FIELD(mergeFamilies, numCols * sizeof(Oid));
|
1167
|
+
COPY_POINTER_FIELD(mergeCollations, numCols * sizeof(Oid));
|
1168
|
+
COPY_POINTER_FIELD(mergeStrategies, numCols * sizeof(int));
|
1169
|
+
COPY_POINTER_FIELD(mergeNullsFirst, numCols * sizeof(bool));
|
1172
1170
|
|
1173
1171
|
return newnode;
|
1174
1172
|
}
|
@@ -1303,12 +1301,9 @@ _copyAgg(const Agg *from)
|
|
1303
1301
|
COPY_SCALAR_FIELD(aggstrategy);
|
1304
1302
|
COPY_SCALAR_FIELD(aggsplit);
|
1305
1303
|
COPY_SCALAR_FIELD(numCols);
|
1306
|
-
|
1307
|
-
|
1308
|
-
|
1309
|
-
COPY_POINTER_FIELD(grpOperators, from->numCols * sizeof(Oid));
|
1310
|
-
COPY_POINTER_FIELD(grpCollations, from->numCols * sizeof(Oid));
|
1311
|
-
}
|
1304
|
+
COPY_POINTER_FIELD(grpColIdx, from->numCols * sizeof(AttrNumber));
|
1305
|
+
COPY_POINTER_FIELD(grpOperators, from->numCols * sizeof(Oid));
|
1306
|
+
COPY_POINTER_FIELD(grpCollations, from->numCols * sizeof(Oid));
|
1312
1307
|
COPY_SCALAR_FIELD(numGroups);
|
1313
1308
|
COPY_SCALAR_FIELD(transitionSpace);
|
1314
1309
|
COPY_BITMAPSET_FIELD(aggParams);
|
@@ -1330,19 +1325,13 @@ _copyWindowAgg(const WindowAgg *from)
|
|
1330
1325
|
|
1331
1326
|
COPY_SCALAR_FIELD(winref);
|
1332
1327
|
COPY_SCALAR_FIELD(partNumCols);
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1336
|
-
COPY_POINTER_FIELD(partOperators, from->partNumCols * sizeof(Oid));
|
1337
|
-
COPY_POINTER_FIELD(partCollations, from->partNumCols * sizeof(Oid));
|
1338
|
-
}
|
1328
|
+
COPY_POINTER_FIELD(partColIdx, from->partNumCols * sizeof(AttrNumber));
|
1329
|
+
COPY_POINTER_FIELD(partOperators, from->partNumCols * sizeof(Oid));
|
1330
|
+
COPY_POINTER_FIELD(partCollations, from->partNumCols * sizeof(Oid));
|
1339
1331
|
COPY_SCALAR_FIELD(ordNumCols);
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1343
|
-
COPY_POINTER_FIELD(ordOperators, from->ordNumCols * sizeof(Oid));
|
1344
|
-
COPY_POINTER_FIELD(ordCollations, from->ordNumCols * sizeof(Oid));
|
1345
|
-
}
|
1332
|
+
COPY_POINTER_FIELD(ordColIdx, from->ordNumCols * sizeof(AttrNumber));
|
1333
|
+
COPY_POINTER_FIELD(ordOperators, from->ordNumCols * sizeof(Oid));
|
1334
|
+
COPY_POINTER_FIELD(ordCollations, from->ordNumCols * sizeof(Oid));
|
1346
1335
|
COPY_SCALAR_FIELD(frameOptions);
|
1347
1336
|
COPY_NODE_FIELD(startOffset);
|
1348
1337
|
COPY_NODE_FIELD(endOffset);
|
@@ -3510,6 +3499,7 @@ _copyAlterTableCmd(const AlterTableCmd *from)
|
|
3510
3499
|
COPY_NODE_FIELD(def);
|
3511
3500
|
COPY_SCALAR_FIELD(behavior);
|
3512
3501
|
COPY_SCALAR_FIELD(missing_ok);
|
3502
|
+
COPY_SCALAR_FIELD(recurse);
|
3513
3503
|
|
3514
3504
|
return newnode;
|
3515
3505
|
}
|
@@ -642,6 +642,18 @@ list_delete_cell(List *list, ListCell *cell)
|
|
642
642
|
*/
|
643
643
|
|
644
644
|
|
645
|
+
/*
|
646
|
+
* Delete the first N cells of the list.
|
647
|
+
*
|
648
|
+
* The List is pfree'd if the request causes all cells to be deleted.
|
649
|
+
*/
|
650
|
+
#ifndef DEBUG_LIST_MEMORY_USAGE
|
651
|
+
#else
|
652
|
+
#ifdef CLOBBER_FREED_MEMORY
|
653
|
+
#else
|
654
|
+
#endif
|
655
|
+
#endif
|
656
|
+
|
645
657
|
/*
|
646
658
|
* Generate the union of two lists. This is calculated by copying
|
647
659
|
* list1 via list_copy(), then adding to it all the members of list2
|
@@ -457,7 +457,7 @@
|
|
457
457
|
REASSIGN = 579,
|
458
458
|
RECHECK = 580,
|
459
459
|
RECURSIVE = 581,
|
460
|
-
|
460
|
+
REF_P = 582,
|
461
461
|
REFERENCES = 583,
|
462
462
|
REFERENCING = 584,
|
463
463
|
REFRESH = 585,
|
@@ -934,7 +934,7 @@
|
|
934
934
|
#define REASSIGN 579
|
935
935
|
#define RECHECK 580
|
936
936
|
#define RECURSIVE 581
|
937
|
-
#define
|
937
|
+
#define REF_P 582
|
938
938
|
#define REFERENCES 583
|
939
939
|
#define REFERENCING 584
|
940
940
|
#define REFRESH 585
|
@@ -3354,7 +3354,7 @@ static const char *const yytname[] =
|
|
3354
3354
|
"PRESERVE", "PREPARE", "PREPARED", "PRIMARY", "PRIOR", "PRIVILEGES",
|
3355
3355
|
"PROCEDURAL", "PROCEDURE", "PROCEDURES", "PROGRAM", "PUBLICATION",
|
3356
3356
|
"QUOTE", "RANGE", "READ", "REAL", "REASSIGN", "RECHECK", "RECURSIVE",
|
3357
|
-
"
|
3357
|
+
"REF_P", "REFERENCES", "REFERENCING", "REFRESH", "REINDEX", "RELATIVE_P",
|
3358
3358
|
"RELEASE", "RENAME", "REPEATABLE", "REPLACE", "REPLICA", "RESET",
|
3359
3359
|
"RESTART", "RESTRICT", "RETURNING", "RETURNS", "REVOKE", "RIGHT", "ROLE",
|
3360
3360
|
"ROLLBACK", "ROLLUP", "ROUTINE", "ROUTINES", "ROW", "ROWS", "RULE",
|
@@ -46994,6 +46994,21 @@ insertSelectOptions(SelectStmt *stmt,
|
|
46994
46994
|
ereport(ERROR,
|
46995
46995
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
46996
46996
|
errmsg("WITH TIES cannot be specified without ORDER BY clause")));
|
46997
|
+
if (limitClause->limitOption == LIMIT_OPTION_WITH_TIES && stmt->lockingClause)
|
46998
|
+
{
|
46999
|
+
ListCell *lc;
|
47000
|
+
|
47001
|
+
foreach(lc, stmt->lockingClause)
|
47002
|
+
{
|
47003
|
+
LockingClause *lock = lfirst_node(LockingClause, lc);
|
47004
|
+
|
47005
|
+
if (lock->waitPolicy == LockWaitSkip)
|
47006
|
+
ereport(ERROR,
|
47007
|
+
(errcode(ERRCODE_SYNTAX_ERROR),
|
47008
|
+
errmsg("%s and %s options cannot be used together",
|
47009
|
+
"SKIP LOCKED", "WITH TIES")));
|
47010
|
+
}
|
47011
|
+
}
|
46997
47012
|
stmt->limitOption = limitClause->limitOption;
|
46998
47013
|
}
|
46999
47014
|
if (withClause)
|