@ -143,6 +143,8 @@ typedef struct KeyActions
#define CAS_INITIALLY_DEFERRED 0x08
#define CAS_NOT_VALID 0x10
#define CAS_NO_INHERIT 0x20
#define CAS_NOT_ENFORCED 0x40
#define CAS_ENFORCED 0x80
#define parser_yyerror(msg) scanner_yyerror(msg, yyscanner)
@ -196,8 +198,8 @@ static void SplitColQualList(List *qualList,
List **constraintList, CollateClause **collClause,
core_yyscan_t yyscanner);
static void processCASbits(int cas_bits, int location, const char *constrType,
bool *deferrable, bool *initdeferred, bool *not_vali d,
bool *no_inherit, core_yyscan_t yyscanner);
bool *deferrable, bool *initdeferred, bool *is_enforce d,
bool *not_valid, bool *no _inherit, core_yyscan_t yyscanner);
static PartitionStrategy parsePartitionStrategy(char *strategy, int location,
core_yyscan_t yyscanner);
static void preprocess_pubobj_list(List *pubobjspec_list,
@ -711,9 +713,9 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
DETACH DICTIONARY DISABLE_P DISCARD DISTINCT DO DOCUMENT_P DOMAIN_P
DOUBLE_P DROP
EACH ELSE EMPTY_P ENABLE_P ENCODING ENCRYPTED END_P ENUM_P ERROR_P ESCAPE
EVENT EXCEPT EXCLUDE EXCLUDING EXCLUSIVE EXECUTE EXISTS EXPLAIN EXPRESSIO N
EXTENSION EXTERNAL EXTRACT
EACH ELSE EMPTY_P ENABLE_P ENCODING ENCRYPTED END_P ENFORCED EN UM_P ERROR_P
ESCAPE E VENT EXCEPT EXCLUDE EXCLUDING EXCLUSIVE EXECUTE EXISTS EXPLAIN
EXPRESSION EX TENSION EXTERNAL EXTRACT
FALSE_P FAMILY FETCH FILTER FINALIZE FIRST_P FLOAT_P FOLLOWING FOR
FORCE FOREIGN FORMAT FORWARD FREEZE FROM FULL FUNCTION FUNCTIONS
@ -2658,7 +2660,7 @@ alter_table_cmd:
processCASbits($4, @4, "ALTER CONSTRAINT statement",
&c->deferrable,
&c->initdeferred,
NULL, NULL, yyscanner);
NULL, NULL, NULL, yyscanner);
$$ = (Node *) n;
}
/* ALTER TABLE <name> VALIDATE CONSTRAINT ... */
@ -3915,6 +3917,7 @@ ColConstraintElem:
n->contype = CONSTR_NOTNULL;
n->location = @1;
n->is_no_inherit = $3;
n->is_enforced = true;
n->skip_validation = false;
n->initially_valid = true;
$$ = (Node *) n;
@ -3961,6 +3964,7 @@ ColConstraintElem:
n->is_no_inherit = $5;
n->raw_expr = $3;
n->cooked_expr = NULL;
n->is_enforced = true;
n->skip_validation = false;
n->initially_valid = true;
$$ = (Node *) n;
@ -4022,6 +4026,7 @@ ColConstraintElem:
n->fk_upd_action = ($5)->updateAction->action;
n->fk_del_action = ($5)->deleteAction->action;
n->fk_del_set_cols = ($5)->deleteAction->cols;
n->is_enforced = true;
n->skip_validation = false;
n->initially_valid = true;
$$ = (Node *) n;
@ -4087,6 +4092,22 @@ ConstraintAttr:
n->location = @1;
$$ = (Node *) n;
}
| ENFORCED
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_ATTR_ENFORCED;
n->location = @1;
$$ = (Node *) n;
}
| NOT ENFORCED
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_ATTR_NOT_ENFORCED;
n->location = @1;
$$ = (Node *) n;
}
;
@ -4148,7 +4169,7 @@ ConstraintElem:
n->raw_expr = $3;
n->cooked_expr = NULL;
processCASbits($5, @5, "CHECK",
NULL, NULL, &n->skip_validation,
NULL, NULL, &n->is_enforced, &n-> skip_validation,
&n->is_no_inherit, yyscanner);
n->initially_valid = !n->skip_validation;
$$ = (Node *) n;
@ -4162,7 +4183,7 @@ ConstraintElem:
n->keys = list_make1(makeString($3));
/* no NOT VALID support yet */
processCASbits($4, @4, "NOT NULL",
NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
&n->is_no_inherit, yyscanner);
n->initially_valid = true;
$$ = (Node *) n;
@ -4183,7 +4204,7 @@ ConstraintElem:
n->indexspace = $9;
processCASbits($10, @10, "UNIQUE",
&n->deferrable, &n->initdeferred, NULL,
NULL, yyscanner);
NULL, NULL, yyscanner);
$$ = (Node *) n;
}
| UNIQUE ExistingIndex ConstraintAttributeSpec
@ -4199,7 +4220,7 @@ ConstraintElem:
n->indexspace = NULL;
processCASbits($3, @3, "UNIQUE",
&n->deferrable, &n->initdeferred, NULL,
NULL, yyscanner);
NULL, NULL, yyscanner);
$$ = (Node *) n;
}
| PRIMARY KEY '(' columnList opt_without_overlaps ')' opt_c_include opt_definition OptConsTableSpace
@ -4217,7 +4238,7 @@ ConstraintElem:
n->indexspace = $9;
processCASbits($10, @10, "PRIMARY KEY",
&n->deferrable, &n->initdeferred, NULL,
NULL, yyscanner);
NULL, NULL, yyscanner);
$$ = (Node *) n;
}
| PRIMARY KEY ExistingIndex ConstraintAttributeSpec
@ -4233,7 +4254,7 @@ ConstraintElem:
n->indexspace = NULL;
processCASbits($4, @4, "PRIMARY KEY",
&n->deferrable, &n->initdeferred, NULL,
NULL, yyscanner);
NULL, NULL, yyscanner);
$$ = (Node *) n;
}
| EXCLUDE access_method_clause '(' ExclusionConstraintList ')'
@ -4253,7 +4274,7 @@ ConstraintElem:
n->where_clause = $9;
processCASbits($10, @10, "EXCLUDE",
&n->deferrable, &n->initdeferred, NULL,
NULL, yyscanner);
NULL, NULL, yyscanner);
$$ = (Node *) n;
}
| FOREIGN KEY '(' columnList optionalPeriodName ')' REFERENCES qualified_name
@ -4282,7 +4303,7 @@ ConstraintElem:
n->fk_del_set_cols = ($11)->deleteAction->cols;
processCASbits($12, @12, "FOREIGN KEY",
&n->deferrable, &n->initdeferred,
&n->skip_validation, NULL,
NULL, &n->skip_validation, NULL,
yyscanner);
n->initially_valid = !n->skip_validation;
$$ = (Node *) n;
@ -4322,8 +4343,9 @@ DomainConstraintElem:
n->raw_expr = $3;
n->cooked_expr = NULL;
processCASbits($5, @5, "CHECK",
NULL, NULL, &n->skip_validation,
NULL, NULL, NULL, &n->skip_validation,
&n->is_no_inherit, yyscanner);
n->is_enforced = true;
n->initially_valid = !n->skip_validation;
$$ = (Node *) n;
}
@ -4337,7 +4359,7 @@ DomainConstraintElem:
/* no NOT VALID, NO INHERIT support */
processCASbits($3, @3, "NOT NULL",
NULL, NULL, NULL,
NULL, yyscanner);
NULL, NULL, yyscanner);
n->initially_valid = true;
$$ = (Node *) n;
}
@ -6000,7 +6022,7 @@ CreateTrigStmt:
n->transitionRels = NIL;
processCASbits($11, @11, "TRIGGER",
&n->deferrable, &n->initdeferred, NULL,
NULL, yyscanner);
NULL, NULL, yyscanner);
n->constrrel = $10;
$$ = (Node *) n;
}
@ -6169,7 +6191,8 @@ ConstraintAttributeSpec:
parser_errposition(@2)));
/* generic message for other conflicts */
if ((newspec & (CAS_NOT_DEFERRABLE | CAS_DEFERRABLE)) == (CAS_NOT_DEFERRABLE | CAS_DEFERRABLE) ||
(newspec & (CAS_INITIALLY_IMMEDIATE | CAS_INITIALLY_DEFERRED)) == (CAS_INITIALLY_IMMEDIATE | CAS_INITIALLY_DEFERRED))
(newspec & (CAS_INITIALLY_IMMEDIATE | CAS_INITIALLY_DEFERRED)) == (CAS_INITIALLY_IMMEDIATE | CAS_INITIALLY_DEFERRED) ||
(newspec & (CAS_NOT_ENFORCED | CAS_ENFORCED)) == (CAS_NOT_ENFORCED | CAS_ENFORCED))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting constraint properties"),
@ -6185,6 +6208,8 @@ ConstraintAttributeElem:
| INITIALLY DEFERRED { $$ = CAS_INITIALLY_DEFERRED; }
| NOT VALID { $$ = CAS_NOT_VALID; }
| NO INHERIT { $$ = CAS_NO_INHERIT; }
| NOT ENFORCED { $$ = CAS_NOT_ENFORCED; }
| ENFORCED { $$ = CAS_ENFORCED; }
;
@ -17688,6 +17713,7 @@ unreserved_keyword:
| ENABLE_P
| ENCODING
| ENCRYPTED
| ENFORCED
| ENUM_P
| ERROR_P
| ESCAPE
@ -18265,6 +18291,7 @@ bare_label_keyword:
| ENCODING
| ENCRYPTED
| END_P
| ENFORCED
| ENUM_P
| ERROR_P
| ESCAPE
@ -19404,8 +19431,8 @@ SplitColQualList(List *qualList,
*/
static void
processCASbits(int cas_bits, int location, const char *constrType,
bool *deferrable, bool *initdeferred, bool *not_vali d,
bool *no_inherit, core_yyscan_t yyscanner)
bool *deferrable, bool *initdeferred, bool *is_enforce d,
bool *not_valid, bool *no _inherit, core_yyscan_t yyscanner)
{
/* defaults */
if (deferrable)
@ -19414,6 +19441,8 @@ processCASbits(int cas_bits, int location, const char *constrType,
*initdeferred = false;
if (not_valid)
*not_valid = false;
if (is_enforced)
*is_enforced = true;
if (cas_bits & (CAS_DEFERRABLE | CAS_INITIALLY_DEFERRED))
{
@ -19466,6 +19495,41 @@ processCASbits(int cas_bits, int location, const char *constrType,
constrType),
parser_errposition(location)));
}
if (cas_bits & CAS_NOT_ENFORCED)
{
if (is_enforced)
*is_enforced = false;
else
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
/* translator: %s is CHECK, UNIQUE, or similar */
errmsg("%s constraints cannot be marked NOT ENFORCED",
constrType),
parser_errposition(location)));
/*
* NB: The validated status is irrelevant when the constraint is set to
* NOT ENFORCED, but for consistency, it should be set accordingly.
* This ensures that if the constraint is later changed to ENFORCED, it
* will automatically be in the correct NOT VALIDATED state.
*/
if (not_valid)
*not_valid = true;
}
if (cas_bits & CAS_ENFORCED)
{
if (is_enforced)
*is_enforced = true;
else
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
/* translator: %s is CHECK, UNIQUE, or similar */
errmsg("%s constraints cannot be marked ENFORCED",
constrType),
parser_errposition(location)));
}
}
/*