OSDN Git Service

Cleanup getattr code. Make CHAR() use attcacheoff.
authorBruce Momjian <bruce@momjian.us>
Wed, 4 Feb 1998 21:32:12 +0000 (21:32 +0000)
committerBruce Momjian <bruce@momjian.us>
Wed, 4 Feb 1998 21:32:12 +0000 (21:32 +0000)
src/backend/access/common/heaptuple.c
src/backend/access/common/indextuple.c
src/include/catalog/pg_type.h

index a1ce78f..9791d75 100644 (file)
@@ -1,4 +1,4 @@
- /*-------------------------------------------------------------------------
+/*-------------------------------------------------------------------------
  *
  * heaptuple.c--
  *       This file contains heap tuple accessor and mutator routines, as well
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.31 1998/01/31 04:38:02 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.32 1998/02/04 21:32:08 momjian Exp $
  *
  * NOTES
  *       The old interface functions have been converted to macros
@@ -23,6 +23,7 @@
 #include <access/htup.h>
 #include <access/transam.h>
 #include <access/tupmacs.h>
+#include <catalog/pg_type.h>
 #include <storage/bufpage.h>
 #include <utils/memutils.h>
 
@@ -435,7 +436,6 @@ nocachegetattr(HeapTuple tup,
                }
                else if (attnum == 0)
                {
-
                        /*
                         * first attribute is always at position zero
                         */
@@ -443,8 +443,6 @@ nocachegetattr(HeapTuple tup,
                }
 #endif
 
-               tp = (char *) tup + tup->t_hoff;
-
                slow = 0;
        }
        else
@@ -478,18 +476,38 @@ nocachegetattr(HeapTuple tup,
                 *              Now check to see if any preceeding bits are null...
                 * ----------------
                 */
-
                {
                        register int i = 0; /* current offset in bp */
+                       register int mask;      /* bit in byte we're looking at */
+                       register char n;        /* current byte in bp */
+                       register int byte,
+                                                finalbit;
 
-                       for (i = 0; i < attnum && !slow; i++)
+                       byte = attnum >> 3;
+                       finalbit = attnum & 0x07;
+
+                       for (; i <= byte && !slow; i++)
                        {
-                               if (att_isnull(i, bp))
-                                       slow = 1;
+                               n = bp[i];
+                               if (i < byte)
+                               {
+                                       /* check for nulls in any "earlier" bytes */
+                                       if ((~n) != 0)
+                                               slow=1;
+                               }
+                               else
+                               {
+                                       /* check for nulls "before" final bit of last byte */
+                                       mask = (1 << finalbit) - 1;
+                                       if ((~n) & mask)
+                                               slow=1;
+                               }
                        }
                }
        }
 
+       tp = (char *) tup + tup->t_hoff;
+
        /*
         * now check for any non-fixed length attrs before our attribute
         */
