1 /*
2  * This file and its contents are licensed under the Apache License 2.0.
3  * Please see the included NOTICE for copyright information and
4  * LICENSE-APACHE for a copy of the license.
5  */
6 #ifndef TIMESCALEDB_SCANNER_H
7 #define TIMESCALEDB_SCANNER_H
8 
9 #include <postgres.h>
10 #include <access/genam.h>
11 #include <access/heapam.h>
12 #include <nodes/lockoptions.h>
13 #include <utils/fmgroids.h>
14 
15 #include "utils.h"
16 #include "compat/compat.h"
17 
18 typedef struct ScanTupLock
19 {
20 	LockTupleMode lockmode;
21 	LockWaitPolicy waitpolicy;
22 	unsigned int lockflags;
23 } ScanTupLock;
24 
25 /* Tuple information passed on to handlers when scanning for tuples. */
26 typedef struct TupleInfo
27 {
28 	Relation scanrel;
29 	TupleTableSlot *slot;
30 	/* return index tuple if it was requested -- only for index scans */
31 	IndexTuple ituple;
32 	TupleDesc ituple_desc;
33 
34 	/*
35 	 * If the user requested a tuple lock, the result of the lock is passed on
36 	 * in lockresult.
37 	 */
38 	TM_Result lockresult;
39 	/* Failure data in case of failed tuple lock */
40 	TM_FailureData lockfd;
41 	int count;
42 
43 	/*
44 	 * The memory context (optionally) set initially in the ScannerCtx. This
45 	 * can be used to allocate data on in the tuple handle function.
46 	 */
47 	MemoryContext mctx;
48 } TupleInfo;
49 
50 typedef enum ScanTupleResult
51 {
52 	SCAN_DONE,
53 	SCAN_CONTINUE
54 } ScanTupleResult;
55 
56 typedef enum ScanFilterResult
57 {
58 	SCAN_EXCLUDE,
59 	SCAN_INCLUDE
60 } ScanFilterResult;
61 
62 typedef ScanTupleResult (*tuple_found_func)(TupleInfo *ti, void *data);
63 typedef ScanFilterResult (*tuple_filter_func)(const TupleInfo *ti, void *data);
64 typedef void (*postscan_func)(int num_tuples, void *data);
65 
66 typedef struct ScannerCtx
67 {
68 	Oid table;
69 	Oid index;
70 	ScanKey scankey;
71 	int nkeys, norderbys, limit; /* Limit on number of tuples to return. 0 or
72 								  * less means no limit */
73 	bool want_itup;
74 	bool keeplock; /* Keep the table lock after the scan finishes */
75 	LOCKMODE lockmode;
76 	MemoryContext result_mctx; /* The memory context to allocate the result
77 								* on */
78 	const ScanTupLock *tuplock;
79 	ScanDirection scandirection;
80 	Snapshot snapshot; /* Snapshot requested by the caller. Set automatically
81 						* when NULL */
82 	void *data;		   /* User-provided data passed on to filter()
83 						* and tuple_found() */
84 
85 	/*
86 	 * Optional handler called before a scan starts, but relation locks are
87 	 * acquired.
88 	 */
89 	void (*prescan)(void *data);
90 
91 	/*
92 	 * Optional handler called after a scan finishes and before relation locks
93 	 * are released. Passes on the number of tuples found.
94 	 */
95 	void (*postscan)(int num_tuples, void *data);
96 
97 	/*
98 	 * Optional handler to filter tuples. Should return SCAN_INCLUDE for
99 	 * tuples that should be passed on to tuple_found, or SCAN_EXCLUDE
100 	 * otherwise.
101 	 */
102 	ScanFilterResult (*filter)(const TupleInfo *ti, void *data);
103 
104 	/*
105 	 * Handler for found tuples. Should return SCAN_CONTINUE to continue the
106 	 * scan or SCAN_DONE to finish without scanning further tuples.
107 	 */
108 	ScanTupleResult (*tuple_found)(TupleInfo *ti, void *data);
109 } ScannerCtx;
110 
111 /* Performs an index scan or heap scan and returns the number of matching
112  * tuples. */
113 extern TSDLLEXPORT int ts_scanner_scan(ScannerCtx *ctx);
114 extern TSDLLEXPORT bool ts_scanner_scan_one(ScannerCtx *ctx, bool fail_if_not_found,
115 											const char *item_type);
116 
117 /*
118  * Internal types and functions below.
119  *
120  * The below functions and types are really only exposed for the scan_iterator.
121  * The type definitions are needed for struct embedding and the functions are needed
122  * for iteration.
123  */
124 typedef union ScanDesc
125 {
126 	IndexScanDesc index_scan;
127 	TableScanDesc table_scan;
128 } ScanDesc;
129 /*
130  * InternalScannerCtx is the context passed to Scanner functions.
131  * It holds a pointer to the user-given ScannerCtx as well as
132  * internal state used during scanning. Should not be used outside scanner.c
133  * but is embedded in ScanIterator.
134  */
135 typedef struct InternalScannerCtx
136 {
137 	Relation tablerel, indexrel;
138 	TupleInfo tinfo;
139 	ScanDesc scan;
140 	ScannerCtx *sctx;
141 	bool registered_snapshot;
142 	bool closed;
143 } InternalScannerCtx;
144 
145 extern TSDLLEXPORT void ts_scanner_start_scan(ScannerCtx *ctx, InternalScannerCtx *ictx);
146 extern TSDLLEXPORT void ts_scanner_end_scan(ScannerCtx *ctx, InternalScannerCtx *ictx);
147 extern TSDLLEXPORT TupleInfo *ts_scanner_next(ScannerCtx *ctx, InternalScannerCtx *ictx);
148 extern TSDLLEXPORT ItemPointer ts_scanner_get_tuple_tid(TupleInfo *ti);
149 extern TSDLLEXPORT HeapTuple ts_scanner_fetch_heap_tuple(const TupleInfo *ti, bool materialize,
150 														 bool *should_free);
151 extern TSDLLEXPORT TupleDesc ts_scanner_get_tupledesc(const TupleInfo *ti);
152 extern TSDLLEXPORT void *ts_scanner_alloc_result(const TupleInfo *ti, Size size);
153 
154 #endif /* TIMESCALEDB_SCANNER_H */
155