diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2004-06-04 20:35:21 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2004-06-04 20:35:21 +0000 |
commit | 8f2ea8b7b53a02078ba0393e6892ac5356a3631e (patch) | |
tree | 536f02e4a6eec0304d76688d65cffbcea9679c9b /src/backend/executor | |
parent | af44cac6ef46e225ae963c5e1f9e2e91a0112e04 (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.c | 49 | ||||
-rw-r--r-- | src/backend/executor/spi.c | 11 |
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 |