diff options
Diffstat (limited to 'src/backend/access/robert/robertam.c')
| -rw-r--r-- | src/backend/access/robert/robertam.c | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/src/backend/access/robert/robertam.c b/src/backend/access/robert/robertam.c new file mode 100644 index 0000000000..49045cd0ad --- /dev/null +++ b/src/backend/access/robert/robertam.c @@ -0,0 +1,202 @@ +/* + * robertam.c + */ + +#include "postgres.h" + +#include "access/heaptoast.h" +#include "access/robertam.h" +#include "access/robert_scan.h" +#include "access/robert_slot.h" +#include "utils/builtins.h" + +extern Datum robert_tableam_handler(PG_FUNCTION_ARGS); + +static const TableAmRoutine robertam_methods = { + .type = T_TableAmRoutine, + + .slot_callbacks = robert_slot_callbacks, + + .scan_begin = robert_scan_begin, + .scan_end = robert_scan_end, + .scan_rescan = robert_scan_rescan, + .scan_getnextslot = robert_scan_getnextslot, + + .parallelscan_estimate = table_block_parallelscan_estimate, + .parallelscan_initialize = table_block_parallelscan_initialize, + .parallelscan_reinitialize = table_block_parallelscan_reinitialize, + + .index_fetch_begin = robert_index_fetch_begin, + .index_fetch_reset = robert_index_fetch_reset, + .index_fetch_end = robert_index_fetch_end, + .index_fetch_tuple = robert_index_fetch_tuple, + + .tuple_fetch_row_version = robert_tuple_fetch_row_version, + .tuple_tid_valid = robert_tuple_tid_valid, + .tuple_get_latest_tid = robert_tuple_get_latest_tid, + .tuple_satisfies_snapshot = robert_tuple_satisfies_snapshot, + .compute_xid_horizon_for_tuples = robert_compute_xid_horizon_for_tuples, + + .tuple_insert = robert_tuple_insert, + .tuple_insert_speculative = robert_tuple_insert_speculative, + .tuple_complete_speculative = robert_tuple_complete_speculative, + .multi_insert = robert_multi_insert, + .tuple_delete = robert_tuple_delete, + .tuple_update = robert_tuple_update, + .tuple_lock = robert_tuple_lock, + .finish_bulk_insert = robert_finish_bulk_insert, + + .relation_set_new_filenode = robert_relation_set_new_filenode, + .relation_nontransactional_truncate = robert_relation_nontransactional_truncate, + .relation_copy_data = robert_relation_copy_data, + .relation_copy_for_cluster = robert_relation_copy_for_cluster, + .relation_vacuum = robert_relation_vacuum, + .scan_analyze_next_block = robert_scan_analyze_next_block, + .scan_analyze_next_tuple = robert_scan_analyze_next_tuple, + .index_build_range_scan = robert_index_build_range_scan, + .index_validate_scan = robert_index_validate_scan, + + .relation_size = table_block_relation_size, + .relation_needs_toast_table = robert_relation_needs_toast_table, + .relation_toast_am = robert_relation_toast_am, + .toast_max_chunk_size = TOAST_MAX_CHUNK_SIZE, + + .relation_estimate_size = robert_relation_estimate_size, + + .scan_bitmap_next_block = robert_scan_bitmap_next_block, + .scan_bitmap_next_tuple = robert_scan_bitmap_next_tuple, + + .scan_sample_next_block = robert_scan_sample_next_block, + .scan_sample_next_tuple = robert_scan_sample_next_tuple +}; + +Datum +robert_tableam_handler(PG_FUNCTION_ARGS) +{ + PG_RETURN_POINTER(&robertam_methods); +} + + +bool +robert_tuple_fetch_row_version(Relation rel, ItemPointer tid, + Snapshot snapshot, TupleTableSlot *slot) +{ + return false; +} + +bool +robert_tuple_tid_valid(TableScanDesc sscan, ItemPointer tid) +{ + RobertScanDesc scan = (RobertScanDesc) sscan; + + return ItemPointerIsValid(tid) && + ItemPointerGetBlockNumber(tid) < scan->rrs_nblocks; +} + +void +robert_tuple_get_latest_tid(TableScanDesc scan, ItemPointer tid) +{ +} + +bool +robert_tuple_satisfies_snapshot(Relation rel, TupleTableSlot *slot, + Snapshot snapshot) +{ + return false; +} + +TransactionId +robert_compute_xid_horizon_for_tuples(Relation rel, + ItemPointerData *items, + int nitems) +{ + return InvalidTransactionId; +} + +/* + * Check to see whether the table needs a TOAST table. It does only if + * (1) there are any toastable attributes, and (2) the maximum length + * of a tuple could exceed TOAST_TUPLE_THRESHOLD. (We don't want to + * create a toast table for something like "f1 varchar(20)".) + */ +bool +robert_relation_needs_toast_table(Relation rel) +{ + int32 data_length = 0; + bool maxlength_unknown = false; + bool has_toastable_attrs = false; + TupleDesc tupdesc = rel->rd_att; + int32 tuple_length; + int i; + + for (i = 0; i < tupdesc->natts; i++) + { + Form_pg_attribute att = TupleDescAttr(tupdesc, i); + + if (att->attisdropped) + continue; + + /* we don't align if it's pass-by-value */ + if (!att->attbyval) + data_length = att_align_nominal(data_length, att->attalign); + + if (att->attlen > 0) + { + /* Fixed-length types are never toastable */ + data_length += att->attlen; + } + else + { + int32 maxlen = type_maximum_size(att->atttypid, + att->atttypmod); + + if (maxlen < 0) + maxlength_unknown = true; + else + data_length += maxlen; + if (att->attstorage != 'p') + has_toastable_attrs = true; + } + } + if (!has_toastable_attrs) + return false; /* nothing to toast? */ + if (maxlength_unknown) + return true; /* any unlimited-length attrs? */ + tuple_length = SizeofRobertTupleHeader + BITMAPLEN(tupdesc->natts) + + data_length; + return (tuple_length > TOAST_TUPLE_THRESHOLD); +} + +/* + * robert_relation_toast_am + * + * TOAST tables for robert relations are just robert relations. + */ +Oid +robert_relation_toast_am(Relation rel) +{ + return rel->rd_rel->relam; +} + +/* + * robert_relation_estimate_size + * + * Each tuple involves an item pointer and an (unaligned) RobertTupleHeader. + * + * We don't currently have any special space, so only the size of the page + * header needs to be subtracted from the number of usable bytes per page. + */ +void +robert_relation_estimate_size(Relation rel, int32 *attr_widths, + BlockNumber *pages, double *tuples, + double *allvisfrac) +{ + const Size overhead_bytes_per_tuple = + SizeofRobertTupleHeader + sizeof(ItemIdData); + const Size usable_bytes_per_page = BLCKSZ - SizeOfPageHeaderData; + + table_block_relation_estimate_size(rel, attr_widths, pages, tuples, + allvisfrac, + overhead_bytes_per_tuple, + usable_bytes_per_page); +} |
