Skip to content

Commit b2539d7

Browse files
committed
Add rewrite rules and tupdesc flags
Signed-off-by: Ildus Kurbangaliev <i.kurbangaliev@gmail.com>
1 parent 6543e14 commit b2539d7

File tree

18 files changed

+187
-17
lines changed

18 files changed

+187
-17
lines changed

src/backend/access/brin/brin_tuple.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ brin_form_tuple(BrinDesc *brdesc, BlockNumber blkno, BrinMemTuple *tuple,
9696
int keyno;
9797
int idxattno;
9898
uint16 phony_infomask = 0;
99+
uint16 phony_infomask2 = 0;
99100
bits8 *phony_nullbitmap;
100101
Size len,
101102
hoff,
@@ -187,6 +188,7 @@ brin_form_tuple(BrinDesc *brdesc, BlockNumber blkno, BrinMemTuple *tuple,
187188
(char *) rettuple + hoff,
188189
data_len,
189190
&phony_infomask,
191+
&phony_infomask2,
190192
phony_nullbitmap);
191193

192194
/* done with these */

src/backend/access/common/heaptuple.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ fill_val(Form_pg_attribute att,
177177
int *bitmask,
178178
char **dataP,
179179
uint16 *infomask,
180+
uint16 *infomask2,
180181
Datum datum,
181182
bool isnull)
182183
{
@@ -207,6 +208,9 @@ fill_val(Form_pg_attribute att,
207208
**bit |= *bitmask;
208209
}
209210

211+
if (OidIsValid(att->attcompression))
212+
*infomask2 |= HEAP_HASCUSTOMCOMPRESSED;
213+
210214
/*
211215
* XXX we use the att_align macros on the pointer value itself, not on an
212216
* offset. This is a bit of a hack.
@@ -245,6 +249,15 @@ fill_val(Form_pg_attribute att,
245249
/* no alignment, since it's short by definition */
246250
data_length = VARSIZE_EXTERNAL(val);
247251
memcpy(data, val, data_length);
252+
253+
if (VARATT_IS_EXTERNAL_ONDISK(val))
254+
{
255+
struct varatt_external toast_pointer;
256+
257+
VARATT_EXTERNAL_GET_POINTER(toast_pointer, val);
258+
if (VARATT_EXTERNAL_IS_CUSTOM_COMPRESSED(toast_pointer))
259+
*infomask2 |= HEAP_HASCUSTOMCOMPRESSED;
260+
}
248261
}
249262
}
250263
else if (VARATT_IS_SHORT(val))
@@ -268,6 +281,9 @@ fill_val(Form_pg_attribute att,
268281
att->attalign);
269282
data_length = VARSIZE(val);
270283
memcpy(data, val, data_length);
284+
285+
if (VARATT_IS_CUSTOM_COMPRESSED(val))
286+
*infomask2 |= HEAP_HASCUSTOMCOMPRESSED;
271287
}
272288
}
273289
else if (att->attlen == -2)
@@ -304,7 +320,7 @@ void
304320
heap_fill_tuple(TupleDesc tupleDesc,
305321
Datum *values, bool *isnull,
306322
char *data, Size data_size,
307-
uint16 *infomask, bits8 *bit)
323+
uint16 *infomask, uint16 *infomask2, bits8 *bit)
308324
{
309325
bits8 *bitP;
310326
int bitmask;
@@ -328,6 +344,7 @@ heap_fill_tuple(TupleDesc tupleDesc,
328344
}
329345

330346
*infomask &= ~(HEAP_HASNULL | HEAP_HASVARWIDTH | HEAP_HASEXTERNAL);
347+
*infomask2 &= ~HEAP_HASCUSTOMCOMPRESSED;
331348

332349
for (i = 0; i < numberOfAttributes; i++)
333350
{
@@ -338,6 +355,7 @@ heap_fill_tuple(TupleDesc tupleDesc,
338355
&bitmask,
339356
&data,
340357
infomask,
358+
infomask2,
341359
values ? values[i] : PointerGetDatum(NULL),
342360
isnull ? isnull[i] : true);
343361
}
@@ -752,6 +770,7 @@ expand_tuple(HeapTuple *targetHeapTuple,
752770
int bitMask = 0;
753771
char *targetData;
754772
uint16 *infoMask;
773+
uint16 *infoMask2;
755774

756775
Assert((targetHeapTuple && !targetMinimalTuple)
757776
|| (!targetHeapTuple && targetMinimalTuple));
@@ -864,6 +883,7 @@ expand_tuple(HeapTuple *targetHeapTuple,
864883
+ offsetof(HeapTupleHeaderData, t_bits));
865884
targetData = (char *) (*targetHeapTuple)->t_data + hoff;
866885
infoMask = &(targetTHeader->t_infomask);
886+
infoMask2 = &(targetTHeader->t_infomask2);
867887
}
868888
else
869889
{
@@ -882,6 +902,7 @@ expand_tuple(HeapTuple *targetHeapTuple,
882902
+ offsetof(MinimalTupleData, t_bits));
883903
targetData = (char *) *targetMinimalTuple + hoff;
884904
infoMask = &((*targetMinimalTuple)->t_infomask);
905+
infoMask2 = &((*targetMinimalTuple)->t_infomask2);
885906
}
886907

887908
if (targetNullLen > 0)
@@ -934,6 +955,7 @@ expand_tuple(HeapTuple *targetHeapTuple,
934955
&bitMask,
935956
&targetData,
936957
infoMask,
958+
infoMask2,
937959
attrmiss[attnum].am_value,
938960
false);
939961
}
@@ -944,6 +966,7 @@ expand_tuple(HeapTuple *targetHeapTuple,
944966
&bitMask,
945967
&targetData,
946968
infoMask,
969+
infoMask2,
947970
(Datum) 0,
948971
true);
949972
}
@@ -1093,6 +1116,7 @@ heap_form_tuple(TupleDesc tupleDescriptor,
10931116
(char *) td + hoff,
10941117
data_len,
10951118
&td->t_infomask,
1119+
&td->t_infomask2,
10961120
(hasnull ? td->t_bits : NULL));
10971121

