diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2003-02-03 21:15:45 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2003-02-03 21:15:45 +0000 |
commit | 3752e85bad45e98383ea1c9e7e7dbaf13f41da7e (patch) | |
tree | ce6735a837cf169d82744b7877630494d35ce65a /src/backend/executor | |
parent | 464598b637cfabde01695a27a32ed8f133d127d7 (diff) | |
download | postgresql-3752e85bad45e98383ea1c9e7e7dbaf13f41da7e.tar.gz postgresql-3752e85bad45e98383ea1c9e7e7dbaf13f41da7e.zip |
Determine the set of constraints applied to a domain at executor
startup, not in the parser; this allows ALTER DOMAIN to work correctly
with domain constraint operations stored in rules. Rod Taylor;
code review by Tom Lane.
Diffstat (limited to 'src/backend/executor')
-rw-r--r-- | src/backend/executor/execQual.c | 82 |
1 files changed, 45 insertions, 37 deletions
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c index c13e1e1e4d8..a2583fcc4c9 100644 --- a/src/backend/executor/execQual.c +++ b/src/backend/executor/execQual.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.123 2003/01/12 04:03:34 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.124 2003/02/03 21:15:43 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -36,6 +36,7 @@ #include "access/heapam.h" #include "catalog/pg_type.h" +#include "commands/typecmds.h" #include "executor/execdebug.h" #include "executor/functions.h" #include "executor/nodeSubplan.h" @@ -80,10 +81,10 @@ static Datum ExecEvalNullTest(GenericExprState *nstate, static Datum ExecEvalBooleanTest(GenericExprState *bstate, ExprContext *econtext, bool *isNull, ExprDoneCond *isDone); -static Datum ExecEvalConstraintTest(ConstraintTestState *cstate, +static Datum ExecEvalCoerceToDomain(CoerceToDomainState *cstate, ExprContext *econtext, bool *isNull, ExprDoneCond *isDone); -static Datum ExecEvalConstraintTestValue(ConstraintTestValue *conVal, +static Datum ExecEvalCoerceToDomainValue(CoerceToDomainValue *conVal, ExprContext *econtext, bool *isNull); static Datum ExecEvalFieldSelect(GenericExprState *fstate, ExprContext *econtext, @@ -1559,32 +1560,37 @@ ExecEvalBooleanTest(GenericExprState *bstate, } /* - * ExecEvalConstraintTest + * ExecEvalCoerceToDomain * - * Test the constraint against the data provided. If the data fits - * within the constraint specifications, pass it through (return the + * Test the provided data against the domain constraint(s). If the data + * passes the constraint specifications, pass it through (return the * datum) otherwise throw an error. */ static Datum -ExecEvalConstraintTest(ConstraintTestState *cstate, ExprContext *econtext, +ExecEvalCoerceToDomain(CoerceToDomainState *cstate, ExprContext *econtext, bool *isNull, ExprDoneCond *isDone) { - ConstraintTest *constraint = (ConstraintTest *) cstate->xprstate.expr; + CoerceToDomain *ctest = (CoerceToDomain *) cstate->xprstate.expr; Datum result; + List *l; result = ExecEvalExpr(cstate->arg, econtext, isNull, isDone); if (isDone && *isDone == ExprEndResult) return result; /* nothing to check */ - switch (constraint->testtype) + foreach(l, cstate->constraints) { - case CONSTR_TEST_NOTNULL: - if (*isNull) - elog(ERROR, "Domain %s does not allow NULL values", - constraint->domname); - break; - case CONSTR_TEST_CHECK: + DomainConstraintState *con = (DomainConstraintState *) lfirst(l); + + switch (con->constrainttype) + { + case DOM_CONSTRAINT_NOTNULL: + if (*isNull) + elog(ERROR, "Domain %s does not allow NULL values", + format_type_be(ctest->resulttype)); + break; + case DOM_CONSTRAINT_CHECK: { Datum conResult; bool conIsNull; @@ -1592,7 +1598,7 @@ ExecEvalConstraintTest(ConstraintTestState *cstate, ExprContext *econtext, bool save_isNull; /* - * Set up value to be returned by ConstraintTestValue nodes. + * Set up value to be returned by CoerceToDomainValue nodes. * We must save and restore prior setting of econtext's * domainValue fields, in case this node is itself within * a check expression for another domain. @@ -1603,35 +1609,37 @@ ExecEvalConstraintTest(ConstraintTestState *cstate, ExprContext *econtext, econtext->domainValue_datum = result; econtext->domainValue_isNull = *isNull; - conResult = ExecEvalExpr(cstate->check_expr, + conResult = ExecEvalExpr(con->check_expr, econtext, &conIsNull, NULL); if (!conIsNull && !DatumGetBool(conResult)) - elog(ERROR, "ExecEvalConstraintTest: Domain %s constraint %s failed", - constraint->domname, constraint->name); + elog(ERROR, "ExecEvalCoerceToDomain: Domain %s constraint %s failed", + format_type_be(ctest->resulttype), con->name); econtext->domainValue_datum = save_datum; econtext->domainValue_isNull = save_isNull; + + break; } - break; - default: - elog(ERROR, "ExecEvalConstraintTest: Constraint type unknown"); - break; + default: + elog(ERROR, "ExecEvalCoerceToDomain: Constraint type unknown"); + break; + } } - /* If all has gone well (constraint did not fail) return the datum */ + /* If all has gone well (constraints did not fail) return the datum */ return result; } /* - * ExecEvalConstraintTestValue + * ExecEvalCoerceToDomainValue * - * Return the value stored by constraintTest. + * Return the value stored by CoerceToDomain. */ static Datum -ExecEvalConstraintTestValue(ConstraintTestValue *conVal, ExprContext *econtext, - bool *isNull) +ExecEvalCoerceToDomainValue(CoerceToDomainValue *conVal, + ExprContext *econtext, bool *isNull) { *isNull = econtext->domainValue_isNull; return econtext->domainValue_datum; @@ -1830,14 +1838,14 @@ ExecEvalExpr(ExprState *expression, isNull, isDone); break; - case T_ConstraintTest: - retDatum = ExecEvalConstraintTest((ConstraintTestState *) expression, + case T_CoerceToDomain: + retDatum = ExecEvalCoerceToDomain((CoerceToDomainState *) expression, econtext, isNull, isDone); break; - case T_ConstraintTestValue: - retDatum = ExecEvalConstraintTestValue((ConstraintTestValue *) expr, + case T_CoerceToDomainValue: + retDatum = ExecEvalCoerceToDomainValue((CoerceToDomainValue *) expr, econtext, isNull); break; @@ -1915,7 +1923,7 @@ ExecInitExpr(Expr *node, PlanState *parent) case T_Var: case T_Const: case T_Param: - case T_ConstraintTestValue: + case T_CoerceToDomainValue: /* No special setup needed for these node types */ state = (ExprState *) makeNode(ExprState); break; @@ -2092,13 +2100,13 @@ ExecInitExpr(Expr *node, PlanState *parent) state = (ExprState *) gstate; } break; - case T_ConstraintTest: + case T_CoerceToDomain: { - ConstraintTest *ctest = (ConstraintTest *) node; - ConstraintTestState *cstate = makeNode(ConstraintTestState); + CoerceToDomain *ctest = (CoerceToDomain *) node; + CoerceToDomainState *cstate = makeNode(CoerceToDomainState); cstate->arg = ExecInitExpr(ctest->arg, parent); - cstate->check_expr = ExecInitExpr(ctest->check_expr, parent); + cstate->constraints = GetDomainConstraints(ctest->resulttype); state = (ExprState *) cstate; } break; |