From d40885cc4053923591271444719b1f9791c61e49 Mon Sep 17 00:00:00 2001 From: "Vadim B. Mikheev" Date: Fri, 22 Aug 1997 14:28:20 +0000 Subject: [PATCH] + ExecConstraints() --- src/backend/executor/execMain.c | 176 ++++++++++++++++++++++++++++++---------- 1 file changed, 133 insertions(+), 43 deletions(-) diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index d484b477fe..cc8d98d898 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -26,7 +26,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.18 1997/08/22 03:12:16 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.19 1997/08/22 14:28:20 vadim Exp $ * *------------------------------------------------------------------------- */ @@ -73,8 +73,6 @@ static void ExecDelete(TupleTableSlot *slot, ItemPointer tupleid, static void ExecReplace(TupleTableSlot *slot, ItemPointer tupleid, EState *estate, Query *parseTree); -static HeapTuple ExecAttrDefault (Relation rel, HeapTuple tuple); - /* end of local decls */ #ifdef QUERY_LIMIT @@ -930,29 +928,15 @@ ExecAppend(TupleTableSlot *slot, if ( resultRelationDesc->rd_att->constr ) { - if ( resultRelationDesc->rd_att->constr->num_defval > 0 ) - { - HeapTuple newtuple; - - newtuple = ExecAttrDefault (resultRelationDesc, tuple); - - if ( newtuple != tuple ) - { - Assert ( slot->ttc_shouldFree ); - slot->val = tuple = newtuple; - } - } - - if ( resultRelationDesc->rd_att->constr->has_not_null ) + HeapTuple newtuple; + + newtuple = ExecConstraints ("ExecAppend", resultRelationDesc, tuple); + + if ( newtuple != tuple ) /* modified by DEFAULT */ { - int attrChk; - - for (attrChk = 1; attrChk <= resultRelationDesc->rd_att->natts; attrChk++) - { - if (resultRelationDesc->rd_att->attrs[attrChk-1]->attnotnull && heap_attisnull(tuple,attrChk)) - elog(WARN,"ExecAppend: Fail to add null value in not null attribute %s", - resultRelationDesc->rd_att->attrs[attrChk-1]->attname.data); - } + Assert ( slot->ttc_shouldFree ); + pfree (tuple); + slot->val = tuple = newtuple; } } @@ -1081,15 +1065,19 @@ ExecReplace(TupleTableSlot *slot, * ---------------- */ - if (resultRelationDesc->rd_att->constr && resultRelationDesc->rd_att->constr->has_not_null) - { - int attrChk; - for (attrChk = 1; attrChk <= resultRelationDesc->rd_att->natts; attrChk++) { - if (resultRelationDesc->rd_att->attrs[attrChk-1]->attnotnull && heap_attisnull(tuple,attrChk)) - elog(WARN,"ExecReplace: Fail to update null value in not null attribute %s", - resultRelationDesc->rd_att->attrs[attrChk-1]->attname.data); - } - } + if ( resultRelationDesc->rd_att->constr ) + { + HeapTuple newtuple; + + newtuple = ExecConstraints ("ExecReplace", resultRelationDesc, tuple); + + if ( newtuple != tuple ) /* modified by DEFAULT */ + { + Assert ( slot->ttc_shouldFree ); + pfree (tuple); + slot->val = tuple = newtuple; + } + } /* ---------------- * replace the heap tuple @@ -1140,7 +1128,8 @@ ExecAttrDefault (Relation rel, HeapTuple tuple) { int ndef = rel->rd_att->constr->num_defval; AttrDefault *attrdef = rel->rd_att->constr->defval; - ExprContext *econtext = makeNode(ExprContext); + ExprContext *econtext = makeNode (ExprContext); + HeapTuple newtuple; Node *expr; bool isnull; bool isdone; @@ -1150,21 +1139,23 @@ ExecAttrDefault (Relation rel, HeapTuple tuple) char *repl = NULL; int i; + econtext->ecxt_scantuple = NULL; /* scan tuple slot */ + econtext->ecxt_innertuple = NULL; /* inner tuple slot */ + econtext->ecxt_outertuple = NULL; /* outer tuple slot */ + econtext->ecxt_relation = NULL; /* relation */ + econtext->ecxt_relid = 0; /* relid */ + econtext->ecxt_param_list_info = NULL; /* param list info */ + econtext->ecxt_range_table = NULL; /* range table */ for (i = 0; i < ndef; i++) { if ( !heap_attisnull (tuple, attrdef[i].adnum) ) continue; expr = (Node*) stringToNode (attrdef[i].adbin); - econtext->ecxt_scantuple = NULL; /* scan tuple slot */ - econtext->ecxt_innertuple = NULL; /* inner tuple slot */ - econtext->ecxt_outertuple = NULL; /* outer tuple slot */ - econtext->ecxt_relation = NULL; /* relation */ - econtext->ecxt_relid = 0; /* relid */ - econtext->ecxt_param_list_info = NULL; /* param list info */ - econtext->ecxt_range_table = NULL; /* range table */ val = ExecEvalExpr (expr, econtext, &isnull, &isdone); + pfree (expr); + if ( isnull ) continue; @@ -1182,9 +1173,108 @@ ExecAttrDefault (Relation rel, HeapTuple tuple) } + pfree (econtext); + if ( repl == NULL ) return (tuple); - return (heap_modifytuple (tuple, InvalidBuffer, rel, replValue, replNull, repl)); + newtuple = heap_modifytuple (tuple, InvalidBuffer, rel, replValue, replNull, repl); + + pfree (repl); + pfree (replNull); + pfree (replValue); + + return (newtuple); + +} + +static char * +ExecRelCheck (Relation rel, HeapTuple tuple) +{ + int ncheck = rel->rd_att->constr->num_check; + ConstrCheck *check = rel->rd_att->constr->check; + ExprContext *econtext = makeNode (ExprContext); + TupleTableSlot *slot = makeNode (TupleTableSlot); + RangeTblEntry *rte = makeNode (RangeTblEntry); + List *rtlist; + List *qual; + bool res; + int i; + + slot->val = tuple; + slot->ttc_shouldFree = false; + slot->ttc_descIsNew = true; + slot->ttc_tupleDescriptor = rel->rd_att; + slot->ttc_buffer = InvalidBuffer; + slot->ttc_whichplan = -1; + rte->relname = nameout (&(rel->rd_rel->relname)); + rte->timeRange = NULL; + rte->refname = rte->relname; + rte->relid = rel->rd_id; + rte->inh = false; + rte->archive = false; + rte->inFromCl = true; + rte->timeQual = NULL; + rtlist = lcons (rte, NIL); + econtext->ecxt_scantuple = slot; /* scan tuple slot */ + econtext->ecxt_innertuple = NULL; /* inner tuple slot */ + econtext->ecxt_outertuple = NULL; /* outer tuple slot */ + econtext->ecxt_relation = rel; /* relation */ + econtext->ecxt_relid = 0; /* relid */ + econtext->ecxt_param_list_info = NULL; /* param list info */ + econtext->ecxt_range_table = rtlist; /* range table */ + + for (i = 0; i < ncheck; i++) + { + qual = (List*) stringToNode (check[i].ccbin); + + res = ExecQual (qual, econtext); + + pfree (qual); + + if ( !res ) + return (check[i].ccname); + } + + pfree (slot); + pfree (rte->relname); + pfree (rte); + pfree (rtlist); + pfree (econtext); + + return ((char *) NULL); + +} + +HeapTuple +ExecConstraints (char *caller, Relation rel, HeapTuple tuple) +{ + HeapTuple newtuple = tuple; + + Assert ( rel->rd_att->constr ); + if ( rel->rd_att->constr->num_defval > 0 ) + newtuple = tuple = ExecAttrDefault (rel, tuple); + + if ( rel->rd_att->constr->has_not_null ) + { + int attrChk; + + for (attrChk = 1; attrChk <= rel->rd_att->natts; attrChk++) + { + if (rel->rd_att->attrs[attrChk-1]->attnotnull && heap_attisnull (tuple,attrChk)) + elog(WARN,"%s: Fail to add null value in not null attribute %s", + caller, rel->rd_att->attrs[attrChk-1]->attname.data); + } + } + + if ( rel->rd_att->constr->num_check > 0 ) + { + char *failed; + + if ( ( failed = ExecRelCheck (rel, tuple) ) != NULL ) + elog(WARN,"%s: rejected due to CHECK constraint %s", caller, failed); + } + + return (newtuple); } -- 2.11.0