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

Commit 1637684

Browse files
committed
Cleanup getattr code. Make CHAR() use attcacheoff.
1 parent 60f54d6 commit 1637684

File tree

3 files changed

+158
-108
lines changed

3 files changed

+158
-108
lines changed

src/backend/access/common/heaptuple.c

Lines changed: 91 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*-------------------------------------------------------------------------
1+
/*-------------------------------------------------------------------------
22
*
33
* heaptuple.c--
44
* This file contains heap tuple accessor and mutator routines, as well
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.31 1998/01/31 04:38:02 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.32 1998/02/04 21:32:08 momjian Exp $
1212
*
1313
* NOTES
1414
* The old interface functions have been converted to macros
@@ -23,6 +23,7 @@
2323
#include <access/htup.h>
2424
#include <access/transam.h>
2525
#include <access/tupmacs.h>
26+
#include <catalog/pg_type.h>
2627
#include <storage/bufpage.h>
2728
#include <utils/memutils.h>
2829

@@ -435,16 +436,13 @@ nocachegetattr(HeapTuple tup,
435436
}
436437
else if (attnum == 0)
437438
{
438-
439439
/*
440440
* first attribute is always at position zero
441441
*/
442442
return ((Datum) fetchatt(&(att[0]), (char *) tup + tup->t_hoff));
443443
}
444444
#endif
445445

446-
tp = (char *) tup + tup->t_hoff;
447-
448446
slow = 0;
449447
}
450448
else
@@ -478,40 +476,58 @@ nocachegetattr(HeapTuple tup,
478476
* Now check to see if any preceeding bits are null...
479477
* ----------------
480478
*/
481-
482479
{
483480
register int i = 0; /* current offset in bp */
481+
register int mask; /* bit in byte we're looking at */
482+
register char n; /* current byte in bp */
483+
register int byte,
484+
finalbit;
484485

485-
for (i = 0; i < attnum && !slow; i++)
486+
byte = attnum >> 3;
487+
finalbit = attnum & 0x07;
488+
489+
for (; i <= byte && !slow; i++)
486490
{
487-
if (att_isnull(i, bp))
488-
slow = 1;
491+
n = bp[i];
492+
if (i < byte)
493+
{
494+
/* check for nulls in any "earlier" bytes */
495+
if ((~n) != 0)
496+
slow=1;
497+
}
498+
else
499+
{
500+
/* check for nulls "before" final bit of last byte */
501+
mask = (1 << finalbit) - 1;
502+
if ((~n) & mask)
503+
slow=1;
504+
}
489505
}
490506
}
491507
}
492508

