|
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