@@ -497,21 +515,19 @@ nocachegetattr(HeapTuple tup,
        {
                if (att[attnum]->attcacheoff > 0)
                {
-                       return (Datum)
-                               fetchatt(&(att[attnum]),
-                                                tp + att[attnum]->attcacheoff);
+                       return (Datum)fetchatt(&(att[attnum]),
+                                               tp + att[attnum]->attcacheoff);
                }
                else if (attnum == 0)
                {
-                       return (Datum)
-                               fetchatt(&(att[0]), (char *) tup + tup->t_hoff);
+                       return ((Datum) fetchatt(&(att[0]), (char *) tp));
                }
                else if (!HeapTupleAllFixed(tup))
                {
                        register int j = 0;
 
                        for (j = 0; j < attnum && !slow; j++)
-                               if (att[j]->attlen < 1)
+                               if (att[j]->attlen < 1 && !VARLENA_FIXED_SIZE(att[j]))
                                        slow = 1;
                }
        }
@@ -535,10 +551,18 @@ nocachegetattr(HeapTuple tup,
                while (att[j]->attcacheoff > 0)
                        j++;
 
-               off = att[j - 1]->attcacheoff + att[j - 1]->attlen;
+               if (!VARLENA_FIXED_SIZE(att[j]))
+                       off = att[j - 1]->attcacheoff + att[j - 1]->attlen;
+               else
+                       off = att[j - 1]->attcacheoff + att[j - 1]->atttypmod;
 
                for (; j < attnum + 1; j++)
                {
+                       /*
+                        * Fix me when going to a machine with more than a four-byte
+                        * word!
+                        */
+
                        switch (att[j]->attlen)
                        {
                                case -1:
@@ -554,25 +578,28 @@ nocachegetattr(HeapTuple tup,
                                        off = INTALIGN(off);
                                        break;
                                default:
-                                       if (att[j]->attlen < sizeof(int32))
-                                       {
-                                               elog(ERROR,
-                                                        "nocachegetattr: attribute %d has len %d",
-                                                        j, att[j]->attlen);
-                                       }
-                                       if (att[j]->attalign == 'd')
-                                               off = DOUBLEALIGN(off);
+                                       if (att[j]->attlen > sizeof(int32))
+                                               off = (att[j]->attalign == 'd') ?
+                                                       DOUBLEALIGN(off) : LONGALIGN(off);
                                        else
-                                               off = LONGALIGN(off);
+                                               elog(ERROR, "nocache_index_getattr: attribute %d has len %d",
+                                                        j, att[j]->attlen);
                                        break;
                        }
 
                        att[j]->attcacheoff = off;
-                       off += att[j]->attlen;
+
+                       /* The only varlena/-1 length value to get here is this */
+                       if (!VARLENA_FIXED_SIZE(att[j]))
+                               off += att[j]->attlen;
+                       else
+                       {
+                               Assert(att[j]->atttypmod == VARSIZE(tp + off));
+                               off += att[j]->atttypmod;
+                       }
                }
 
-               return
-                       (Datum) fetchatt(&(att[attnum]), tp + att[attnum]->attcacheoff);
+               return (Datum) fetchatt(&(att[attnum]), tp + att[attnum]->attcacheoff);
        }
        else
        {
@@ -600,41 +627,37 @@ nocachegetattr(HeapTuple tup,
                                        continue;
                                }
                        }
-                       switch (att[i]->attlen)
-                       {
-                               case -1:
-                                       off = (att[i]->attalign == 'd') ?
-                                               DOUBLEALIGN(off) : INTALIGN(off);
-                                       break;
-                               case sizeof(char):
-                                       break;
-                               case sizeof(short):
-                                       off = SHORTALIGN(off);
-                                       break;
-                               case sizeof(int32):
-                                       off = INTALIGN(off);
-                                       break;
-                               default:
-                                       if (att[i]->attlen < sizeof(int32))
-                                               elog(ERROR,
-                                                        "nocachegetattr2: attribute %d has len %d",
-                                                        i, att[i]->attlen);
-                                       if (att[i]->attalign == 'd')
-                                               off = DOUBLEALIGN(off);
-                                       else
-                                               off = LONGALIGN(off);
-                                       break;
-                       }
+
+                       /* If we know the next offset, we can skip the rest */
                        if (usecache && att[i]->attcacheoff > 0)
-                       {
                                off = att[i]->attcacheoff;
-                               if (att[i]->attlen == -1)
-                               {
-                                       usecache = false;
-                               }
-                       }
                        else
                        {
+                               switch (att[i]->attlen)
+                               {
+                                       case -1:
+                                               off = (att[i]->attalign == 'd') ?
+                                                       DOUBLEALIGN(off) : INTALIGN(off);
+                                               break;
+                                       case sizeof(char):
+                                               break;
+                                       case sizeof(short):
+                                               off = SHORTALIGN(off);
+                                               break;
+                                       case sizeof(int32):
+                                               off = INTALIGN(off);
+                                               break;
+                                       default:
+                                               if (att[i]->attlen < sizeof(int32))
+                                                       elog(ERROR,
+                                                                "nocachegetattr2: attribute %d has len %d",
+                                                                i, att[i]->attlen);
+                                               if (att[i]->attalign == 'd')
+                                                       off = DOUBLEALIGN(off);
+                                               else
+                                                       off = LONGALIGN(off);
+                                               break;
+                               }
                                if (usecache)
                                        att[i]->attcacheoff = off;
                        }
@@ -644,21 +667,25 @@ nocachegetattr(HeapTuple tup,
                                case sizeof(char):
                                        off++;
                                        break;
-                               case sizeof(int16):
-                                       off += sizeof(int16);
+                               case sizeof(short):
+                                       off += sizeof(short);
                                        break;
                                case sizeof(int32):
                                        off += sizeof(int32);
                                        break;
                                case -1:
-                                       usecache = false;
+                                       Assert(!VARLENA_FIXED_SIZE(att[i]) ||
+                                                       att[i]->atttypmod == VARSIZE(tp + off));
                                        off += VARSIZE(tp + off);
+                                       if (!VARLENA_FIXED_SIZE(att[i]))
+                                               usecache = false;
                                        break;
                                default:
                                        off += att[i]->attlen;
                                        break;
                        }
                }
+
                switch (att[attnum]->attlen)
                {
                        case -1:
@@ -683,7 +710,8 @@ nocachegetattr(HeapTuple tup,
                                        off = LONGALIGN(off);
                                break;
                }
-               return ((Datum) fetchatt(&(att[attnum]), tp + off));
+
+               return (Datum) fetchatt(&(att[attnum]), tp + off);
        }
 }
 