10981122
return tuple;
@@ -1415,6 +1439,7 @@ heap_form_minimal_tuple(TupleDesc tupleDescriptor,
14151439
(char *) tuple + hoff,
14161440
data_len,
14171441
&tuple->t_infomask,
1442+
&tuple->t_infomask2,
14181443
(hasnull ? tuple->t_bits : NULL));
14191444

14201445
return tuple;

src/backend/access/common/indextuple.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ index_form_tuple(TupleDesc tupleDescriptor,
5050
unsigned short infomask = 0;
5151
bool hasnull = false;
5252
uint16 tupmask = 0;
53+
uint16 tupmask2 = 0;
5354
int numberOfAttributes = tupleDescriptor->natts;
5455

5556
#ifdef TOAST_INDEX_HACK
@@ -162,6 +163,7 @@ index_form_tuple(TupleDesc tupleDescriptor,
162163
(char *) tp + hoff,
163164
data_size,
164165
&tupmask,
166+
&tupmask2,
165167
(hasnull ? (bits8 *) tp + sizeof(IndexTupleData) : NULL));
166168

167169
#ifdef TOAST_INDEX_HACK

src/backend/access/common/tupdesc.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "postgres.h"
2121

2222
#include "access/htup_details.h"
23+
#include "access/reloptions.h"
2324
#include "access/tupdesc_details.h"
2425
#include "catalog/pg_collation.h"
2526
#include "catalog/pg_type.h"
@@ -72,6 +73,7 @@ CreateTemplateTupleDesc(int natts)
7273
desc->constr = NULL;
7374
desc->tdtypeid = RECORDOID;
7475
desc->tdtypmod = -1;
76+
desc->tdflags = 0;
7577
desc->tdrefcount = -1; /* assume not reference-counted */
7678

7779
return desc;
@@ -94,8 +96,17 @@ CreateTupleDesc(int natts, Form_pg_attribute *attrs)
9496
desc = CreateTemplateTupleDesc(natts);
9597

9698
for (i = 0; i < natts; ++i)
99+
{
97100
memcpy(TupleDescAttr(desc, i), attrs[i], ATTRIBUTE_FIXED_PART_SIZE);
98101

102+
/*
103+
* If even one of attributes is compressed we save information about
104+
* it to TupleDesc flags
105+
*/
106+
if (OidIsValid(attrs[i]->attcompression))
107+
desc->tdflags |= TD_ATTR_CUSTOM_COMPRESSED;
108+
}
109+
99110
return desc;
100111
}
101112

