aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Wieck <JanWieck@Yahoo.com>1999-02-07 16:17:14 +0000
committerJan Wieck <JanWieck@Yahoo.com>1999-02-07 16:17:14 +0000
commitef590e101ec2e7fd4d2c80b925ce2188aa000bba (patch)
treedf6c63a57a232ff236a5b0885857060f4feb5db3
parentdd4a357dc9eeeafa0e8768ab3ae4ffaa4d8c2fcf (diff)
downloadpostgresql-ef590e101ec2e7fd4d2c80b925ce2188aa000bba.tar.gz
postgresql-ef590e101ec2e7fd4d2c80b925ce2188aa000bba.zip
Changed ExecConstraints() and ExecRelCheck() to cache the constraints
qualification expression trees in the execution state. Prevents from memory exhaustion on INSERT, UPDATE or COPY to tables that have CHECK constraints. Speedup against the variant using freeObject() is more than factor 2. Jan
-rw-r--r--src/backend/commands/copy.c5
-rw-r--r--src/backend/executor/execMain.c28
-rw-r--r--src/include/executor/executor.h5
-rw-r--r--src/include/nodes/execnodes.h3
4 files changed, 27 insertions, 14 deletions
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index ff8555e39dd..9df08908c23 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.71 1999/02/03 21:16:03 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.72 1999/02/07 16:17:10 wieck Exp $
*
*-------------------------------------------------------------------------
*/
@@ -505,6 +505,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
Node **indexPred = NULL;
TupleDesc rtupdesc;
ExprContext *econtext = NULL;
+ EState *estate = makeNode(EState); /* for ExecConstraints() */
#ifndef OMIT_PARTIAL_INDEX
TupleTable tupleTable;
@@ -805,7 +806,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
*/
if (rel->rd_att->constr)
- ExecConstraints("CopyFrom", rel, tuple);
+ ExecConstraints("CopyFrom", rel, tuple, estate);
heap_insert(rel, tuple);
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index d511e5f6e56..5ce90902b4c 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.74 1999/02/07 14:20:11 wieck Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.75 1999/02/07 16:17:11 wieck Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1124,7 +1124,7 @@ ExecAppend(TupleTableSlot *slot,
if (resultRelationDesc->rd_att->constr)
{
- ExecConstraints("ExecAppend", resultRelationDesc, tuple);
+ ExecConstraints("ExecAppend", resultRelationDesc, tuple, estate);
}
/******************
@@ -1327,7 +1327,7 @@ ExecReplace(TupleTableSlot *slot,
if (resultRelationDesc->rd_att->constr)
{
- ExecConstraints("ExecReplace", resultRelationDesc, tuple);
+ ExecConstraints("ExecReplace", resultRelationDesc, tuple, estate);
}
/*
@@ -1472,7 +1472,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;
@@ -1505,14 +1505,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);
- freeObject(qual);
-
if (!res)
return check[i].ccname;
}
@@ -1528,7 +1538,7 @@ ExecRelCheck(Relation rel, HeapTuple tuple)
}
void
-ExecConstraints(char *caller, Relation rel, HeapTuple tuple)
+ExecConstraints(char *caller, Relation rel, HeapTuple tuple, EState *estate)
{
Assert(rel->rd_att->constr);
@@ -1549,7 +1559,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);
}
diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h
index 33774d21f41..68d89897d09 100644
--- a/src/include/executor/executor.h
+++ b/src/include/executor/executor.h
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: executor.h,v 1.28 1998/11/27 19:33:32 vadim Exp $
+ * $Id: executor.h,v 1.29 1999/02/07 16:17:12 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 void ExecConstraints(char *caller, Relation rel, HeapTuple tuple);
+extern void ExecConstraints(char *caller, Relation rel, HeapTuple tuple,
+ EState *estate);
#ifdef QUERY_LIMIT
extern int ExecutorLimit(int limit);
extern int ExecutorGetLimit(void);
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index d9cdd2509de..45625c62e7b 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: execnodes.h,v 1.22 1999/01/29 09:23:13 vadim Exp $
+ * $Id: execnodes.h,v 1.23 1999/02/07 16:17:14 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 */