index eed1799..5bb18cd 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/access/common/indextuple.c,v 1.23 1998/01/31 04:38:03 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/access/common/indextuple.c,v 1.24 1998/02/04 21:32:09 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -19,6 +19,7 @@
 #include <access/ibit.h>
 #include <access/itup.h>
 #include <access/tupmacs.h>
+#include <catalog/pg_type.h>
 
 #ifndef HAVE_MEMMOVE
 #include <regex/utils.h>
@@ -188,8 +189,6 @@ nocache_index_getattr(IndexTuple tup,
                }
 #endif
 
-               tp = (char *) tup + data_off;
-
                slow = 0;
        }
        else
@@ -224,35 +223,33 @@ nocache_index_getattr(IndexTuple tup,
                        register int mask;      /* bit in byte we're looking at */
                        register char n;        /* current byte in bp */
                        register int byte,
-                                               finalbit;
+                                                finalbit;
 
                        byte = attnum >> 3;
                        finalbit = attnum & 0x07;
 
-                       for (; i <= byte; i++)
+                       for (; i <= byte && !slow; i++)
                        {
                                n = bp[i];
                                if (i < byte)
                                {
                                        /* check for nulls in any "earlier" bytes */
                                        if ((~n) != 0)
-                                       {
-                                               slow++;
-                                               break;
-                                       }
+                                               slow=1;
                                }
                                else
                                {
                                        /* check for nulls "before" final bit of last byte */
-                                       mask = (finalbit << 1) - 1;
+                                       mask = (1 << finalbit) - 1;
                                        if ((~n) & mask)
-                                               slow++;
+                                               slow=1;
                                }
                        }
                }
-               tp = (char *) tup + data_off;
        }
 
+       tp = (char *) tup + data_off;
+
        /* now check for any non-fixed length attrs before our attribute */
 
        if (!slow)
@@ -262,12 +259,16 @@ nocache_index_getattr(IndexTuple tup,
                        return (Datum) fetchatt(&(att[attnum]),
                                                         tp + att[attnum]->attcacheoff);
                }
+               else if (attnum == 0)
+               {
+                       return ((Datum) fetchatt(&(att[0]), (char *) tp));
+               }
                else if (!IndexTupleAllFixed(tup))
                {
                        register int j = 0;
 
                        for (j = 0; j < attnum && !slow; j++)
-                               if (att[j]->attlen < 1)
+                               if (att[j]->attlen < 1 && !VARLENA_FIXED_SIZE(att[j]))
                                        slow = 1;
                }
        }
@@ -292,12 +293,13 @@ nocache_index_getattr(IndexTuple tup,
                while (att[j]->attcacheoff > 0)
                        j++;
 
-               off = att[j - 1]->attcacheoff +
-                       att[j - 1]->attlen;
+               if (!VARLENA_FIXED_SIZE(att[j]))
+                       off = att[j - 1]->attcacheoff + att[j - 1]->attlen;
+               else
+                       off = att[j - 1]->attcacheoff + att[j - 1]->atttypmod;
 
                for (; j < attnum + 1; j++)
                {
-
                        /*
                         * Fix me when going to a machine with more than a four-byte
                         * word!
@@ -329,11 +331,18 @@ nocache_index_getattr(IndexTuple tup,
                        }
 
                        att[j]->attcacheoff = off;
-                       off += att[j]->attlen;
+
+                       /* The only varlena/-1 length value to get here is this */
+                       if (!VARLENA_FIXED_SIZE(att[j]))
+                               off += att[j]->attlen;
+                       else
+                       {
+                               Assert(att[j]->atttypmod == VARSIZE(tp + off));
+                               off += att[j]->atttypmod;
+                       }
                }
 
-               return (Datum) fetchatt(&(att[attnum]),
-                                                tp + att[attnum]->attcacheoff);
+               return (Datum) fetchatt(&(att[attnum]), tp + att[attnum]->attcacheoff);
        }
        else
        {
@@ -356,51 +365,64 @@ nocache_index_getattr(IndexTuple tup,
                                }
                        }
 
