Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1f5cc8c

Browse files
committed
Remove VARLENA_FIXED_SIZE hack, which is irreversibly broken now that
both MULTIBYTE and TOAST prevent char(n) from being truly fixed-size. Simplify and speed up fastgetattr() and index_getattr() macros by eliminating special cases for attnum=1. It's just as fast to handle the first attribute by presetting its attcacheoff to zero; so do that instead when loading the tupledesc in relcache.c.
1 parent 59a9735 commit 1f5cc8c

File tree

7 files changed

+122
-151
lines changed

7 files changed

+122
-151
lines changed

src/backend/access/common/heaptuple.c

Lines changed: 14 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.66 2000/11/14 21:04:32 tgl Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.67 2000/11/30 18:38:45 tgl Exp $
1313
*
1414
* NOTES
1515
* The old interface functions have been converted to macros
@@ -300,11 +300,11 @@ nocachegetattr(HeapTuple tuple,
300300
TupleDesc tupleDesc,
301301
bool *isnull)
302302
{
303-
char *tp; /* ptr to att in tuple */
304303
HeapTupleHeader tup = tuple->t_data;
305-
bits8 *bp = tup->t_bits; /* ptr to att in tuple */
306304
Form_pg_attribute *att = tupleDesc->attrs;
307-
int slow = 0; /* do we have to walk nulls? */
305+
char *tp; /* ptr to att in tuple */
306+
bits8 *bp = tup->t_bits; /* ptr to null bitmask in tuple */
307+
bool slow = false; /* do we have to walk nulls? */
308308

309309
(void) isnull; /* not used */
310310
#ifdef IN_MACRO
@@ -336,14 +336,6 @@ nocachegetattr(HeapTuple tuple,
336336
fetchatt(&(att[attnum]),
337337
(char *) tup + tup->t_hoff + att[attnum]->attcacheoff);
338338
}
339-
else if (attnum == 0)
340-
{
341-
342-
/*
343-
* first attribute is always at position zero
344-
*/
345-
return (Datum) fetchatt(&(att[0]), (char *) tup + tup->t_hoff);
346-
}
347339
#endif
348340
}
349341
else
@@ -378,7 +370,7 @@ nocachegetattr(HeapTuple tuple,
378370

379371
/* check for nulls "before" final bit of last byte */
380372
if ((~bp[byte]) & ((1 << finalbit) - 1))
381-
slow = 1;
373+
slow = true;
382374
else
383375
{
384376
/* check for nulls in any "earlier" bytes */
@@ -388,7 +380,7 @@ nocachegetattr(HeapTuple tuple,
388380
{
389381
if (bp[i] != 0xFF)
390382
{
391-
slow = 1;
383+
slow = true;
392384
break;
393385
}
394386
}
@@ -408,29 +400,27 @@ nocachegetattr(HeapTuple tuple,
408400
return (Datum) fetchatt(&(att[attnum]),
409401
tp + att[attnum]->attcacheoff);
410402
}
411-
else if (attnum == 0)
412-
return (Datum) fetchatt(&(att[0]), tp);
413403
else if (!HeapTupleAllFixed(tuple))
414404
{
415405
int j;
416406

417407
/*
418-
* In for(), we make this <= and not < because we want to test
408+
* In for(), we test <= and not < because we want to see
419409
* if we can go past it in initializing offsets.
420410
*/
421411
for (j = 0; j <= attnum; j++)
422412
{
423-
if (att[j]->attlen < 1 && !VARLENA_FIXED_SIZE(att[j]))
413+
if (att[j]->attlen <= 0)
424414
{
425-
slow = 1;
415+
slow = true;
426416
break;
427417
}
428418
}
429419
}
430420
}
431421

432422
/*
433-
* If slow is zero, and we got here, we know that we have a tuple with
423+
* If slow is false, and we got here, we know that we have a tuple with
434424
* no nulls or varlenas before the target attribute. If possible, we
435425
* also want to initialize the remainder of the attribute cached
436426
* offset values.
@@ -446,21 +436,17 @@ nocachegetattr(HeapTuple tuple,
446436

447437
att[0]->attcacheoff = 0;
448438

449-
while (att[j]->attcacheoff > 0)
439+
while (j < attnum && att[j]->attcacheoff > 0)
450440
j++;
451441

452-
if (!VARLENA_FIXED_SIZE(att[j - 1]))
453-
off = att[j - 1]->attcacheoff + att[j - 1]->attlen;
454-
else
455-
off = att[j - 1]->attcacheoff + att[j - 1]->atttypmod;
442+
off = att[j - 1]->attcacheoff + att[j - 1]->attlen;
456443

457444
for (; j <= attnum ||
458445
/* Can we compute more? We will probably need them */
459446
(j < tup->t_natts &&
460447
att[j]->attcacheoff == -1 &&
461448
(HeapTupleNoNulls(tuple) || !att_isnull(j, bp)) &&
462-
(HeapTupleAllFixed(tuple) ||
463-
att[j]->attlen > 0 || VARLENA_FIXED_SIZE(att[j]))); j++)
449+
(HeapTupleAllFixed(tuple) || att[j]->attlen > 0)); j++)
464450
{
465451

466452
/*
@@ -516,8 +502,7 @@ nocachegetattr(HeapTuple tuple,
516502

517503
off = att_addlength(off, att[i]->attlen, tp + off);
518504

519-
if (usecache &&
520-
att[i]->attlen == -1 && !VARLENA_FIXED_SIZE(att[i]))
505+
if (usecache && att[i]->attlen == -1)
521506
usecache = false;
522507
}
523508

src/backend/access/common/indextuple.c

Lines changed: 47 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/access/common/indextuple.c,v 1.46 2000/11/16 05:50:57 momjian Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/access/common/indextuple.c,v 1.47 2000/11/30 18:38:45 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -160,13 +160,13 @@ index_formtuple(TupleDesc tupleDescriptor,
160160
*
161161
* This caches attribute offsets in the attribute descriptor.
162162
*
163-
* an alternate way to speed things up would be to cache offsets
163+
* An alternate way to speed things up would be to cache offsets
164164
* with the tuple, but that seems more difficult unless you take
165165
* the storage hit of actually putting those offsets into the
166166
* tuple you send to disk. Yuck.
167167
*
168168
* This scheme will be slightly slower than that, but should
169-
* preform well for queries which hit large #'s of tuples. After
169+
* perform well for queries which hit large #'s of tuples. After
170170
* you cache the offsets once, examining all the other tuples using
171171
* the same attribute descriptor will go much quicker. -cim 5/4/91
172172
* ----------------
@@ -177,13 +177,13 @@ nocache_index_getattr(IndexTuple tup,
177177
TupleDesc tupleDesc,
178178
bool *isnull)
179179
{
180+
Form_pg_attribute *att = tupleDesc->attrs;
180181
char *tp; /* ptr to att in tuple */
181-
char *bp = NULL; /* ptr to att in tuple */
182-
int slow; /* do we have to walk nulls? */
182+
bits8 *bp = NULL; /* ptr to null bitmask in tuple */
183+
bool slow = false; /* do we have to walk nulls? */
183184
int data_off; /* tuple data offset */
184-
Form_pg_attribute *att = tupleDesc->attrs;
185185

186-
(void) isnull;
186+
(void) isnull; /* not used */
187187
/* ----------------
188188
* sanity checks
189189
* ----------------
@@ -209,38 +209,26 @@ nocache_index_getattr(IndexTuple tup,
209209
data_off = IndexTupleHasMinHeader(tup) ? sizeof *tup :
210210
IndexInfoFindDataOffset(tup->t_info);
211211

212+
attnum--;
213+
212214
if (IndexTupleNoNulls(tup))
213215
{
214-
attnum--;
215-
216216
#ifdef IN_MACRO
217217
/* This is handled in the macro */
218-
219-
/* first attribute is always at position zero */
220-
221-
if (attnum == 1)
222-
return (Datum) fetchatt(&(att[0]), (char *) tup + data_off);
223218
if (att[attnum]->attcacheoff != -1)
224219
{
225220
return (Datum) fetchatt(&(att[attnum]),
226221
(char *) tup + data_off +
227222
att[attnum]->attcacheoff);
228223
}
229224
#endif
230-
231-
slow = 0;
232225
}
233226
else
234227
{ /* there's a null somewhere in the tuple */
235-
236-
slow = 0;
237228
/* ----------------
238229
* check to see if desired att is null
239230
* ----------------
240231
*/
241-
242-
attnum--;
243-
244232
bp = (char *) tup + sizeof(*tup); /* "knows" t_bits are
245233
* here! */
246234
#ifdef IN_MACRO
@@ -254,34 +242,28 @@ nocache_index_getattr(IndexTuple tup,
254242
#endif
255243

256244
/* ----------------
257-
* Now check to see if any preceeding bits are null...
245+
* Now check to see if any preceding bits are null...
258246
* ----------------
259247
*/
260248
{
261-
int i = 0; /* current offset in bp */
262-
int mask; /* bit in byte we're looking at */
263-
char n; /* current byte in bp */
264-
int byte,
265-
finalbit;
249+
int byte = attnum >> 3;
250+
int finalbit = attnum & 0x07;
266251

267-
byte = attnum >> 3;
268-
finalbit = attnum & 0x07;
269-
270-
for (; i <= byte && !slow; i++)
252+
/* check for nulls "before" final bit of last byte */
253+
if ((~bp[byte]) & ((1 << finalbit) - 1))
254+
slow = true;
255+
else
271256
{
272-
n = bp[i];
273-
if (i < byte)
274-
{
275-
/* check for nulls in any "earlier" bytes */
276-
if ((~n) != 0)
277-
slow = 1;
278-
}
279-
else
257+
/* check for nulls in any "earlier" bytes */
258+
int i;
259+
260+
for (i = 0; i < byte; i++)
280261
{
281-
/* check for nulls "before" final bit of last byte */
282-
mask = (1 << finalbit) - 1;
283-
if ((~n) & mask)
284-
slow = 1;
262+
if (bp[i] != 0xFF)
263+
{
264+
slow = true;
265+
break;
266+
}
285267
}
286268
}
287269
}
@@ -298,24 +280,25 @@ nocache_index_getattr(IndexTuple tup,
298280
return (Datum) fetchatt(&(att[attnum]),
299281
tp + att[attnum]->attcacheoff);
300282
}
301-
else if (attnum == 0)
302-
return (Datum) fetchatt(&(att[0]), (char *) tp);
303283
else if (!IndexTupleAllFixed(tup))
304284
{
305-
int j = 0;
285+
int j;
306286

307-
for (j = 0; j < attnum && !slow; j++)
308-
if (att[j]->attlen < 1 && !VARLENA_FIXED_SIZE(att[j]))
309-
slow = 1;
287+
for (j = 0; j < attnum; j++)
288+
if (att[j]->attlen <= 0)
289+
{
290+
slow = true;
291+
break;
292+
}
310293
}
311294
}
312295

313296
/*
314-
* if slow is zero, and we got here, we know that we have a tuple with
315-
* no nulls. We also know that we have to initialize the remainder of
316-
* the attribute cached offset values.
297+
* If slow is false, and we got here, we know that we have a tuple with
298+
* no nulls or varlenas before the target attribute. If possible, we
299+
* also want to initialize the remainder of the attribute cached
300+
* offset values.
317301
*/
318-
319302
if (!slow)
320303
{
321304
int j = 1;
@@ -327,15 +310,12 @@ nocache_index_getattr(IndexTuple tup,
327310

328311
att[0]->attcacheoff = 0;
329312

330-
while (att[j]->attcacheoff != -1)
313+
while (j < attnum && att[j]->attcacheoff > 0)
331314
j++;
332315

333-
if (!VARLENA_FIXED_SIZE(att[j - 1]))
334-
off = att[j - 1]->attcacheoff + att[j - 1]->attlen;
335-
else
336-
off = att[j - 1]->attcacheoff + att[j - 1]->atttypmod;
316+
off = att[j - 1]->attcacheoff + att[j - 1]->attlen;
337317

338-
for (; j < attnum + 1; j++)
318+
for (; j <= attnum; j++)
339319
{
340320

341321
/*
@@ -347,14 +327,7 @@ nocache_index_getattr(IndexTuple tup,
347327

348328
att[j]->attcacheoff = off;
349329

350-
/* The only varlena/-1 length value to get here is this */
351-
if (!VARLENA_FIXED_SIZE(att[j]))
352-
off += att[j]->attlen;
353-
else
354-
{
355-
Assert(att[j]->atttypmod == VARSIZE(tp + off));
356-
off += att[j]->atttypmod;
357-
}
330+
off += att[j]->attlen;
358331
}
359332

360333
return (Datum) fetchatt(&(att[attnum]), tp + att[attnum]->attcacheoff);
@@ -391,27 +364,14 @@ nocache_index_getattr(IndexTuple tup,
391364
att[i]->attcacheoff = off;
392365
}
393366

394-
switch (att[i]->attlen)
367+
if (att[i]->attlen == -1)
395368
{
396-
case sizeof(char):
397-
off++;
398-
break;
399-
case sizeof(short):
400-
off += sizeof(short);
401-
break;
402-
case sizeof(int32):
403-
off += sizeof(int32);
404-
break;
405-
case -1:
406-
Assert(!VARLENA_FIXED_SIZE(att[i]) ||
407-
att[i]->atttypmod == VARSIZE(tp + off));
408-
off += VARSIZE(tp + off);
409-
if (!VARLENA_FIXED_SIZE(att[i]))
410-
usecache = false;
411-
break;
412-
default:
413-
off += att[i]->attlen;
414-
break;
369+
off += VARSIZE(tp + off);
370+
usecache = false;
371+
}
372+
else
373+
{
374+
off += att[i]->attlen;
415375
}
416376
}
417377

src/backend/access/heap/heapam.c

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.97 2000/11/30 08:46:20 vadim Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.98 2000/11/30 18:38:45 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -535,18 +535,11 @@ fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
535535
((isnull) ? (*(isnull) = false) : (dummyret) NULL),
536536
HeapTupleNoNulls(tup) ?
537537
(
538-
((tupleDesc)->attrs[(attnum) - 1]->attcacheoff != -1 ||
539-
(attnum) == 1) ?
538+
(tupleDesc)->attrs[(attnum) - 1]->attcacheoff >= 0 ?
540539
(
541540
(Datum) fetchatt(&((tupleDesc)->attrs[(attnum) - 1]),
542541
(char *) (tup)->t_data + (tup)->t_data->t_hoff +
543-
(
544-
((attnum) != 1) ?
545-
(tupleDesc)->attrs[(attnum) - 1]->attcacheoff
546-
:
547-
0
548-
)
549-
)
542+
(tupleDesc)->attrs[(attnum) - 1]->attcacheoff)
550543
)
551544
:
552545
nocachegetattr((tup), (attnum), (tupleDesc), (isnull))

0 commit comments

Comments
 (0)