|
71 | 71 | #define VARLENA_ATT_IS_PACKABLE(att) \ |
72 | 72 | ((att)->attstorage != 'p') |
73 | 73 |
|
| 74 | +static Datum getmissingattr(TupleDesc tupleDesc, int attnum, bool *isnull); |
| 75 | + |
74 | 76 |
|
75 | 77 | /* ---------------------------------------------------------------- |
76 | 78 | * misc support routines |
|
80 | 82 | /* |
81 | 83 | * Return the missing value of an attribute, or NULL if there isn't one. |
82 | 84 | */ |
83 | | -Datum |
| 85 | +static Datum |
84 | 86 | getmissingattr(TupleDesc tupleDesc, |
85 | 87 | int attnum, bool *isnull) |
86 | 88 | { |
@@ -1350,186 +1352,6 @@ heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, |
1350 | 1352 | values[attnum] = getmissingattr(tupleDesc, attnum + 1, &isnull[attnum]); |
1351 | 1353 | } |
1352 | 1354 |
|
1353 | | -/* |
1354 | | - * slot_deform_tuple |
1355 | | - * Given a TupleTableSlot, extract data from the slot's physical tuple |
1356 | | - * into its Datum/isnull arrays. Data is extracted up through the |
1357 | | - * natts'th column (caller must ensure this is a legal column number). |
1358 | | - * |
1359 | | - * This is essentially an incremental version of heap_deform_tuple: |
1360 | | - * on each call we extract attributes up to the one needed, without |
1361 | | - * re-computing information about previously extracted attributes. |
1362 | | - * slot->tts_nvalid is the number of attributes already extracted. |
1363 | | - */ |
1364 | | -void |
1365 | | -slot_deform_tuple(TupleTableSlot *slot, int natts) |
1366 | | -{ |
1367 | | - HeapTuple tuple = slot->tts_tuple; |
1368 | | - TupleDesc tupleDesc = slot->tts_tupleDescriptor; |
1369 | | - Datum *values = slot->tts_values; |
1370 | | - bool *isnull = slot->tts_isnull; |
1371 | | - HeapTupleHeader tup = tuple->t_data; |
1372 | | - bool hasnulls = HeapTupleHasNulls(tuple); |
1373 | | - int attnum; |
1374 | | - char *tp; /* ptr to tuple data */ |
1375 | | - uint32 off; /* offset in tuple data */ |
1376 | | - bits8 *bp = tup->t_bits; /* ptr to null bitmap in tuple */ |
1377 | | - bool slow; /* can we use/set attcacheoff? */ |
1378 | | - |
1379 | | - /* |
1380 | | - * Check whether the first call for this tuple, and initialize or restore |
1381 | | - * loop state. |
1382 | | - */ |
1383 | | - attnum = slot->tts_nvalid; |
1384 | | - if (attnum == 0) |
1385 | | - { |
1386 | | - /* Start from the first attribute */ |
1387 | | - off = 0; |
1388 | | - slow = false; |
1389 | | - } |
1390 | | - else |
1391 | | - { |
1392 | | - /* Restore state from previous execution */ |
1393 | | - off = slot->tts_off; |
1394 | | - slow = TTS_SLOW(slot); |
1395 | | - } |
1396 | | - |
1397 | | - tp = (char *) tup + tup->t_hoff; |
1398 | | - |
1399 | | - for (; attnum < natts; attnum++) |
1400 | | - { |
1401 | | - Form_pg_attribute thisatt = TupleDescAttr(tupleDesc, attnum); |
1402 | | - |
1403 | | - if (hasnulls && att_isnull(attnum, bp)) |
1404 | | - { |
1405 | | - values[attnum] = (Datum) 0; |
1406 | | - isnull[attnum] = true; |
1407 | | - slow = true; /* can't use attcacheoff anymore */ |
1408 | | - continue; |
1409 | | - } |
1410 | | - |
1411 | | - isnull[attnum] = false; |
1412 | | - |
1413 | | - if (!slow && thisatt->attcacheoff >= 0) |
1414 | | - off = thisatt->attcacheoff; |
1415 | | - else if (thisatt->attlen == -1) |
1416 | | - { |
1417 | | - /* |
1418 | | - * We can only cache the offset for a varlena attribute if the |
1419 | | - * offset is already suitably aligned, so that there would be no |
1420 | | - * pad bytes in any case: then the offset will be valid for either |
1421 | | - * an aligned or unaligned value. |
1422 | | - */ |
1423 | | - if (!slow && |
1424 | | - off == att_align_nominal(off, thisatt->attalign)) |
1425 | | - thisatt->attcacheoff = off; |
1426 | | - else |
1427 | | - { |
1428 | | - off = att_align_pointer(off, thisatt->attalign, -1, |
1429 | | - tp + off); |
1430 | | - slow = true; |
1431 | | - } |
1432 | | - } |
1433 | | - else |
1434 | | - { |
1435 | | - /* not varlena, so safe to use att_align_nominal */ |
1436 | | - off = att_align_nominal(off, thisatt->attalign); |
1437 | | - |
1438 | | - if (!slow) |
1439 | | - thisatt->attcacheoff = off; |
1440 | | - } |
1441 | | - |
1442 | | - values[attnum] = fetchatt(thisatt, tp + off); |
1443 | | - |
1444 | | - off = att_addlength_pointer(off, thisatt->attlen, tp + off); |
1445 | | - |
1446 | | - if (thisatt->attlen <= 0) |
1447 | | - slow = true; /* can't use attcacheoff anymore */ |
1448 | | - } |
1449 | | - |
1450 | | - /* |
1451 | | - * Save state for next execution |
1452 | | - */ |
1453 | | - slot->tts_nvalid = attnum; |
1454 | | - slot->tts_off = off; |
1455 | | - if (slow) |
1456 | | - slot->tts_flags |= TTS_FLAG_SLOW; |
1457 | | - else |
1458 | | - slot->tts_flags &= ~TTS_FLAG_SLOW; |
1459 | | -} |
1460 | | - |
1461 | | -/* |
1462 | | - * slot_attisnull |
1463 | | - * Detect whether an attribute of the slot is null, without |
1464 | | - * actually fetching it. |
1465 | | - */ |
1466 | | -bool |
1467 | | -slot_attisnull(TupleTableSlot *slot, int attnum) |
1468 | | -{ |
1469 | | - HeapTuple tuple = slot->tts_tuple; |
1470 | | - TupleDesc tupleDesc = slot->tts_tupleDescriptor; |
1471 | | - |
1472 | | - /* |
1473 | | - * system attributes are handled by heap_attisnull |
1474 | | - */ |
1475 | | - if (attnum <= 0) |
1476 | | - { |
1477 | | - if (tuple == NULL) /* internal error */ |
1478 | | - elog(ERROR, "cannot extract system attribute from virtual tuple"); |
1479 | | - if (tuple == &(slot->tts_minhdr)) /* internal error */ |
1480 | | - elog(ERROR, "cannot extract system attribute from minimal tuple"); |
1481 | | - return heap_attisnull(tuple, attnum, tupleDesc); |
1482 | | - } |
1483 | | - |
1484 | | - /* |
1485 | | - * fast path if desired attribute already cached |
1486 | | - */ |
1487 | | - if (attnum <= slot->tts_nvalid) |
1488 | | - return slot->tts_isnull[attnum - 1]; |
1489 | | - |
1490 | | - /* |
1491 | | - * return NULL if attnum is out of range according to the tupdesc |
1492 | | - */ |
1493 | | - if (attnum > tupleDesc->natts) |
1494 | | - return true; |
1495 | | - |
1496 | | - /* |
1497 | | - * otherwise we had better have a physical tuple (tts_nvalid should equal |
1498 | | - * natts in all virtual-tuple cases) |
1499 | | - */ |
1500 | | - if (tuple == NULL) /* internal error */ |
1501 | | - elog(ERROR, "cannot extract attribute from empty tuple slot"); |
1502 | | - |
1503 | | - /* and let the tuple tell it */ |
1504 | | - return heap_attisnull(tuple, attnum, tupleDesc); |
1505 | | -} |
1506 | | - |
1507 | | -/* |
1508 | | - * slot_getsysattr |
1509 | | - * This function fetches a system attribute of the slot's current tuple. |
1510 | | - * Unlike slot_getattr, if the slot does not contain system attributes, |
1511 | | - * this will return false (with a NULL attribute value) instead of |
1512 | | - * throwing an error. |
1513 | | - */ |
1514 | | -bool |
1515 | | -slot_getsysattr(TupleTableSlot *slot, int attnum, |
1516 | | - Datum *value, bool *isnull) |
1517 | | -{ |
1518 | | - HeapTuple tuple = slot->tts_tuple; |
1519 | | - |
1520 | | - Assert(attnum < 0); /* else caller error */ |
1521 | | - if (tuple == NULL || |
1522 | | - tuple == &(slot->tts_minhdr)) |
1523 | | - { |
1524 | | - /* No physical tuple, or minimal tuple, so fail */ |
1525 | | - *value = (Datum) 0; |
1526 | | - *isnull = true; |
1527 | | - return false; |
1528 | | - } |
1529 | | - *value = heap_getsysattr(tuple, attnum, slot->tts_tupleDescriptor, isnull); |
1530 | | - return true; |
1531 | | -} |
1532 | | - |
1533 | 1355 | /* |
1534 | 1356 | * heap_freetuple |
1535 | 1357 | */ |
|
0 commit comments