Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit a6bc330

Browse files
committed
Add read support for some missing raw parse nodes
The node types A_Const, Constraint, and A_Expr had custom output functions, but no read functions were implemented so far. The A_Expr output format had to be tweaked a bit to make it easier to parse. Be a bit more cautious about applying strncmp to unterminated strings. Also error out if an unrecognized enum value is found in each case, instead of just printing a placeholder value. That was maybe ok for debugging but won't work if we want to have robust round-tripping. Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://www.postgresql.org/message-id/flat/4159834.1657405226@sss.pgh.pa.us
1 parent 2cb1a5a commit a6bc330

File tree

3 files changed

+253
-11
lines changed

3 files changed

+253
-11
lines changed

src/backend/nodes/outfuncs.c

+4-5
Original file line numberDiff line numberDiff line change
@@ -548,12 +548,12 @@ _outA_Expr(StringInfo str, const A_Expr *node)
548548
WRITE_NODE_FIELD(name);
549549
break;
550550
case AEXPR_OP_ANY:
551-
WRITE_NODE_FIELD(name);
552551
appendStringInfoString(str, " ANY");
552+
WRITE_NODE_FIELD(name);
553553
break;
554554
case AEXPR_OP_ALL:
555-
WRITE_NODE_FIELD(name);
556555
appendStringInfoString(str, " ALL");
556+
WRITE_NODE_FIELD(name);
557557
break;
558558
case AEXPR_DISTINCT:
559559
appendStringInfoString(str, " DISTINCT");
@@ -600,7 +600,7 @@ _outA_Expr(StringInfo str, const A_Expr *node)
600600
WRITE_NODE_FIELD(name);
601601
break;
602602
default:
603-
appendStringInfoString(str, " ??");
603+
elog(ERROR, "unrecognized A_Expr_Kind: %d", (int) node->kind);
604604
break;
605605
}
606606

@@ -782,8 +782,7 @@ _outConstraint(StringInfo str, const Constraint *node)
782782
break;
783783

784784
default:
785-
appendStringInfo(str, "<unrecognized_constraint %d>",
786-
(int) node->contype);
785+
elog(ERROR, "unrecognized ConstrType: %d", (int) node->contype);
787786
break;
788787
}
789788
}

src/backend/nodes/readfuncs.c

+246-3
Original file line numberDiff line numberDiff line change
@@ -270,11 +270,11 @@ _readBoolExpr(void)
270270
/* do-it-yourself enum representation */
271271
token = pg_strtok(&length); /* skip :boolop */
272272
token = pg_strtok(&length); /* get field value */
273-
if (strncmp(token, "and", 3) == 0)
273+
if (length == 3 && strncmp(token, "and", 3) == 0)
274274
local_node->boolop = AND_EXPR;
275-
else if (strncmp(token, "or", 2) == 0)
275+
else if (length == 2 && strncmp(token, "or", 2) == 0)
276276
local_node->boolop = OR_EXPR;
277-
else if (strncmp(token, "not", 3) == 0)
277+
else if (length == 3 && strncmp(token, "not", 3) == 0)
278278
local_node->boolop = NOT_EXPR;
279279
else
280280
elog(ERROR, "unrecognized boolop \"%.*s\"", length, token);
@@ -285,6 +285,162 @@ _readBoolExpr(void)
285285
READ_DONE();
286286
}
287287

