summaryrefslogtreecommitdiff
path: root/src/backend/parser
diff options
context:
space:
mode:
authorPeter Eisentraut2024-03-24 06:37:13 +0000
committerPeter Eisentraut2024-03-24 06:37:13 +0000
commit34768ee361656841a122f1c8d52a2ad753612feb (patch)
tree7a4fef14e45e477f18d545231d65942b27a01bb4 /src/backend/parser
parentb1fe8efdf17eb4877f7c4c31c85111ec740ad872 (diff)
Add temporal FOREIGN KEY contraints
Add PERIOD clause to foreign key constraint definitions. This is supported for range and multirange types. Temporal foreign keys check for range containment instead of equality. This feature matches the behavior of the SQL standard temporal foreign keys, but it works on PostgreSQL's native ranges instead of SQL's "periods", which don't exist in PostgreSQL (yet). Reference actions ON {UPDATE,DELETE} {CASCADE,SET NULL,SET DEFAULT} are not supported yet. Author: Paul A. Jungwirth <pj@illuminatedcomputing.com> Reviewed-by: Peter Eisentraut <peter@eisentraut.org> Reviewed-by: jian he <jian.universality@gmail.com> Discussion: https://www.postgresql.org/message-id/flat/CA+renyUApHgSZF9-nd-a0+OPGharLQLO=mDHcY4_qQ0+noCUVg@mail.gmail.com
Diffstat (limited to 'src/backend/parser')
-rw-r--r--src/backend/parser/gram.y45
1 files changed, 34 insertions, 11 deletions
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index c247eefb0cc..c1b0cff1c9e 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -523,12 +523,13 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
SetResetClause FunctionSetResetClause
%type <node> TableElement TypedTableElement ConstraintElem TableFuncElement
-%type <node> columnDef columnOptions
+%type <node> columnDef columnOptions optionalPeriodName
%type <defelt> def_elem reloption_elem old_aggr_elem operator_def_elem
%type <node> def_arg columnElem 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
OptWhereClause operator_def_arg
+%type <list> opt_column_and_period_list
%type <list> rowsfrom_item rowsfrom_list opt_col_def_list
%type <boolean> opt_ordinality opt_without_overlaps
%type <list> ExclusionConstraintList ExclusionConstraintElem
@@ -755,7 +756,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
OVER OVERLAPS OVERLAY OVERRIDING OWNED OWNER
PARALLEL PARAMETER PARSER PARTIAL PARTITION PASSING PASSWORD
- PLACING PLANS POLICY
+ PERIOD PLACING PLANS POLICY
POSITION PRECEDING PRECISION PRESERVE PREPARE PREPARED PRIMARY
PRIOR PRIVILEGES PROCEDURAL PROCEDURE PROCEDURES PROGRAM PUBLICATION
@@ -4237,21 +4238,31 @@ 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 = ($10)->updateAction->action;
- n->fk_del_action = ($10)->deleteAction->action;
- n->fk_del_set_cols = ($10)->deleteAction->cols;
- processCASbits($11, @11, "FOREIGN KEY",
+ if ($5)
+ {
+ n->fk_attrs = lappend(n->fk_attrs, $5);
+ n->fk_with_period = true;
+ }
+ n->pk_attrs = linitial($9);
+ if (lsecond($9))
+ {
+ n->pk_attrs = lappend(n->pk_attrs, lsecond($9));
+ n->pk_with_period = true;
+ }
+ n->fk_matchtype = $10;
+ n->fk_upd_action = ($11)->updateAction->action;
+ n->fk_del_action = ($11)->deleteAction->action;
+ n->fk_del_set_cols = ($11)->deleteAction->cols;
+ processCASbits($12, @12, "FOREIGN KEY",
&n->deferrable, &n->initdeferred,
&n->skip_validation, NULL,
yyscanner);
@@ -4279,6 +4290,16 @@ columnList:
| columnList ',' columnElem { $$ = lappend($1, $3); }
;
+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);
@@ -17491,6 +17512,7 @@ unreserved_keyword:
| PARTITION
| PASSING
| PASSWORD
+ | PERIOD
| PLANS
| POLICY
| PRECEDING
@@ -18108,6 +18130,7 @@ bare_label_keyword:
| PARTITION
| PASSING
| PASSWORD
+ | PERIOD
| PLACING
| PLANS
| POLICY