8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
* NOTES
14
14
* The old interface functions have been converted to macros
@@ -311,13 +311,13 @@ heap_getsysattr(HeapTuple tup, Buffer b, int attnum)
311
311
*
312
312
* This caches attribute offsets in the attribute descriptor.
313
313
*
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
315
315
* with the tuple, but that seems more difficult unless you take
316
316
* the storage hit of actually putting those offsets into the
317
317
* tuple you send to disk. Yuck.
318
318
*
319
319
* 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
321
321
* you cache the offsets once, examining all the other tuples using
322
322
* the same attribute descriptor will go much quicker. -cim 5/4/91
323
323
* ----------------
@@ -331,8 +331,8 @@ nocachegetattr(HeapTuple tuple,
331
331
char * tp ; /* ptr to att in tuple */
332
332
HeapTupleHeader tup = tuple -> t_data ;
333
333
bits8 * bp = tup -> t_bits ; /* ptr to att in tuple */
334
- int slow ; /* do we have to walk nulls? */
335
334
Form_pg_attribute * att = tupleDesc -> attrs ;
335
+ int slow = 0 ; /* do we have to walk nulls? */
336
336
337
337
338
338
#if IN_MACRO
@@ -343,6 +343,8 @@ nocachegetattr(HeapTuple tuple,
343
343
* isnull = false;
344
344
#endif
345
345
346
+ attnum -- ;
347
+
346
348
/* ----------------
347
349
* Three cases:
348
350
*
@@ -354,8 +356,6 @@ nocachegetattr(HeapTuple tuple,
354
356
355
357
if (HeapTupleNoNulls (tuple ))
356
358
{
357
- attnum -- ;
358
-
359
359
#if IN_MACRO
360
360
/* This is handled in the macro */
361
361
if (att [attnum ]-> attcacheoff != -1 )
@@ -373,20 +373,13 @@ nocachegetattr(HeapTuple tuple,
373
373
return (Datum ) fetchatt (& (att [0 ]), (char * ) tup + tup -> t_hoff );
374
374
}
375
375
#endif
376
-
377
- slow = 0 ;
378
376
}
379
377
else
380
378
{
381
-
382
379
/*
383
380
* there's a null somewhere in the tuple
384
381
*/
385
382
386
- tp = (char * ) tup + tup -> t_hoff ;
387
- slow = 0 ;
388
- attnum -- ;
389
-
390
383
/* ----------------
391
384
* check to see if desired att is null
392
385
* ----------------
@@ -403,34 +396,27 @@ nocachegetattr(HeapTuple tuple,
403
396
#endif
404
397
405
398
/* ----------------
406
- * Now check to see if any preceeding bits are null...
399
+ * Now check to see if any preceding bits are null...
407
400
* ----------------
408
401
*/
409
402
{
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 ;
418
405
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
420
410
{
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 ++ )
423
414
{
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
+ {
433
417
slow = 1 ;
418
+ break ;
419
+ }
434
420
}
435
421
}
436
422
}
@@ -449,24 +435,29 @@ nocachegetattr(HeapTuple tuple,
449
435
tp + att [attnum ]-> attcacheoff );
450
436
}
451
437
else if (attnum == 0 )
452
- return (Datum ) fetchatt (& (att [0 ]), ( char * ) tp );
438
+ return (Datum ) fetchatt (& (att [0 ]), tp );
453
439
else if (!HeapTupleAllFixed (tuple ))
454
440
{
455
- int j = 0 ;
456
-
441
+ int j ;
457
442
/*
458
443
* In for(), we make this <= and not < because we want to test
459
444
* if we can go past it in initializing offsets.
460
445
*/
461
- for (j = 0 ; j <= attnum && !slow ; j ++ )
446
+ for (j = 0 ; j <= attnum ; j ++ )
447
+ {
462
448
if (att [j ]-> attlen < 1 && !VARLENA_FIXED_SIZE (att [j ]))
449
+ {
463
450
slow = 1 ;
451
+ break ;
452
+ }
453
+ }
464
454
}
465
455
}
466
456
467
457
/*
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
470
461
* attribute cached offset values.
471
462
*/
472
463
if (!slow )
@@ -550,7 +541,8 @@ nocachegetattr(HeapTuple tuple,
550
541
551
542
off = att_addlength (off , att [i ]-> attlen , tp + off );
552
543
553
- if (att [i ]-> attlen == -1 && !VARLENA_FIXED_SIZE (att [i ]))
544
+ if (usecache &&
545
+ att [i ]-> attlen == -1 && !VARLENA_FIXED_SIZE (att [i ]))
554
546
usecache = false;
555
547
}
556
548
0 commit comments