288+
static A_Const *
289+
_readA_Const(void)
290+
{
291+
READ_LOCALS(A_Const);
292+
293+
token = pg_strtok(&length);
294+
if (length == 4 && strncmp(token, "NULL", 4) == 0)
295+
local_node->isnull = true;
296+
else
297+
{
298+
union ValUnion *tmp = nodeRead(NULL, 0);
299+
300+
memcpy(&local_node->val, tmp, sizeof(*tmp));
301+
}
302+
303+
READ_LOCATION_FIELD(location);
304+
305+
READ_DONE();
306+
}
307+
308+
/*
309+
* _readConstraint
310+
*/
311+
static Constraint *
312+
_readConstraint(void)
313+
{
314+
READ_LOCALS(Constraint);
315+
316+
READ_STRING_FIELD(conname);
317+
READ_BOOL_FIELD(deferrable);
318+
READ_BOOL_FIELD(initdeferred);
319+
READ_LOCATION_FIELD(location);
320+
321+
token = pg_strtok(&length); /* skip :contype */
322+
token = pg_strtok(&length); /* get field value */
323+
if (length == 4 && strncmp(token, "NULL", 4) == 0)
324+
local_node->contype = CONSTR_NULL;
325+
else if (length == 8 && strncmp(token, "NOT_NULL", 8) == 0)
326+
local_node->contype = CONSTR_NOTNULL;
327+
else if (length == 7 && strncmp(token, "DEFAULT", 7) == 0)
328+
local_node->contype = CONSTR_DEFAULT;
329+
else if (length == 8 && strncmp(token, "IDENTITY", 8) == 0)
330+
local_node->contype = CONSTR_IDENTITY;
331+
else if (length == 9 && strncmp(token, "GENERATED", 9) == 0)
332+
local_node->contype = CONSTR_GENERATED;
333+
else if (length == 5 && strncmp(token, "CHECK", 5) == 0)
334+
local_node->contype = CONSTR_CHECK;
335+
else if (length == 11 && strncmp(token, "PRIMARY_KEY", 11) == 0)
336+
local_node->contype = CONSTR_PRIMARY;
337+
else if (length == 6 && strncmp(token, "UNIQUE", 6) == 0)
338+
local_node->contype = CONSTR_UNIQUE;
339+
else if (length == 9 && strncmp(token, "EXCLUSION", 9) == 0)
340+
local_node->contype = CONSTR_EXCLUSION;
341+
else if (length == 11 && strncmp(token, "FOREIGN_KEY", 11) == 0)
342+
local_node->contype = CONSTR_FOREIGN;
343+
else if (length == 15 && strncmp(token, "ATTR_DEFERRABLE", 15) == 0)
344+
local_node->contype = CONSTR_ATTR_DEFERRABLE;
345+
else if (length == 19 && strncmp(token, "ATTR_NOT_DEFERRABLE", 19) == 0)
346+
local_node->contype = CONSTR_ATTR_NOT_DEFERRABLE;
347+
else if (length == 13 && strncmp(token, "ATTR_DEFERRED", 13) == 0)
348+
local_node->contype = CONSTR_ATTR_DEFERRED;
349+
else if (length == 14 && strncmp(token, "ATTR_IMMEDIATE", 14) == 0)
350+
local_node->contype = CONSTR_ATTR_IMMEDIATE;
351+
352+
switch (local_node->contype)
353+
{
354+
case CONSTR_NULL:
355+
case CONSTR_NOTNULL:
356+
/* no extra fields */
357+
break;
358+
359+
case CONSTR_DEFAULT:
360+
READ_NODE_FIELD(raw_expr);
361+
READ_STRING_FIELD(cooked_expr);
362+
break;
363+
364+
case CONSTR_IDENTITY:
365+
READ_NODE_FIELD(options);
366+
READ_CHAR_FIELD(generated_when);
367+
break;
368+
369+
case CONSTR_GENERATED:
370+
READ_NODE_FIELD(raw_expr);
371+
READ_STRING_FIELD(cooked_expr);
372+
READ_CHAR_FIELD(generated_when);
373+
break;
374+
375+
case CONSTR_CHECK:
376+
READ_BOOL_FIELD(is_no_inherit);
377+
READ_NODE_FIELD(raw_expr);
378+
READ_STRING_FIELD(cooked_expr);
379+
READ_BOOL_FIELD(skip_validation);
380+
READ_BOOL_FIELD(initially_valid);
381+
break;
382+
383+
case CONSTR_PRIMARY:
384+
READ_NODE_FIELD(keys);
385+
READ_NODE_FIELD(including);
386+
READ_NODE_FIELD(options);
387+
READ_STRING_FIELD(indexname);
388+
READ_STRING_FIELD(indexspace);
389+
READ_BOOL_FIELD(reset_default_tblspc);
390+
/* access_method and where_clause not currently used */
391+
break;
392+
393+
case CONSTR_UNIQUE:
394+
READ_BOOL_FIELD(nulls_not_distinct);
395+
READ_NODE_FIELD(keys);
396+
READ_NODE_FIELD(including);
397+
READ_NODE_FIELD(options);
398+
READ_STRING_FIELD(indexname);
399+
READ_STRING_FIELD(indexspace);
400+
READ_BOOL_FIELD(reset_default_tblspc);
401+
/* access_method and where_clause not currently used */
402+
break;
403+
404+
case CONSTR_EXCLUSION:
405+
READ_NODE_FIELD(exclusions);
406+
READ_NODE_FIELD(including);
407+
READ_NODE_FIELD(options);
408+
READ_STRING_FIELD(indexname);
409+
READ_STRING_FIELD(indexspace);
410+
READ_BOOL_FIELD(reset_default_tblspc);
411+
READ_STRING_FIELD(access_method);
412+
READ_NODE_FIELD(where_clause);
413+
break;
414+
415+
case CONSTR_FOREIGN:
416+
READ_NODE_FIELD(pktable);
417+
READ_NODE_FIELD(fk_attrs);
418+
READ_NODE_FIELD(pk_attrs);
419+
READ_CHAR_FIELD(fk_matchtype);
420+
READ_CHAR_FIELD(fk_upd_action);
421+
READ_CHAR_FIELD(fk_del_action);
422+
READ_NODE_FIELD(fk_del_set_cols);
423+
READ_NODE_FIELD(old_conpfeqop);
424+
READ_OID_FIELD(old_pktable_oid);
425+
READ_BOOL_FIELD(skip_validation);
426+
READ_BOOL_FIELD(initially_valid);
427+
break;
428+
429+
case CONSTR_ATTR_DEFERRABLE:
430+
case CONSTR_ATTR_NOT_DEFERRABLE:
431+
case CONSTR_ATTR_DEFERRED:
432+
case CONSTR_ATTR_IMMEDIATE:
433+
/* no extra fields */
434+
break;
435+
436+
default:
437+
elog(ERROR, "unrecognized ConstrType: %d", (int) local_node->contype);
438+
break;
439+
}
440+
441+
READ_DONE();
442+
}
443+
288444
static RangeTblEntry *
289445
_readRangeTblEntry(void)
290446
{
@@ -376,6 +532,93 @@ _readRangeTblEntry(void)
376532
READ_DONE();
377533
}
378534