509+
tp = (char *) tup + tup->t_hoff;
510+
493511
/*
494512
* now check for any non-fixed length attrs before our attribute
495513
*/
496514
if (!slow)
497515
{
498516
if (att[attnum]->attcacheoff > 0)
499517
{
500-
return (Datum)
501-
fetchatt(&(att[attnum]),
502-
tp + att[attnum]->attcacheoff);
518+
return (Datum)fetchatt(&(att[attnum]),
519+
tp + att[attnum]->attcacheoff);
503520
}
504521
else if (attnum == 0)
505522
{
506-
return (Datum)
507-
fetchatt(&(att[0]), (char *) tup + tup->t_hoff);
523+
return ((Datum) fetchatt(&(att[0]), (char *) tp));
508524
}
509525
else if (!HeapTupleAllFixed(tup))
510526
{
511527
register int j = 0;
512528

513529
for (j = 0; j < attnum && !slow; j++)
514-
if (att[j]->attlen < 1)
530+
if (att[j]->attlen < 1 && !VARLENA_FIXED_SIZE(att[j]))
515531
slow = 1;
516532
}
517533
}
@@ -535,10 +551,18 @@ nocachegetattr(HeapTuple tup,
535551
while (att[j]->attcacheoff > 0)
536552
j++;
537553

538-
off = att[j - 1]->attcacheoff + att[j - 1]->attlen;
554+
if (!VARLENA_FIXED_SIZE(att[j]))
555+
off = att[j - 1]->attcacheoff + att[j - 1]->attlen;
556+
else
557+
off = att[j - 1]->attcacheoff + att[j - 1]->atttypmod;
539558

540559
for (; j < attnum + 1; j++)
541560
{
561+
/*
562+
* Fix me when going to a machine with more than a four-byte
563+
* word!
564+
*/
565+
542566
switch (att[j]->attlen)
543567
{
544568
case -1:
@@ -554,25 +578,28 @@ nocachegetattr(HeapTuple tup,
554578
off = INTALIGN(off);
555579
break;
556580
default:
557-
if (att[j]->attlen < sizeof(int32))
558-
{
559-
elog(ERROR,
560-
"nocachegetattr: attribute %d has len %d",
561-
j, att[j]->attlen);
562-
}
563-
if (att[j]->attalign == 'd')
564-
off = DOUBLEALIGN(off);
581+
if (att[j]->attlen > sizeof(int32))
582+
off = (att[j]->attalign == 'd') ?
583+
DOUBLEALIGN(off) : LONGALIGN(off);
565584
else
566-
off = LONGALIGN(off);
585+
elog(ERROR, "nocache_index_getattr: attribute %d has len %d",
586+
j, att[j]->attlen);
567587
break;
568588
}
569589

570590
att[j]->attcacheoff = off;
571-
off += att[j]->attlen;
591+
592+
/* The only varlena/-1 length value to get here is this */
593+
if (!VARLENA_FIXED_SIZE(att[j]))
594+
off += att[j]->attlen;
595+
else
596+
{
597+
Assert(att[j]->atttypmod == VARSIZE(tp + off));
598+
off += att[j]->atttypmod;
599+
}
572600
}
573601

574-
return
575-
(Datum) fetchatt(&(att[attnum]), tp + att[attnum]->attcacheoff);
602+
return (Datum) fetchatt(&(att[attnum]), tp + att[attnum]->attcacheoff);
576603
}
577604
else
578605
{
@@ -600,41 +627,37 @@ nocachegetattr(HeapTuple tup,
600627
continue;
601628
}
602629
}
603-
switch (att[i]->attlen)
604-
{
605-
case -1:
606-
off = (att[i]->attalign == 'd') ?
607-
DOUBLEALIGN(off) : INTALIGN(off);
608-
break;
609-
case sizeof(char):
610-
break;
611-
case sizeof(short):
612-
off = SHORTALIGN(off);
613-
break;
614-
case sizeof(int32):
615-
off = INTALIGN(off);
616-
break;
617-
default:
618-
if (att[i]->attlen < sizeof(int32))
619-
elog(ERROR,
620-
"nocachegetattr2: attribute %d has len %d",
621-
i, att[i]->attlen);
622-
if (att[i]->attalign == 'd')
623-
off = DOUBLEALIGN(off);
624-
else
625-
off = LONGALIGN(off);
626-
break;
627-
}
630+
631+
/* If we know the next offset, we can skip the rest */
628632
if (usecache && att[i]->attcacheoff > 0)
629-
{
630633
off = att[i]->attcacheoff;
631-
if (att[i]->attlen == -1)
632-
{
633-
usecache = false;
634-
}
635-
}
636634
else
637635
{
636+
switch (att[i]->attlen)
637+
{
638+
case -1:
639+
off = (att[i]->attalign == 'd') ?
640+
DOUBLEALIGN(off) : INTALIGN(off);
641+
break;
642+
case sizeof(char):
643+
break;
644+
case sizeof(short):
645+
off = SHORTALIGN(off);
646+
break;
647+
case sizeof(int32):
648+
off = INTALIGN(off);
649+
break;
650+
default:
651+
if (att[i]->attlen < sizeof(int32))
652+
elog(ERROR,
653+
"nocachegetattr2: attribute %d has len %d",
654+
i, att[i]->attlen);
655+
if (att[i]->attalign == 'd')
656+
off = DOUBLEALIGN(off);
657+
else
658+
off = LONGALIGN(off);
659+
break;
660+
}
638661
if (usecache)
639662
att[i]->attcacheoff = off;
640663
}
@@ -644,21 +667,25 @@ nocachegetattr(HeapTuple tup,
644667
case sizeof(char):
645668
off++;
646669
break;
647-
case sizeof(int16):
648-
off += sizeof(int16);
670+
case sizeof(short):
671+
off += sizeof(short);
649672
break;
650673
case sizeof(int32):
651674
off += sizeof(int32);
652675
break;
653676
case -1:
654-
usecache = false;
677+
Assert(!VARLENA_FIXED_SIZE(att[i]) ||
678+
att[i]->atttypmod == VARSIZE(tp + off));
655679
off += VARSIZE(tp + off);
680+
if (!VARLENA_FIXED_SIZE(att[i]))
681+
usecache = false;
656682
break;
657683
default:
658684
off += att[i]->attlen;
659685
break;
660686
}
661687
}
688+
662689
switch (att[attnum]->attlen)
663690
{
664691
case -1:
@@ -683,7 +710,8 @@ nocachegetattr(HeapTuple tup,
683710
off = LONGALIGN(off);
684711
break;
685712
}
686-
return ((Datum) fetchatt(&(att[attnum]), tp + off));
713+
714+
return (Datum) fetchatt(&(att[attnum]), tp + off);
687715
}
688716
}
689717

0 commit comments

Comments
 (0)