@@ -137,6 +148,7 @@ CreateTupleDescCopy(TupleDesc tupdesc)
137148
/* We can copy the tuple type identification, too */
138149
desc->tdtypeid = tupdesc->tdtypeid;
139150
desc->tdtypmod = tupdesc->tdtypmod;
151+
desc->tdflags = tupdesc->tdflags;
140152

141153
return desc;
142154
}
@@ -217,6 +229,7 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc)
217229
/* We can copy the tuple type identification, too */
218230
desc->tdtypeid = tupdesc->tdtypeid;
219231
desc->tdtypmod = tupdesc->tdtypmod;
232+
desc->tdflags = tupdesc->tdflags;
220233

221234
return desc;
222235
}
@@ -304,6 +317,7 @@ TupleDescCopyEntry(TupleDesc dst, AttrNumber dstAttno,
304317
dstAtt->atthasmissing = false;
305318
dstAtt->attidentity = '\0';
306319
dstAtt->attgenerated = '\0';
320+
dstAtt->attcompression = InvalidOid;
307321
}
308322

309323
/*
@@ -418,6 +432,8 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
418432
return false;
419433
if (tupdesc1->tdtypeid != tupdesc2->tdtypeid)
420434
return false;
435+
if (tupdesc1->tdflags != tupdesc2->tdflags)
436+
return false;
421437

422438
for (i = 0; i < tupdesc1->natts; i++)
423439
{
@@ -470,6 +486,8 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
470486
return false;
471487
if (attr1->attcollation != attr2->attcollation)
472488
return false;
489+
if (attr1->attcompression != attr2->attcompression)
490+
return false;
473491
/* attacl, attoptions and attfdwoptions are not even present... */
474492
}
475493

@@ -557,6 +575,7 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
557575
}
558576
else if (tupdesc2->constr != NULL)
559577
return false;
578+
560579
return true;
561580
}
562581

@@ -663,6 +682,7 @@ TupleDescInitEntry(TupleDesc desc,
663682
att->attalign = typeForm->typalign;
664683
att->attstorage = typeForm->typstorage;
665684
att->attcollation = typeForm->typcollation;
685+
att->attcompression = InvalidOid;
666686

667687
ReleaseSysCache(tuple);
668688
}

src/backend/access/heap/heapam.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171

7272