535+
static A_Expr *
536+
_readA_Expr(void)
537+
{
538+
READ_LOCALS(A_Expr);
539+
540+
token = pg_strtok(&length);
541+
542+
if (length == 3 && strncmp(token, "ANY", 3) == 0)
543+
{
544+
local_node->kind = AEXPR_OP_ANY;
545+
READ_NODE_FIELD(name);
546+
}
547+
else if (length == 3 && strncmp(token, "ALL", 3) == 0)
548+
{
549+
local_node->kind = AEXPR_OP_ALL;
550+
READ_NODE_FIELD(name);
551+
}
552+
else if (length == 8 && strncmp(token, "DISTINCT", 8) == 0)
553+
{
554+
local_node->kind = AEXPR_DISTINCT;
555+
READ_NODE_FIELD(name);
556+
}
557+
else if (length == 12 && strncmp(token, "NOT_DISTINCT", 12) == 0)
558+
{
559+
local_node->kind = AEXPR_NOT_DISTINCT;
560+
READ_NODE_FIELD(name);
561+
}
562+
else if (length == 6 && strncmp(token, "NULLIF", 6) == 0)
563+
{
564+
local_node->kind = AEXPR_NULLIF;
565+
READ_NODE_FIELD(name);
566+
}
567+
else if (length == 2 && strncmp(token, "IN", 2) == 0)
568+
{
569+
local_node->kind = AEXPR_IN;
570+
READ_NODE_FIELD(name);
571+
}
572+
else if (length == 4 && strncmp(token, "LIKE", 4) == 0)
573+
{
574+
local_node->kind = AEXPR_LIKE;
575+
READ_NODE_FIELD(name);
576+
}
577+
else if (length == 5 && strncmp(token, "ILIKE", 5) == 0)
578+
{
579+
local_node->kind = AEXPR_ILIKE;
580+
READ_NODE_FIELD(name);
581+
}
582+
else if (length == 7 && strncmp(token, "SIMILAR", 7) == 0)
583+
{
584+
local_node->kind = AEXPR_SIMILAR;
585+
READ_NODE_FIELD(name);
586+
}
587+
else if (length == 7 && strncmp(token, "BETWEEN", 7) == 0)
588+
{
589+
local_node->kind = AEXPR_BETWEEN;
590+
READ_NODE_FIELD(name);
591+
}
592+
else if (length == 11 && strncmp(token, "NOT_BETWEEN", 11) == 0)
593+
{
594+
local_node->kind = AEXPR_NOT_BETWEEN;
595+
READ_NODE_FIELD(name);
596+
}
597+
else if (length == 11 && strncmp(token, "BETWEEN_SYM", 11) == 0)
598+
{
599+
local_node->kind = AEXPR_BETWEEN_SYM;
600+
READ_NODE_FIELD(name);
601+
}
602+
else if (length == 15 && strncmp(token, "NOT_BETWEEN_SYM", 15) == 0)
603+
{
604+
local_node->kind = AEXPR_NOT_BETWEEN_SYM;
605+
READ_NODE_FIELD(name);
606+
}
607+
else if (length == 5 && strncmp(token, ":name", 5) == 0)
608+
{
609+
local_node->kind = AEXPR_OP;
610+
local_node->name = nodeRead(NULL, 0);
611+
}
612+
else
613+
elog(ERROR, "unrecognized A_Expr kind: \"%.*s\"", length, token);
614+
615+
READ_NODE_FIELD(lexpr);
616+
READ_NODE_FIELD(rexpr);
617+
READ_LOCATION_FIELD(location);
618+
619+
READ_DONE();
620+
}
621+
379622
static ExtensibleNode *
380623
_readExtensibleNode(void)
381624
{

src/include/nodes/parsenodes.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ typedef enum A_Expr_Kind
291291

292292
typedef struct A_Expr
293293
{
294-
pg_node_attr(custom_read_write, no_read)
294+
pg_node_attr(custom_read_write)
295295

296296
NodeTag type;
297297
A_Expr_Kind kind; /* see above */
@@ -319,7 +319,7 @@ union ValUnion
319319

320320
typedef struct A_Const
321321
{
322-
pg_node_attr(custom_copy_equal, custom_read_write, no_read)
322+
pg_node_attr(custom_copy_equal, custom_read_write)
323323

324324
NodeTag type;
325325
union ValUnion val;
@@ -2332,7 +2332,7 @@ typedef enum ConstrType /* types of constraints */
23322332

23332333
typedef struct Constraint
23342334
{
2335-
pg_node_attr(custom_read_write, no_read)
2335+
pg_node_attr(custom_read_write)
23362336

23372337
NodeTag type;
23382338
ConstrType contype; /* see above */

0 commit comments

Comments
 (0)