diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 94ded3c135..5eb49738c8 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -2162,7 +2162,9 @@ typedef struct Constraint /* Fields used for FOREIGN KEY constraints: */ RangeVar *pktable; /* Primary key table */ List *fk_attrs; /* Attributes of foreign key */ + Node *fk_period; /* String node naming Period or range column */ List *pk_attrs; /* Corresponding attrs in PK table */ + Node *pk_period; /* String node naming Period or range column */ char fk_matchtype; /* FULL, PARTIAL, SIMPLE */ char fk_upd_action; /* ON UPDATE action */ char fk_del_action; /* ON DELETE action */ @@ -2170,6 +2172,9 @@ typedef struct Constraint Oid old_pktable_oid; /* pg_constraint.confrelid of my former * self */ + /* Fields used for temporal PRIMARY KEY and FOREIGN KEY constraints: */ + Node *without_overlaps; /* String node naming PERIOD or range column */ + /* Fields used for constraints that allow a NOT VALID specification */ bool skip_validation; /* skip validation of existing rows? */ bool initially_valid; /* mark the new constraint as valid? */ diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h index 00ace8425e..92628f390a 100644 --- a/src/include/parser/kwlist.h +++ b/src/include/parser/kwlist.h @@ -299,6 +299,7 @@ PG_KEYWORD("partial", PARTIAL, UNRESERVED_KEYWORD) PG_KEYWORD("partition", PARTITION, UNRESERVED_KEYWORD) PG_KEYWORD("passing", PASSING, UNRESERVED_KEYWORD) PG_KEYWORD("password", PASSWORD, UNRESERVED_KEYWORD) +PG_KEYWORD("period", PERIOD, RESERVED_KEYWORD) PG_KEYWORD("placing", PLACING, RESERVED_KEYWORD) PG_KEYWORD("plans", PLANS, UNRESERVED_KEYWORD) PG_KEYWORD("policy", POLICY, UNRESERVED_KEYWORD) diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index c97bb367f8..f5ecbeb445 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -473,10 +473,12 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type TableElement TypedTableElement ConstraintElem TableFuncElement %type columnDef columnOptions %type def_elem reloption_elem old_aggr_elem operator_def_elem -%type def_arg columnElem where_clause where_or_current_clause +%type def_arg columnElem withoutOverlapsClause optionalPeriodName + where_clause where_or_current_clause a_expr b_expr c_expr AexprConst indirection_el opt_slice_bound columnref in_expr having_clause func_table xmltable array_expr ExclusionWhereClause operator_def_arg +%type opt_column_and_period_list %type rowsfrom_item rowsfrom_list opt_col_def_list %type opt_ordinality %type ExclusionConstraintList ExclusionConstraintElem @@ -667,7 +669,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); ORDER ORDINALITY OTHERS OUT_P OUTER_P OVER OVERLAPS OVERLAY OVERRIDING OWNED OWNER - PARALLEL PARSER PARTIAL PARTITION PASSING PASSWORD PLACING PLANS POLICY + PARALLEL PARSER PARTIAL PARTITION PASSING PASSWORD PERIOD PLACING PLANS POLICY POSITION PRECEDING PRECISION PRESERVE PREPARE PREPARED PRIMARY PRIOR PRIVILEGES PROCEDURAL PROCEDURE PROCEDURES PROGRAM PUBLICATION @@ -3462,6 +3464,7 @@ ColConstraintElem: n->contype = CONSTR_PRIMARY; n->location = @1; n->keys = NULL; + n->without_overlaps = NULL; n->options = $3; n->indexname = NULL; n->indexspace = $4; @@ -3678,18 +3681,19 @@ ConstraintElem: NULL, yyscanner); $$ = (Node *)n; } - | PRIMARY KEY '(' columnList ')' opt_c_include opt_definition OptConsTableSpace + | PRIMARY KEY '(' columnList withoutOverlapsClause ')' opt_c_include opt_definition OptConsTableSpace ConstraintAttributeSpec { Constraint *n = makeNode(Constraint); n->contype = CONSTR_PRIMARY; n->location = @1; n->keys = $4; - n->including = $6; - n->options = $7; + n->without_overlaps = $5; + n->including = $7; + n->options = $8; n->indexname = NULL; - n->indexspace = $8; - processCASbits($9, @9, "PRIMARY KEY", + n->indexspace = $9; + processCASbits($10, @10, "PRIMARY KEY", &n->deferrable, &n->initdeferred, NULL, NULL, yyscanner); $$ = (Node *)n; @@ -3700,6 +3704,7 @@ ConstraintElem: n->contype = CONSTR_PRIMARY; n->location = @1; n->keys = NIL; + n->without_overlaps = NULL; n->including = NIL; n->options = NIL; n->indexname = $3; @@ -3728,19 +3733,21 @@ ConstraintElem: NULL, yyscanner); $$ = (Node *)n; } - | FOREIGN KEY '(' columnList ')' REFERENCES qualified_name - opt_column_list key_match key_actions ConstraintAttributeSpec + | FOREIGN KEY '(' columnList optionalPeriodName ')' REFERENCES qualified_name + opt_column_and_period_list key_match key_actions ConstraintAttributeSpec { Constraint *n = makeNode(Constraint); n->contype = CONSTR_FOREIGN; n->location = @1; - n->pktable = $7; + n->pktable = $8; n->fk_attrs = $4; - n->pk_attrs = $8; - n->fk_matchtype = $9; - n->fk_upd_action = (char) ($10 >> 8); - n->fk_del_action = (char) ($10 & 0xFF); - processCASbits($11, @11, "FOREIGN KEY", + n->fk_period = $5; + n->pk_attrs = linitial($9); + n->pk_period = lsecond($9); + n->fk_matchtype = $10; + n->fk_upd_action = (char) ($11 >> 8); + n->fk_del_action = (char) ($11 & 0xFF); + processCASbits($12, @12, "FOREIGN KEY", &n->deferrable, &n->initdeferred, &n->skip_validation, NULL, yyscanner); @@ -3763,6 +3770,21 @@ columnList: | columnList ',' columnElem { $$ = lappend($1, $3); } ; +withoutOverlapsClause: + ',' columnElem WITHOUT OVERLAPS { $$ = $2; } + | /*EMPTY*/ { $$ = NULL; } + ; + +optionalPeriodName: + ',' PERIOD columnElem { $$ = $3; } + | /*EMPTY*/ { $$ = NULL; } + ; + +opt_column_and_period_list: + '(' columnList optionalPeriodName ')' { $$ = list_make2($2, $3); } + | /*EMPTY*/ { $$ = list_make2(NIL, NULL); } + ; + columnElem: ColId { $$ = (Node *) makeString($1); @@ -15473,6 +15495,7 @@ reserved_keyword: | ONLY | OR | ORDER + | PERIOD | PLACING | PRIMARY | REFERENCES