summaryrefslogtreecommitdiff
path: root/src/backend/executor
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2004-06-04 20:35:21 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2004-06-04 20:35:21 +0000
commit8f2ea8b7b53a02078ba0393e6892ac5356a3631e (patch)
tree536f02e4a6eec0304d76688d65cffbcea9679c9b /src/backend/executor
parentaf44cac6ef46e225ae963c5e1f9e2e91a0112e04 (diff)
Resurrect heap_deformtuple(), this time implemented as a singly nested
loop over the fields instead of a loop around heap_getattr. This is considerably faster (O(N) instead of O(N^2)) when there are nulls or varlena fields, since those prevent use of attcacheoff. Replace loops over heap_getattr with heap_deformtuple in situations where all or most of the fields have to be fetched, such as printtup and tuptoaster. Profiling done more than a year ago shows that this should be a nice win for situations involving many-column tables.
Diffstat (limited to 'src/backend/executor')
-rw-r--r--src/backend/executor/execJunk.c49
-rw-r--r--src/backend/executor/spi.c11
2 files changed, 39 insertions, 21 deletions
diff --git a/src/backend/executor/execJunk.c b/src/backend/executor/execJunk.c
index 20c385134b2..8c693ddc98c 100644
--- a/src/backend/executor/execJunk.c
+++ b/src/backend/executor/execJunk.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/execJunk.c,v 1.40 2004/05/26 04:41:14 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execJunk.c,v 1.41 2004/06/04 20:35:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -246,12 +246,15 @@ ExecRemoveJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
TupleDesc cleanTupType;
TupleDesc tupType;
int cleanLength;
- bool isNull;
int i;
Datum *values;
char *nulls;
+ Datum *old_values;
+ char *old_nulls;
Datum values_array[64];
+ Datum old_values_array[64];
char nulls_array[64];
+ char old_nulls_array[64];
/*
* get info from the slot and the junk filter
@@ -265,11 +268,15 @@ ExecRemoveJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
/*
* Create the arrays that will hold the attribute values and the null
- * information for the new "clean" tuple.
+ * information for the old tuple and new "clean" tuple.
*
* Note: we use memory on the stack to optimize things when we are
* dealing with a small number of attributes. for large tuples we just
* use palloc.
+ *
+ * Note: we could use just one set of arrays if we were willing to
+ * assume that the resno mapping is monotonic... I think it is, but
+ * won't take the risk of breaking things right now.
*/
if (cleanLength > 64)
{
@@ -281,36 +288,52 @@ ExecRemoveJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
values = values_array;
nulls = nulls_array;
}
+ if (tupType->natts > 64)
+ {
+ old_values = (Datum *) palloc(tupType->natts * sizeof(Datum));
+ old_nulls = (char *) palloc(tupType->natts * sizeof(char));
+ }
+ else
+ {
+ old_values = old_values_array;
+ old_nulls = old_nulls_array;
+ }
/*
- * Exctract one by one all the values of the "clean" tuple.
+ * Extract all the values of the old tuple.
+ */
+ heap_deformtuple(tuple, tupType, old_values, old_nulls);
+
+ /*
+ * Transpose into proper fields of the new tuple.
*/
for (i = 0; i < cleanLength; i++)
{
- values[i] = heap_getattr(tuple, cleanMap[i], tupType, &isNull);
+ int j = cleanMap[i] - 1;
- if (isNull)
- nulls[i] = 'n';
- else
- nulls[i] = ' ';
+ values[i] = old_values[j];
+ nulls[i] = old_nulls[j];
}
/*
* Now form the new tuple.
*/
- cleanTuple = heap_formtuple(cleanTupType,
- values,
- nulls);
+ cleanTuple = heap_formtuple(cleanTupType, values, nulls);
/*
* We are done. Free any space allocated for 'values' and 'nulls' and
* return the new tuple.
*/
- if (cleanLength > 64)
+ if (values != values_array)
{
pfree(values);
pfree(nulls);
}
+ if (old_values != old_values_array)
+ {
+ pfree(old_values);
+ pfree(old_nulls);
+ }
return cleanTuple;
}
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
index 6ec4d810a8e..047b8fa2aae 100644
--- a/src/backend/executor/spi.c
+++ b/src/backend/executor/spi.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.115 2004/05/30 23:40:26 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.116 2004/06/04 20:35:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -427,7 +427,6 @@ SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, int *attnum,
int numberOfAttributes;
Datum *v;
char *n;
- bool isnull;
int i;
if (rel == NULL || tuple == NULL || natts < 0 || attnum == NULL || Values == NULL)
@@ -448,11 +447,7 @@ SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, int *attnum,
n = (char *) palloc(numberOfAttributes * sizeof(char));
/* fetch old values and nulls */
- for (i = 0; i < numberOfAttributes; i++)
- {
- v[i] = heap_getattr(tuple, i + 1, rel->rd_att, &isnull);
- n[i] = (isnull) ? 'n' : ' ';
- }
+ heap_deformtuple(tuple, rel->rd_att, v, n);
/* replace values and nulls */
for (i = 0; i < natts; i++)
@@ -474,7 +469,7 @@ SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, int *attnum,
mtuple->t_data->t_ctid = tuple->t_data->t_ctid;
mtuple->t_self = tuple->t_self;
mtuple->t_tableOid = tuple->t_tableOid;
- if (rel->rd_rel->relhasoids)
+ if (rel->rd_att->tdhasoid)
HeapTupleSetOid(mtuple, HeapTupleGetOid(tuple));
}
else