88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.46 1998/11/27 19:51:27 vadim Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.47 1999/01/24 22:53:25 tgl Exp $
1212 *
1313 * NOTES
1414 * The old interface functions have been converted to macros
@@ -311,13 +311,13 @@ heap_getsysattr(HeapTuple tup, Buffer b, int attnum)
311311 *
312312 *This caches attribute offsets in the attribute descriptor.
313313 *
314- *an alternate way to speed things up would be to cache offsets
314+ *An alternate way to speed things up would be to cache offsets
315315 *with the tuple, but that seems more difficult unless you take
316316 *the storage hit of actually putting those offsets into the
317317 *tuple you send to disk. Yuck.
318318 *
319319 *This scheme will be slightly slower than that, but should
320- *preform well for queries which hit large #'s of tuples. After
320+ *perform well for queries which hit large #'s of tuples. After
321321 *you cache the offsets once, examining all the other tuples using
322322 *the same attribute descriptor will go much quicker. -cim 5/4/91
323323 * ----------------
@@ -331,8 +331,8 @@ nocachegetattr(HeapTuple tuple,
331331char * tp ;/* ptr to att in tuple */
332332HeapTupleHeader tup = tuple -> t_data ;
333333bits8 * bp = tup -> t_bits ;/* ptr to att in tuple */
334- int slow ;/* do we have to walk nulls? */
335334Form_pg_attribute * att = tupleDesc -> attrs ;
335+ int slow = 0 ;/* do we have to walk nulls? */
336336
337337
338338#if IN_MACRO
@@ -343,6 +343,8 @@ nocachegetattr(HeapTuple tuple,
343343* isnull = false;
344344#endif
345345
346+ attnum -- ;
347+
346348/* ----------------
347349 * Three cases:
348350 *
@@ -354,8 +356,6 @@ nocachegetattr(HeapTuple tuple,
354356
355357if (HeapTupleNoNulls (tuple ))
356358{
357- attnum -- ;
358-
359359#if IN_MACRO
360360/* This is handled in the macro */
361361if (att [attnum ]-> attcacheoff != -1 )
@@ -373,20 +373,13 @@ nocachegetattr(HeapTuple tuple,
373373return (Datum )fetchatt (& (att [0 ]), (char * )tup + tup -> t_hoff );
374374}
375375#endif
376-
377- slow = 0 ;
378376}
379377else
380378{
381-
382379/*
383380 * there's a null somewhere in the tuple
384381 */
385382
386- tp = (char * )tup + tup -> t_hoff ;
387- slow = 0 ;
388- attnum -- ;
389-
390383/* ----------------
391384 *check to see if desired att is null
392385 * ----------------
@@ -403,34 +396,27 @@ nocachegetattr(HeapTuple tuple,
403396#endif
404397
405398/* ----------------
406- *Now check to see if anypreceeding bits are null...
399+ *Now check to see if anypreceding bits are null...
407400 * ----------------
408401 */
409402{
410- int i = 0 ;/* current offset in bp */
411- int mask ;/* bit in byte we're looking at */
412- char n ;/* current byte in bp */
413- int byte ,
414- finalbit ;
415-
416- byte = attnum >>3 ;
417- finalbit = attnum & 0x07 ;
403+ int byte = attnum >>3 ;
404+ int finalbit = attnum & 0x07 ;
418405
419- for (;i <=byte && !slow ;i ++ )
406+ /* check for nulls "before" final bit of last byte */
407+ if ((~bp [byte ])& ((1 <<finalbit )- 1 ))
408+ slow = 1 ;
409+ else
420410{
421- n = bp [i ];
422- if (i < byte )
411+ /* check for nulls in any "earlier" bytes */
412+ int i ;
413+ for (i = 0 ;i < byte ;i ++ )
423414{
424- /* check for nulls in any "earlier" bytes */
425- if ((~n )!= 0 )
426- slow = 1 ;
427- }
428- else
429- {
430- /* check for nulls "before" final bit of last byte */
431- mask = (1 <<finalbit )- 1 ;
432- if ((~n )& mask )
415+ if (bp [i ]!= 0xFF )
416+ {
433417slow = 1 ;
418+ break ;
419+ }
434420}
435421}
436422}
@@ -449,24 +435,29 @@ nocachegetattr(HeapTuple tuple,
449435tp + att [attnum ]-> attcacheoff );
450436}
451437else if (attnum == 0 )
452- return (Datum )fetchatt (& (att [0 ]),( char * ) tp );
438+ return (Datum )fetchatt (& (att [0 ]),tp );
453439else if (!HeapTupleAllFixed (tuple ))
454440{
455- int j = 0 ;
456-
441+ int j ;
457442/*
458443 * In for(), we make this <= and not < because we want to test
459444 * if we can go past it in initializing offsets.
460445 */
461- for (j = 0 ;j <=attnum && !slow ;j ++ )
446+ for (j = 0 ;j <=attnum ;j ++ )
447+ {
462448if (att [j ]-> attlen < 1 && !VARLENA_FIXED_SIZE (att [j ]))
449+ {
463450slow = 1 ;
451+ break ;
452+ }
453+ }
464454}
465455}
466456
467457/*
468- * if slow is zero, and we got here, we know that we have a tuple with
469- * no nulls. We also have to initialize the remainder of the
458+ * If slow is zero, and we got here, we know that we have a tuple with
459+ * no nulls or varlenas before the target attribute.
460+ * If possible, we also want to initialize the remainder of the
470461 * attribute cached offset values.
471462 */
472463if (!slow )
@@ -550,7 +541,8 @@ nocachegetattr(HeapTuple tuple,
550541
551542off = att_addlength (off ,att [i ]-> attlen ,tp + off );
552543
553- if (att [i ]-> attlen == -1 && !VARLENA_FIXED_SIZE (att [i ]))
544+ if (usecache &&
545+ att [i ]-> attlen == -1 && !VARLENA_FIXED_SIZE (att [i ]))
554546usecache = false;
555547}
556548