Changed ExecConstraints() and ExecRelCheck() to cache constraint

qualification trees in the execution state to avoid memory exhaustion
on INSERT, UPDATE and COPY to tables with check constraints. This
also speeds up those operations substantial because the nodeToString()
for the constraints ccbin is only performed once per query.

Jan
This commit is contained in:
Jan Wieck 1999-02-07 16:50:55 +00:00
parent ccf330d67e
commit cff91fedff
4 changed files with 29 additions and 14 deletions

View file

@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.63 1998/10/26 00:59:21 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.63.2.1 1999/02/07 16:50:51 wieck Exp $
*
*-------------------------------------------------------------------------
*/
@ -402,6 +402,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
Node **indexPred = NULL;
TupleDesc rtupdesc;
ExprContext *econtext = NULL;
EState *estate = makeNode(EState);
#ifndef OMIT_PARTIAL_INDEX
TupleTable tupleTable;
@ -709,7 +710,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
{
HeapTuple newtuple;
newtuple = ExecConstraints("CopyFrom", rel, tuple);
newtuple = ExecConstraints("CopyFrom", rel, tuple, estate);
if (newtuple != tuple)
{

View file

@ -26,7 +26,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.58 1998/10/14 05:10:00 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.58.2.1 1999/02/07 16:50:52 wieck Exp $
*
*-------------------------------------------------------------------------
*/
@ -965,7 +965,8 @@ ExecAppend(TupleTableSlot *slot,
{
HeapTuple newtuple;
newtuple = ExecConstraints("ExecAppend", resultRelationDesc, tuple);
newtuple = ExecConstraints("ExecAppend", resultRelationDesc,
tuple, estate);
if (newtuple != tuple) /* modified by DEFAULT */
{
@ -1148,7 +1149,8 @@ ExecReplace(TupleTableSlot *slot,
{
HeapTuple newtuple;
newtuple = ExecConstraints("ExecReplace", resultRelationDesc, tuple);
newtuple = ExecConstraints("ExecReplace", resultRelationDesc,
tuple, estate);
if (newtuple != tuple) /* modified by DEFAULT */
{
@ -1279,7 +1281,7 @@ ExecAttrDefault(Relation rel, HeapTuple tuple)
#endif
static char *
ExecRelCheck(Relation rel, HeapTuple tuple)
ExecRelCheck(Relation rel, HeapTuple tuple, EState *estate)
{
int ncheck = rel->rd_att->constr->num_check;
ConstrCheck *check = rel->rd_att->constr->check;
@ -1312,14 +1314,24 @@ ExecRelCheck(Relation rel, HeapTuple tuple)
econtext->ecxt_param_exec_vals = NULL; /* exec param values */
econtext->ecxt_range_table = rtlist; /* range table */
if (estate->es_result_relation_constraints == NULL)
{
estate->es_result_relation_constraints =
(List **)palloc(ncheck * sizeof(List *));
for (i = 0; i < ncheck; i++)
{
qual = (List *) stringToNode(check[i].ccbin);
estate->es_result_relation_constraints[i] = qual;
}
}
for (i = 0; i < ncheck; i++)
{
qual = (List *) stringToNode(check[i].ccbin);
qual = estate->es_result_relation_constraints[i];
res = ExecQual(qual, econtext);
pfree(qual);
if (!res)
return check[i].ccname;
}
@ -1335,7 +1347,7 @@ ExecRelCheck(Relation rel, HeapTuple tuple)
}
HeapTuple
ExecConstraints(char *caller, Relation rel, HeapTuple tuple)
ExecConstraints(char *caller, Relation rel, HeapTuple tuple, EState *estate)
{
HeapTuple newtuple = tuple;
@ -1362,7 +1374,7 @@ ExecConstraints(char *caller, Relation rel, HeapTuple tuple)
{
char *failed;
if ((failed = ExecRelCheck(rel, tuple)) != NULL)
if ((failed = ExecRelCheck(rel, tuple, estate)) != NULL)
elog(ERROR, "%s: rejected due to CHECK constraint %s", caller, failed);
}

View file

@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: executor.h,v 1.27 1998/10/14 05:10:05 momjian Exp $
* $Id: executor.h,v 1.27.2.1 1999/02/07 16:50:54 wieck Exp $
*
*-------------------------------------------------------------------------
*/
@ -85,7 +85,8 @@ extern HeapTuple ExecRemoveJunk(JunkFilter *junkfilter, TupleTableSlot *slot);
extern TupleDesc ExecutorStart(QueryDesc *queryDesc, EState *estate);
extern TupleTableSlot *ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature, int count);
extern void ExecutorEnd(QueryDesc *queryDesc, EState *estate);
extern HeapTuple ExecConstraints(char *caller, Relation rel, HeapTuple tuple);
extern HeapTuple ExecConstraints(char *caller, Relation rel, HeapTuple tuple,
EState *estate);
#ifdef QUERY_LIMIT
extern int ExecutorLimit(int limit);
extern int ExecutorGetLimit(void);

View file

@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: execnodes.h,v 1.18 1998/09/01 04:36:35 momjian Exp $
* $Id: execnodes.h,v 1.18.2.1 1999/02/07 16:50:55 wieck Exp $
*
*-------------------------------------------------------------------------
*/
@ -199,6 +199,7 @@ typedef struct EState
Snapshot es_snapshot;
List *es_range_table;
RelationInfo *es_result_relation_info;
List **es_result_relation_constraints;
Relation es_into_relation_descriptor;
ParamListInfo es_param_list_info;
ParamExecData *es_param_exec_vals; /* this is for subselects */