From b0422b215c100bb29c1071872012a1f3c6681058 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 12 Dec 2002 20:35:16 +0000 Subject: Preliminary code review for domain CHECK constraints patch: add documentation, make VALUE a non-reserved word again, use less invasive method of passing ConstraintTestValue into transformExpr, fix problems with nested constraint testing, do correct thing with NULL result from a constraint expression, remove memory leak. Domain checks still need much more work if we are going to allow ALTER DOMAIN, however. --- src/backend/executor/execQual.c | 65 ++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 26 deletions(-) (limited to 'src/backend/executor/execQual.c') diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c index d96e983fa30..79796f1c0b2 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.117 2002/12/12 15:49:28 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.118 2002/12/12 20:35:12 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -77,8 +77,7 @@ static Datum ExecEvalConstraintTest(ConstraintTest *constraint, ExprContext *econtext, bool *isNull, ExprDoneCond *isDone); static Datum ExecEvalConstraintTestValue(ConstraintTestValue *conVal, - ExprContext *econtext, - bool *isNull, ExprDoneCond *isDone); + ExprContext *econtext, bool *isNull); /*---------- @@ -1553,23 +1552,6 @@ ExecEvalBooleanTest(BooleanTest *btest, } } -/* - * ExecEvalConstraintTestValue - * - * Return the value stored by constraintTest. - */ -static Datum -ExecEvalConstraintTestValue(ConstraintTestValue *conVal, ExprContext *econtext, - bool *isNull, ExprDoneCond *isDone) -{ - /* - * If the Datum hasn't been set, then it's ExecEvalConstraintTest - * hasn't been called. - */ - *isNull = econtext->domainValue_isNull; - return econtext->domainValue_datum; -} - /* * ExecEvalConstraintTest * @@ -1585,6 +1567,9 @@ ExecEvalConstraintTest(ConstraintTest *constraint, ExprContext *econtext, result = ExecEvalExpr((Node *) constraint->arg, econtext, isNull, isDone); + if (isDone && *isDone == ExprEndResult) + return result; /* nothing to check */ + switch (constraint->testtype) { case CONSTR_TEST_NOTNULL: @@ -1595,16 +1580,32 @@ ExecEvalConstraintTest(ConstraintTest *constraint, ExprContext *econtext, case CONSTR_TEST_CHECK: { Datum conResult; + bool conIsNull; + Datum save_datum; + bool save_isNull; + + /* + * Set up value to be returned by ConstraintTestValue 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. + */ + save_datum = econtext->domainValue_datum; + save_isNull = econtext->domainValue_isNull; - /* Var with attnum == UnassignedAttrNum uses the result */ econtext->domainValue_datum = result; econtext->domainValue_isNull = *isNull; - conResult = ExecEvalExpr((Node *) constraint->check_expr, econtext, isNull, isDone); + conResult = ExecEvalExpr((Node *) constraint->check_expr, + econtext, &conIsNull, NULL); - if (!DatumGetBool(conResult)) + if (!conIsNull && + !DatumGetBool(conResult)) elog(ERROR, "ExecEvalConstraintTest: Domain %s constraint %s failed", constraint->domname, constraint->name); + + econtext->domainValue_datum = save_datum; + econtext->domainValue_isNull = save_isNull; } break; default: @@ -1616,6 +1617,19 @@ ExecEvalConstraintTest(ConstraintTest *constraint, ExprContext *econtext, return result; } +/* + * ExecEvalConstraintTestValue + * + * Return the value stored by constraintTest. + */ +static Datum +ExecEvalConstraintTestValue(ConstraintTestValue *conVal, ExprContext *econtext, + bool *isNull) +{ + *isNull = econtext->domainValue_isNull; + return econtext->domainValue_datum; +} + /* ---------------------------------------------------------------- * ExecEvalFieldSelect * @@ -1811,9 +1825,8 @@ ExecEvalExpr(Node *expression, break; case T_ConstraintTestValue: retDatum = ExecEvalConstraintTestValue((ConstraintTestValue *) expression, - econtext, - isNull, - isDone); + econtext, + isNull); break; default: elog(ERROR, "ExecEvalExpr: unknown expression type %d", -- cgit v1.2.3