+                       /* If we know the next offset, we can skip the rest */
                        if (usecache && att[i]->attcacheoff > 0)
-                       {
                                off = att[i]->attcacheoff;
-                               if (att[i]->attlen == -1)
-                                       usecache = false;
-                               else
-                                       continue;
+                       else
+                       {
+                               switch (att[i]->attlen)
+                               {
+                                       case -1:
+                                               off = (att[i]->attalign == 'd') ?
+                                                       DOUBLEALIGN(off) : INTALIGN(off);
+                                               break;
+                                       case sizeof(char):
+                                               break;
+                                       case sizeof(short):
+                                               off = SHORTALIGN(off);
+                                               break;
+                                       case sizeof(int32):
+                                               off = INTALIGN(off);
+                                               break;
+                                       default:
+                                               if (att[i]->attlen < sizeof(int32))
+                                                       elog(ERROR,
+                                                                "nocachegetiattr2: attribute %d has len %d",
+                                                                i, att[i]->attlen);
+                                               if (att[i]->attalign == 'd')
+                                                       off = DOUBLEALIGN(off);
+                                               else
+                                                       off = LONGALIGN(off);
+                                               break;
+                               }
+                               if (usecache)
+                                       att[i]->attcacheoff = off;
                        }
 
-                       if (usecache)
-                               att[i]->attcacheoff = off;
                        switch (att[i]->attlen)
                        {
                                case sizeof(char):
                                        off++;
                                        break;
                                case sizeof(short):
-                                       off = SHORTALIGN(off) +sizeof(short);
+                                       off += sizeof(short);
                                        break;
                                case sizeof(int32):
-                                       off = INTALIGN(off) +sizeof(int32);
+                                       off += sizeof(int32);
                                        break;
                                case -1:
-                                       usecache = false;
-                                       off = (att[i]->attalign == 'd') ?
-                                               DOUBLEALIGN(off) : INTALIGN(off);
+                                       Assert(!VARLENA_FIXED_SIZE(att[i]) ||
+                                                       att[i]->atttypmod == VARSIZE(tp + off));
                                        off += VARSIZE(tp + off);
+                                       if (!VARLENA_FIXED_SIZE(att[i]))
+                                               usecache = false;
                                        break;
                                default:
-                                       if (att[i]->attlen > sizeof(int32))
-                                               off = (att[i]->attalign == 'd') ?
-                                                       DOUBLEALIGN(off) + att[i]->attlen :
-                                                       LONGALIGN(off) + att[i]->attlen;
-                                       else
-                                               elog(ERROR, "nocache_index_getattr2: attribute %d has len %d",
-                                                        i, att[i]->attlen);
-
+                                       off += att[i]->attlen;
                                        break;
                        }
                }
 
-               /*
-                * I don't know why this code was missed here! I've got it from
-                * heaptuple.c:nocachegetattr(). - vadim 06/12/97
-                */
                switch (att[attnum]->attlen)
                {
                        case -1:
index ccd70a0..76e4f52 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_type.h,v 1.30 1998/02/03 19:27:17 momjian Exp $
+ * $Id: pg_type.h,v 1.31 1998/02/04 21:32:12 momjian Exp $
  *
  * NOTES
  *       the genbki.sh script reads this file and generates .bki
@@ -366,7 +366,7 @@ DESCR("limited-range ISO-format date and time");
 
 
 #define USE_ATTTYPMOD(typeid)  ((typeid) == BPCHAROID || (typeid) == VARCHAROID)
-#define VARLENA_FIXED_SIZE(attr)       (false && (attr)->atttypid == BPCHAROID && (attr)->atttypmod > 0)
+#define VARLENA_FIXED_SIZE(attr)       ((attr)->atttypid == BPCHAROID && (attr)->atttypmod > 0)
 
 /*
  * prototypes for functions in pg_type.c