7373
static HeapTuple heap_prepare_insert(Relation relation, HeapTuple tup,
74-
TransactionId xid, CommandId cid, int options);
74+
TransactionId xid, CommandId cid, int options, BulkInsertState bistate);
7575
static XLogRecPtr log_heap_update(Relation reln, Buffer oldbuf,
7676
Buffer newbuf, HeapTuple oldtup,
7777
HeapTuple newtup, HeapTuple old_key_tup,
@@ -1817,13 +1817,14 @@ UpdateXmaxHintBits(HeapTupleHeader tuple, Buffer buffer, TransactionId xid)
18171817
* GetBulkInsertState - prepare status object for a bulk insert
18181818
*/
18191819
BulkInsertState
1820-
GetBulkInsertState(void)
1820+
GetBulkInsertState(HTAB *preserved_am_info)
18211821
{
18221822
BulkInsertState bistate;
18231823

18241824
bistate = (BulkInsertState) palloc(sizeof(BulkInsertStateData));
18251825
bistate->strategy = GetAccessStrategy(BAS_BULKWRITE);
18261826
bistate->current_buf = InvalidBuffer;
1827+
bistate->preserved_am_info = preserved_am_info;
18271828
return bistate;
18281829
}
18291830

@@ -1885,7 +1886,7 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid,
18851886
* Note: below this point, heaptup is the data we actually intend to store
18861887
* into the relation; tup is the caller's original untoasted data.
18871888
*/
1888-
heaptup = heap_prepare_insert(relation, tup, xid, cid, options);
1889+
heaptup = heap_prepare_insert(relation, tup, xid, cid, options, bistate);
18891890

18901891
/*
18911892
* Find buffer to insert this tuple into. If the page is all visible,
@@ -2052,7 +2053,7 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid,
20522053
*/
20532054
static HeapTuple
20542055
heap_prepare_insert(Relation relation, HeapTuple tup, TransactionId xid,
2055-
CommandId cid, int options)
2056+
CommandId cid, int options, BulkInsertState bistate)
20562057
{
20572058
/*
20582059
* Parallel operations are required to be strictly read-only in a parallel
@@ -2090,8 +2091,11 @@ heap_prepare_insert(Relation relation, HeapTuple tup, TransactionId xid,
20902091
return tup;
20912092
}
20922093
else if (HeapTupleHasExternal(tup)
2094+
|| RelationGetDescr(relation)->tdflags & TD_ATTR_CUSTOM_COMPRESSED
2095+
|| HeapTupleHasCustomCompressed(tup)
20932096
|| tup->t_len > TOAST_TUPLE_THRESHOLD)
2094-
return toast_insert_or_update(relation, tup, NULL, options, NULL);
2097+
return toast_insert_or_update(relation, tup, NULL, options,
2098+
bistate ? bistate->preserved_am_info : NULL);
20952099
else
20962100
return tup;
20972101
}
@@ -2139,7 +2143,7 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples,
21392143
slots[i]->tts_tableOid = RelationGetRelid(relation);
21402144
tuple->t_tableOid = slots[i]->tts_tableOid;
21412145
heaptuples[i] = heap_prepare_insert(relation, tuple, xid, cid,
2142-
options);
2146+
options, bistate);
21432147
}
21442148

21452149
/*
@@ -3407,6 +3411,8 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
34073411
else
34083412
need_toast = (HeapTupleHasExternal(&oldtup) ||
34093413
HeapTupleHasExternal(newtup) ||
3414+
RelationGetDescr(relation)->tdflags & TD_ATTR_CUSTOM_COMPRESSED ||
3415+
HeapTupleHasCustomCompressed(newtup) ||
34103416
newtup->t_len > TOAST_TUPLE_THRESHOLD);
34113417

34123418
pagefree = PageGetHeapFreeSpace(page);

src/backend/access/heap/tuptoaster.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,6 +1195,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
11951195
(char *) new_data + new_header_len,
11961196
new_data_len,
11971197
&(new_data->t_infomask),
1198+
&(new_data->t_infomask2),
11981199
has_nulls ? new_data->t_bits : NULL);
11991200
}
12001201
else
@@ -1416,6 +1417,7 @@ toast_flatten_tuple_to_datum(HeapTupleHeader tup,
14161417
(char *) new_data + new_header_len,
14171418
new_data_len,
14181419
&(new_data->t_infomask),
1420+
&(new_data->t_infomask2),
14191421
has_nulls ? new_data->t_bits : NULL);
14201422

14211423
/*

src/backend/commands/copy.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2992,6 +2992,7 @@ CopyFrom(CopyState cstate)
29922992
*/
29932993
ExecBSInsertTriggers(estate, resultRelInfo);
29942994

2995+
bistate = GetBulkInsertState(NULL);
29952996
econtext = GetPerTupleExprContext(estate);
29962997

29972998
/* Set up callback to identify error line number */

src/backend/commands/createas.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
560560
*/
561561
myState->ti_options = TABLE_INSERT_SKIP_FSM |
562562
(XLogIsNeeded() ? 0 : TABLE_INSERT_SKIP_WAL);
563-
myState->bistate = GetBulkInsertState();
563+
myState->bistate = GetBulkInsertState(NULL);
564564

565565
/* Not using WAL requires smgr_targblock be initially invalid */
566566
Assert(RelationGetTargetBlock(intoRelationDesc) == InvalidBlockNumber);

src/backend/commands/matview.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ transientrel_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
465465
myState->ti_options = TABLE_INSERT_SKIP_FSM | TABLE_INSERT_FROZEN;
466466
if (!XLogIsNeeded())
467467
myState->ti_options |= TABLE_INSERT_SKIP_WAL;
468-
myState->bistate = GetBulkInsertState();
468+
myState->bistate = GetBulkInsertState(NULL);
469469

470470
/* Not using WAL requires smgr_targblock be initially invalid */
471471
Assert(RelationGetTargetBlock(transientrel) == InvalidBlockNumber);

0 commit comments

Comments
 (0)