9
9
*
10
10
*
11
11
* 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 $
13
13
*
14
14
*-------------------------------------------------------------------------
15
15
*/
@@ -160,13 +160,13 @@ index_formtuple(TupleDesc tupleDescriptor,
160
160
*
161
161
* This caches attribute offsets in the attribute descriptor.
162
162
*
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
164
164
* with the tuple, but that seems more difficult unless you take
165
165
* the storage hit of actually putting those offsets into the
166
166
* tuple you send to disk. Yuck.
167
167
*
168
168
* 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
170
170
* you cache the offsets once, examining all the other tuples using
171
171
* the same attribute descriptor will go much quicker. -cim 5/4/91
172
172
* ----------------
@@ -177,13 +177,13 @@ nocache_index_getattr(IndexTuple tup,
177
177
TupleDesc tupleDesc ,
178
178
bool * isnull )
179
179
{
180
+ Form_pg_attribute * att = tupleDesc -> attrs ;
180
181
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? */
183
184
int data_off ; /* tuple data offset */
184
- Form_pg_attribute * att = tupleDesc -> attrs ;
185
185
186
- (void ) isnull ;
186
+ (void ) isnull ; /* not used */
187
187
/* ----------------
188
188
* sanity checks
189
189
* ----------------
@@ -209,38 +209,26 @@ nocache_index_getattr(IndexTuple tup,
209
209
data_off = IndexTupleHasMinHeader (tup ) ? sizeof * tup :
210
210
IndexInfoFindDataOffset (tup -> t_info );
211
211
212
+ attnum -- ;
213
+
212
214
if (IndexTupleNoNulls (tup ))
213
215
{
214
- attnum -- ;
215
-
216
216
#ifdef IN_MACRO
217
217
/* 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 );
223
218
if (att [attnum ]-> attcacheoff != -1 )
224
219
{
225
220
return (Datum ) fetchatt (& (att [attnum ]),
226
221
(char * ) tup + data_off +
227
222
att [attnum ]-> attcacheoff );
228
223
}
229
224
#endif
230
-
231
- slow = 0 ;
232
225
}
233
226
else
234
227
{ /* there's a null somewhere in the tuple */
235
-
236
- slow = 0 ;
237
228
/* ----------------
238
229
* check to see if desired att is null
239
230
* ----------------
240
231
*/
241
-
242
- attnum -- ;
243
-
244
232
bp = (char * ) tup + sizeof (* tup ); /* "knows" t_bits are
245
233
* here! */
246
234
#ifdef IN_MACRO
@@ -254,34 +242,28 @@ nocache_index_getattr(IndexTuple tup,
254
242
#endif
255
243
256
244
/* ----------------
257
- * Now check to see if any preceeding bits are null...
245
+ * Now check to see if any preceding bits are null...
258
246
* ----------------
259
247
*/
260
248
{
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 ;
266
251
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
271
256
{
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 ++ )
280
261
{
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
+ }
285
267
}
286
268
}
287
269
}
@@ -298,24 +280,25 @@ nocache_index_getattr(IndexTuple tup,
298
280
return (Datum ) fetchatt (& (att [attnum ]),
299
281
tp + att [attnum ]-> attcacheoff );
300
282
}
301
- else if (attnum == 0 )
302
- return (Datum ) fetchatt (& (att [0 ]), (char * ) tp );
303
283
else if (!IndexTupleAllFixed (tup ))
304
284
{
305
- int j = 0 ;
285
+ int j ;
306
286
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
+ }
310
293
}
311
294
}
312
295
313
296
/*
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.
317
301
*/
318
-
319
302
if (!slow )
320
303
{
321
304
int j = 1 ;
@@ -327,15 +310,12 @@ nocache_index_getattr(IndexTuple tup,
327
310
328
311
att [0 ]-> attcacheoff = 0 ;
329
312
330
- while (att [j ]-> attcacheoff != -1 )
313
+ while (j < attnum && att [j ]-> attcacheoff > 0 )
331
314
j ++ ;
332
315
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 ;
337
317
338
- for (; j < attnum + 1 ; j ++ )
318
+ for (; j <= attnum ; j ++ )
339
319
{
340
320
341
321
/*
@@ -347,14 +327,7 @@ nocache_index_getattr(IndexTuple tup,
347
327
348
328
att [j ]-> attcacheoff = off ;
349
329
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 ;
358
331
}
359
332
360
333
return (Datum ) fetchatt (& (att [attnum ]), tp + att [attnum ]-> attcacheoff );
@@ -391,27 +364,14 @@ nocache_index_getattr(IndexTuple tup,
391
364
att [i ]-> attcacheoff = off ;
392
365
}
393
366
394
- switch (att [i ]-> attlen )
367
+ if (att [i ]-> attlen == -1 )
395
368
{
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 ;
415
375
}
416
376
}
417
377
0 commit comments