-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathyeneid.c
560 lines (453 loc) · 19.2 KB
/
yeneid.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
/*--------------------------------------------------------------------------
*
* yeneid.c
* Yeneid access methods
*
*
* IDENTIFICATION
* yeneid.c
*
*--------------------------------------------------------------------------
*/
#include "postgres.h"
#include <math.h>
#include "miscadmin.h"
#include "access/amapi.h"
#include "access/heapam.h"
#include "access/tableam.h"
#include "catalog/index.h"
#include "commands/vacuum.h"
#include "executor/tuptable.h"
#include "yeneid.h"
#include "virt_tablespace.h"
PG_MODULE_MAGIC;
PG_FUNCTION_INFO_V1(yeneid_handler);
PG_FUNCTION_INFO_V1(yeneid_define_relation_offload_policy_internal);
PG_FUNCTION_INFO_V1(yeneid_define_relation_offload_policy_internal_seg);
static const TableAmRoutine yeneid_methods;
/* ------------------------------------------------------------------------
* Slot related callbacks for yeneid AM
* ------------------------------------------------------------------------
*/
static const TupleTableSlotOps *yeneid_slot_callbacks(Relation relation) {
/*
* Here you would most likely want to invent your own set of slot
* callbacks for your AM.
*/
return &TTSOpsMinimalTuple;
}
/* ------------------------------------------------------------------------
* Table Scan Callbacks for yeneid AM
* ------------------------------------------------------------------------
*/
static TableScanDesc yeneid_scan_begin(Relation relation, Snapshot snapshot,
int nkeys, ScanKey key,
ParallelTableScanDesc parallel_scan,
uint32 flags) {
YeneidScanDesc scan;
scan = (YeneidScanDesc)palloc0(sizeof(YeneidScanDescData));
scan->rs_base.rs_rd = relation;
scan->rs_base.rs_snapshot = snapshot;
scan->rs_base.rs_nkeys = nkeys;
scan->rs_base.rs_flags = flags;
scan->rs_base.rs_parallel = parallel_scan;
yeneid_scan_init(scan);
return (TableScanDesc)scan;
}
static void yeneid_scan_end(TableScanDesc sscan) {
YeneidScanDesc scan = (YeneidScanDesc)sscan;
pfree(scan);
}
static void yeneid_scan_rescan(TableScanDesc sscan, ScanKey key,
bool set_params, bool allow_strat,
bool allow_sync, bool allow_pagemode) {
/* nothing to do */
}
static bool yeneid_scan_getnextslot(TableScanDesc sscan,
ScanDirection direction,
TupleTableSlot *slot) {
/* nothing to do */
return yeneid_scan_getnextslot_internal((YeneidScanDesc)sscan, direction,
slot);
}
/* ------------------------------------------------------------------------
* Index Scan Callbacks for yeneid AM
* ------------------------------------------------------------------------
*/
static IndexFetchTableData *yeneid_index_fetch_begin(Relation rel) {
return NULL;
}
static void yeneid_index_fetch_reset(IndexFetchTableData *scan) {
/* nothing to do here */
}
static void yeneid_index_fetch_end(IndexFetchTableData *scan) {
/* nothing to do here */
}
static bool yeneid_index_fetch_tuple(struct IndexFetchTableData *scan,
ItemPointer tid, Snapshot snapshot,
TupleTableSlot *slot, bool *call_again,
bool *all_dead) {
/* there is no data */
return 0;
}
/* ------------------------------------------------------------------------
* Callbacks for non-modifying operations on individual tuples for
* yeneid AM.
* ------------------------------------------------------------------------
*/
static bool yeneid_fetch_row_version(Relation relation, ItemPointer tid,
Snapshot snapshot, TupleTableSlot *slot) {
/* nothing to do */
return false;
}
static void yeneid_get_latest_tid(TableScanDesc sscan, ItemPointer tid) {
/* nothing to do */
}
static bool yeneid_tuple_tid_valid(TableScanDesc scan, ItemPointer tid) {
return false;
}
static bool yeneid_tuple_satisfies_snapshot(Relation rel, TupleTableSlot *slot,
Snapshot snapshot) {
return false;
}
#if PG_VERSION_NUM >= 140000
static TransactionId yeneid_index_delete_tuples(Relation rel,
TM_IndexDeleteOp *delstate) {
return InvalidTransactionId;
}
#endif
/* ----------------------------------------------------------------------------
* Functions for manipulations of physical tuples for yeneid AM.
* ----------------------------------------------------------------------------
*/
static void yeneid_tuple_insert(Relation relation, TupleTableSlot *slot,
CommandId cid, int options,
BulkInsertState bistate, int segindex) {
/* nothing to do */
(void)yeneid_tuple_insert_internal(relation, slot, cid, options, bistate);
}
static void yeneid_tuple_insert_speculative(Relation relation,
TupleTableSlot *slot, CommandId cid,
int options,
BulkInsertState bistate,
uint32 specToken) {
/* nothing to do */
}
static void yeneid_tuple_complete_speculative(Relation relation,
TupleTableSlot *slot,
uint32 spekToken,
bool succeeded) {
/* nothing to do */
}
static void yeneid_multi_insert(Relation relation, TupleTableSlot **slots,
int ntuples, CommandId cid, int options,
BulkInsertState bistate) {
for (int i = 0; i < ntuples; i++)
yeneid_tuple_insert_internal(relation, slots[i], cid, options, bistate);
}
static TM_Result yeneid_tuple_delete(Relation relation, ItemPointer tid,
CommandId cid, Snapshot snapshot,
Snapshot crosscheck, bool wait,
TM_FailureData *tmfd, bool changingPart) {
/* nothing to do, so it is always OK */
return TM_Ok;
}
#if PG_VERSION_NUM >= 130000
static TM_Result yeneid_tuple_update(Relation relation, ItemPointer otid,
TupleTableSlot *slot, CommandId cid,
Snapshot snapshot, Snapshot crosscheck,
bool wait, TM_FailureData *tmfd,
LockTupleMode *lockmode,
TU_UpdateIndexes *update_indexes) {
/* nothing to do, so it is always OK */
return TM_Ok;
}
#else
/* see table_tuple_update() for reference about parameters */
static TM_Result yeneid_tuple_update(Relation rel, ItemPointer otid,
TupleTableSlot *slot, CommandId cid,
Snapshot snapshot, Snapshot crosscheck,
bool wait, TM_FailureData *tmfd,
LockTupleMode *lockmode,
bool *update_indexes) {
/* nothing to do, so it is always OK */
return TM_Ok;
}
#endif
static TM_Result yeneid_tuple_lock(Relation relation, ItemPointer tid,
Snapshot snapshot, TupleTableSlot *slot,
CommandId cid, LockTupleMode mode,
LockWaitPolicy wait_policy, uint8 flags,
TM_FailureData *tmfd) {
/* nothing to do, so it is always OK */
return TM_Ok;
}
static void yeneid_finish_bulk_insert(Relation relation, int options) {
/* nothing to do */
}
/* ------------------------------------------------------------------------
* DDL related callbacks for yeneid AM.
* ------------------------------------------------------------------------
*/
#if PG_VERSION_NUM >= 160000
static void yeneid_relation_set_new_filelocator(Relation rel,
const RelFileLocator *newrnode,
char persistence,
TransactionId *freezeXid,
MultiXactId *minmulti) {
/* nothing to do */
}
#else
static void yeneid_relation_set_new_relfilenode(Relation rel,
const RelFileNode *newrnode,
char persistence,
TransactionId *freezeXid,
MultiXactId *minmulti) {
yeneid_relation_set_new_relfilenode_internal(rel, newrnode, persistence, freezeXid, minmulti);
}
#endif
static void yeneid_relation_nontransactional_truncate(Relation rel) {
/* nothing to do */
}
#if PG_VERSION_NUM >= 160000
static void yeneid_copy_data(Relation rel, const RelFileLocator *newrnode) {
/* there is no data */
}
#else
static void yeneid_copy_data(Relation rel, const RelFileNode *newrnode) {
/* there is no data */
}
#endif
static void yeneid_copy_for_cluster(Relation OldTable, Relation NewTable,
Relation OldIndex, bool use_sort,
TransactionId OldestXmin,
TransactionId *xid_cutoff,
MultiXactId *multi_cutoff,
double *num_tuples, double *tups_vacuumed,
double *tups_recently_dead) {
/* no data, so nothing to do */
}
static void yeneid_vacuum(Relation onerel, VacuumParams *params,
BufferAccessStrategy bstrategy) {
/* no data, so nothing to do */
}
static bool yeneid_scan_analyze_next_block(TableScanDesc scan,
BlockNumber blockno,
BufferAccessStrategy bstrategy) {
/* no data, so no point to analyze next block */
return false;
}
static bool yeneid_scan_analyze_next_tuple(TableScanDesc scan,
TransactionId OldestXmin,
double *liverows, double *deadrows,
TupleTableSlot *slot) {
/* no data, so no point to analyze next tuple */
return false;
}
static double yeneid_index_build_range_scan(
Relation tableRelation, Relation indexRelation, IndexInfo *indexInfo,
bool allow_sync, bool anyvisible, bool progress, BlockNumber start_blockno,
BlockNumber numblocks, IndexBuildCallback callback, void *callback_state,
TableScanDesc scan) {
/* no data, so no tuples */
return 0;
}
static void yeneid_index_validate_scan(Relation tableRelation,
Relation indexRelation,
IndexInfo *indexInfo, Snapshot snapshot,
ValidateIndexState *state) {
/* nothing to do */
}
/* ------------------------------------------------------------------------
* Miscellaneous callbacks for the yeneid AM
* ------------------------------------------------------------------------
*/
static uint64 yeneid_relation_size(Relation rel, ForkNumber forkNumber) {
/* there is nothing */
return 0;
}
/*
* Check to see whether the table needs a TOAST table.
*/
static bool yeneid_relation_needs_toast_table(Relation rel) {
/* no data, so no toast table needed */
return false;
}
/* ------------------------------------------------------------------------
* Planner related callbacks for the yeneid AM
* ------------------------------------------------------------------------
*/
static void yeneid_estimate_rel_size(Relation rel, int32 *attr_widths,
BlockNumber *pages, double *tuples,
double *allvisfrac) {
/* no data available */
if (attr_widths)
*attr_widths = 0;
if (pages)
*pages = 0;
if (tuples)
*tuples = 0;
if (allvisfrac)
*allvisfrac = 0;
}
/* ------------------------------------------------------------------------
* Executor related callbacks for the yeneid AM
* ------------------------------------------------------------------------
*/
static bool yeneid_scan_bitmap_next_block(TableScanDesc scan,
TBMIterateResult *tbmres) {
/* no data, so no point to scan next block */
return false;
}
static bool yeneid_scan_bitmap_next_tuple(TableScanDesc scan,
TBMIterateResult *tbmres,
TupleTableSlot *slot) {
/* no data, so no point to scan next tuple */
return false;
}
static bool yeneid_scan_sample_next_block(TableScanDesc scan,
SampleScanState *scanstate) {
/* no data, so no point to scan next block for sampling */
return false;
}
static bool yeneid_scan_sample_next_tuple(TableScanDesc scan,
SampleScanState *scanstate,
TupleTableSlot *slot) {
/* no data, so no point to scan next tuple for sampling */
return false;
}
#if PG_VERSION_NUM < 140000
static TransactionId
yeneid_compute_xid_horizon_for_tuples(Relation rel, ItemPointerData *tids,
int nitems) {
/*
* This API is only useful for hot standby snapshot conflict resolution
* (for eg. see btree_xlog_delete()), in the context of index page-level
* vacuums (aka page-level cleanups). This operation is only done when
* IndexScanDesc->kill_prior_tuple is true, which is never for AO/CO tables
* (we always return all_dead = false in the index_fetch_tuple() callback
* as we don't support HOT)
*/
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("feature not supported on yeneid relations")));
}
#endif
#ifdef GP_VERSION_NUM
static void yeneid_relation_add_columns(Relation rel, List *newvals,
List *constraints, TupleDesc oldDesc) {
elog(ERROR, "add columns-only not implemented for yeneid tables");
}
static void yeneid_relation_rewrite_columns(Relation rel, List *newvals,
TupleDesc oldDesc) {
elog(ERROR, "rewrite columns-only not implemented for yeneid tables");
}
/*
* For each AO segment, get the starting heap block number and the number of
* heap blocks (together termed as a BlockSequence). The starting heap block
* number is always deterministic given a segment number. See AOtupleId.
*
* The number of heap blocks can be determined from the last row number present
* in the segment. See appendonlytid.h for details.
*/
static BlockSequence *yeneid_relation_get_block_sequences(Relation rel,
int *numSequences) {
elog(ERROR, "not implemented for yeneid tables");
}
/*
* Return the BlockSequence corresponding to the AO segment in which the logical
* heap block 'blkNum' falls.
*/
static void yeneid_relation_get_block_sequence(Relation rel, BlockNumber blkNum,
BlockSequence *sequence) {
elog(ERROR, "not implemented for yeneid tables");
}
/*
* Provides an opportunity to create backend-local state to be consulted during
* the course of the current DML or DML-like command, for the given relation.
*/
static void yeneid_dml_init(Relation relation) {
yeneid_dml_init_internal(relation);
}
/*
* Provides an opportunity to clean up backend-local state set up for the
* current DML or DML-like command, for the given relation.
*/
static void yeneid_dml_finish(Relation relation) {
yeneid_dml_finish_internal(relation);
}
#endif
/* ------------------------------------------------------------------------
* Definition of the yeneid table access method.
* ------------------------------------------------------------------------
*/
static const TableAmRoutine yeneid_methods = {
.type = T_TableAmRoutine,
.slot_callbacks = yeneid_slot_callbacks,
.scan_begin = yeneid_scan_begin,
.scan_end = yeneid_scan_end,
.scan_rescan = yeneid_scan_rescan,
.scan_getnextslot = yeneid_scan_getnextslot,
/* these are common helper functions */
.parallelscan_estimate = table_block_parallelscan_estimate,
.parallelscan_initialize = table_block_parallelscan_initialize,
.parallelscan_reinitialize = table_block_parallelscan_reinitialize,
.index_fetch_begin = yeneid_index_fetch_begin,
.index_fetch_reset = yeneid_index_fetch_reset,
.index_fetch_end = yeneid_index_fetch_end,
.index_fetch_tuple = yeneid_index_fetch_tuple,
.tuple_insert = yeneid_tuple_insert,
.tuple_insert_speculative = yeneid_tuple_insert_speculative,
.tuple_complete_speculative = yeneid_tuple_complete_speculative,
.multi_insert = yeneid_multi_insert,
.tuple_delete = yeneid_tuple_delete,
.tuple_update = yeneid_tuple_update,
.tuple_lock = yeneid_tuple_lock,
.finish_bulk_insert = yeneid_finish_bulk_insert,
.tuple_fetch_row_version = yeneid_fetch_row_version,
.tuple_get_latest_tid = yeneid_get_latest_tid,
.tuple_tid_valid = yeneid_tuple_tid_valid,
.tuple_satisfies_snapshot = yeneid_tuple_satisfies_snapshot,
#if PG_VERSION_NUM < 140000
.compute_xid_horizon_for_tuples = yeneid_compute_xid_horizon_for_tuples,
#endif
#if PG_VERSION_NUM >= 140000
.index_delete_tuples = yeneid_index_delete_tuples,
#endif
#if PG_VERSION_NUM >= 160000
.relation_set_new_filelocator = yeneid_relation_set_new_filelocator,
#else
.relation_set_new_filenode = yeneid_relation_set_new_relfilenode,
#endif
.relation_nontransactional_truncate =
yeneid_relation_nontransactional_truncate,
.relation_copy_data = yeneid_copy_data,
.relation_copy_for_cluster = yeneid_copy_for_cluster,
.relation_vacuum = yeneid_vacuum,
.scan_analyze_next_block = yeneid_scan_analyze_next_block,
.scan_analyze_next_tuple = yeneid_scan_analyze_next_tuple,
.index_build_range_scan = yeneid_index_build_range_scan,
.index_validate_scan = yeneid_index_validate_scan,
.relation_size = yeneid_relation_size,
#ifdef GP_VERSION_NUM
.relation_add_columns = yeneid_relation_add_columns,
.relation_rewrite_columns = yeneid_relation_rewrite_columns,
.relation_get_block_sequences = yeneid_relation_get_block_sequences,
.relation_get_block_sequence = yeneid_relation_get_block_sequence,
.dml_init = yeneid_dml_init,
.dml_finish = yeneid_dml_finish,
#endif
.relation_needs_toast_table = yeneid_relation_needs_toast_table,
.relation_estimate_size = yeneid_estimate_rel_size,
.scan_bitmap_next_block = yeneid_scan_bitmap_next_block,
.scan_bitmap_next_tuple = yeneid_scan_bitmap_next_tuple,
.scan_sample_next_block = yeneid_scan_sample_next_block,
.scan_sample_next_tuple = yeneid_scan_sample_next_tuple};
Datum yeneid_handler(PG_FUNCTION_ARGS) { PG_RETURN_POINTER(¥eid_methods); }
Datum yeneid_define_relation_offload_policy_internal(PG_FUNCTION_ARGS) {
(void)YeneidDefineOffloadPolicy(PG_GETARG_OID(0));
PG_RETURN_VOID();
}
Datum yeneid_define_relation_offload_policy_internal_seg(PG_FUNCTION_ARGS) {
(void)YeneidDefineOffloadPolicy(PG_GETARG_OID(0));
PG_RETURN_VOID();
}