Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2f0903e

Browse files
committed
Improve performance of ExecEvalWholeRowVar.
In commitb8d7f05, we needed to fix ExecEvalWholeRowVar to not changethe state of the slot it's copying. The initial quick hack at thatrequired two rounds of tuple construction, which is not very nice.To fix, add another primitive to tuptoaster.c that does precisely whatwe need. (I initially tried to do this by refactoring one of theexisting functions into two pieces; but it looked like that might hurtperformance for the existing case, and the amount of code that couldbe shared is not very large, so I gave up on that.)Discussion:https://postgr.es/m/26088.1490315792@sss.pgh.pa.us
1 parent895f937 commit2f0903e

File tree

3 files changed

+90
-11
lines changed

3 files changed

+90
-11
lines changed

‎src/backend/access/heap/tuptoaster.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,6 +1288,74 @@ toast_flatten_tuple_to_datum(HeapTupleHeader tup,
12881288
}
12891289

12901290

1291+
/* ----------
1292+
* toast_build_flattened_tuple -
1293+
*
1294+
*Build a tuple containing no out-of-line toasted fields.
1295+
*(This does not eliminate compressed or short-header datums.)
1296+
*
1297+
*This is essentially just like heap_form_tuple, except that it will
1298+
*expand any external-data pointers beforehand.
1299+
*
1300+
*It's not very clear whether it would be preferable to decompress
1301+
*in-line compressed datums while at it. For now, we don't.
1302+
* ----------
1303+
*/
1304+
HeapTuple
1305+
toast_build_flattened_tuple(TupleDesctupleDesc,
1306+
Datum*values,
1307+
bool*isnull)
1308+
{
1309+
HeapTuplenew_tuple;
1310+
Form_pg_attribute*att=tupleDesc->attrs;
1311+
intnumAttrs=tupleDesc->natts;
1312+
intnum_to_free;
1313+
inti;
1314+
Datumnew_values[MaxTupleAttributeNumber];
1315+
Pointerfreeable_values[MaxTupleAttributeNumber];
1316+
1317+
/*
1318+
* We can pass the caller's isnull array directly to heap_form_tuple, but
1319+
* we potentially need to modify the values array.
1320+
*/
1321+
Assert(numAttrs <=MaxTupleAttributeNumber);
1322+
memcpy(new_values,values,numAttrs*sizeof(Datum));
1323+
1324+
num_to_free=0;
1325+
for (i=0;i<numAttrs;i++)
1326+
{
1327+
/*
1328+
* Look at non-null varlena attributes
1329+
*/
1330+
if (!isnull[i]&&att[i]->attlen==-1)
1331+
{
1332+
structvarlena*new_value;
1333+
1334+
new_value= (structvarlena*)DatumGetPointer(new_values[i]);
1335+
if (VARATT_IS_EXTERNAL(new_value))
1336+
{
1337+
new_value=heap_tuple_fetch_attr(new_value);
1338+
new_values[i]=PointerGetDatum(new_value);
1339+
freeable_values[num_to_free++]= (Pointer)new_value;
1340+
}
1341+
}
1342+
}
1343+
1344+
/*
1345+
* Form the reconfigured tuple.
1346+
*/
1347+
new_tuple=heap_form_tuple(tupleDesc,new_values,isnull);
1348+
1349+
/*
1350+
* Free allocated temp values
1351+
*/
1352+
for (i=0;i<num_to_free;i++)
1353+
pfree(freeable_values[i]);
1354+
1355+
returnnew_tuple;
1356+
}
1357+
1358+
12911359
/* ----------
12921360
* toast_compress_datum -
12931361
*

‎src/backend/executor/execExprInterp.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
*/
5959
#include"postgres.h"
6060

61-
#include"access/htup_details.h"
61+
#include"access/tuptoaster.h"
6262
#include"catalog/pg_type.h"
6363
#include"executor/execExpr.h"
6464
#include"executor/nodeSubplan.h"
@@ -3508,24 +3508,24 @@ ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
35083508
}
35093509

35103510
/*
3511-
*Copy the slot tuple and make sure any toasted fields get detoasted.
3511+
*Build a composite datum, making sure any toasted fields get detoasted.
35123512
*
3513-
* (The intermediate copy is a tad annoying here, but we currently have no
3514-
* primitive that will do the right thing. Note it is critical that we
3515-
* not change the slot's state, so we can't use ExecFetchSlotTupleDatum.)
3513+
* (Note: it is critical that we not change the slot's state here.)
35163514
*/
3517-
tuple=ExecCopySlotTuple(slot);
3518-
dtuple= (HeapTupleHeader)
3519-
DatumGetPointer(heap_copy_tuple_as_datum(tuple,
3520-
slot->tts_tupleDescriptor));
3521-
heap_freetuple(tuple);
3515+
tuple=toast_build_flattened_tuple(slot->tts_tupleDescriptor,
3516+
slot->tts_values,
3517+
slot->tts_isnull);
3518+
dtuple=tuple->t_data;
35223519

35233520
/*
35243521
* Label the datum with the composite type info we identified before.
3522+
*
3523+
* (Note: we could skip doing this by passing op->d.wholerow.tupdesc to
3524+
* the tuple build step; but that seems a tad risky so let's not.)
35253525
*/
35263526
HeapTupleHeaderSetTypeId(dtuple,op->d.wholerow.tupdesc->tdtypeid);
35273527
HeapTupleHeaderSetTypMod(dtuple,op->d.wholerow.tupdesc->tdtypmod);
35283528

3529-
*op->resnull= false;
35303529
*op->resvalue=PointerGetDatum(dtuple);
3530+
*op->resnull= false;
35313531
}

‎src/include/access/tuptoaster.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,17 @@ extern Datum toast_flatten_tuple_to_datum(HeapTupleHeader tup,
193193
uint32tup_len,
194194
TupleDesctupleDesc);
195195

196+
/* ----------
197+
* toast_build_flattened_tuple -
198+
*
199+
*Build a tuple containing no out-of-line toasted fields.
200+
*(This does not eliminate compressed or short-header datums.)
201+
* ----------
202+
*/
203+
externHeapTupletoast_build_flattened_tuple(TupleDesctupleDesc,
204+
Datum*values,
205+
bool*isnull);
206+
196207
/* ----------
197208
* toast_compress_datum -
198209
*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp