1 /*-------------------------------------------------------------------------
2  *
3  * metadata_cache.h
4  *	  Executor support for Citus.
5  *
6  * Copyright (c) Citus Data, Inc.
7  *
8  *-------------------------------------------------------------------------
9  */
10 
11 #ifndef METADATA_CACHE_H
12 #define METADATA_CACHE_H
13 
14 #include "postgres.h"
15 
16 #include "fmgr.h"
17 #include "distributed/metadata_utility.h"
18 #include "distributed/pg_dist_partition.h"
19 #include "distributed/worker_manager.h"
20 #include "utils/hsearch.h"
21 
22 extern bool EnableVersionChecks;
23 
24 /* managed via guc.c */
25 typedef enum
26 {
27 	USE_SECONDARY_NODES_NEVER = 0,
28 	USE_SECONDARY_NODES_ALWAYS = 1
29 } ReadFromSecondariesType;
30 extern int ReadFromSecondaries;
31 
32 
33 /*
34  * While upgrading pg_dist_local_group can be empty temporarily, in that
35  * case we use GROUP_ID_UPGRADING as the local group id to communicate
36  * this to other functions.
37  */
38 #define GROUP_ID_UPGRADING -2
39 
40 
41 /*
42  * Representation of a table's metadata that is frequently used for
43  * distributed execution. Cached.
44  */
45 typedef struct
46 {
47 	/* lookup key - must be first. A pg_class.oid oid. */
48 	Oid relationId;
49 
50 	/*
51 	 * Has an invalidation been received for this entry, requiring a rebuild
52 	 * of the cache entry?
53 	 */
54 	bool isValid;
55 
56 	bool hasUninitializedShardInterval;
57 	bool hasUniformHashDistribution; /* valid for hash partitioned tables */
58 	bool hasOverlappingShardInterval;
59 
60 	/* pg_dist_partition metadata for this table */
61 	char *partitionKeyString;
62 	Var *partitionColumn;
63 	char partitionMethod;
64 	uint32 colocationId;
65 	char replicationModel;
66 
67 	/* pg_dist_shard metadata (variable-length ShardInterval array) for this table */
68 	int shardIntervalArrayLength;
69 	ShardInterval **sortedShardIntervalArray;
70 
71 	/* comparator for partition column's type, NULL if DISTRIBUTE_BY_NONE */
72 	FmgrInfo *shardColumnCompareFunction;
73 
74 	/*
75 	 * Comparator for partition interval type (different from
76 	 * shardColumnCompareFunction if hash-partitioned), NULL if
77 	 * DISTRIBUTE_BY_NONE.
78 	 */
79 	FmgrInfo *shardIntervalCompareFunction;
80 	FmgrInfo *hashFunction; /* NULL if table is not distributed by hash */
81 
82 	/*
83 	 * The following two lists consists of relationIds that this distributed
84 	 * relation has a foreign key to (e.g., referencedRelationsViaForeignKey) or
85 	 * other relations has a foreign key to this relation (e.g.,
86 	 * referencingRelationsViaForeignKey).
87 	 *
88 	 * Note that we're keeping all transitive foreign key references as well
89 	 * such that if relation A refers to B, and B refers to C, we keep A and B
90 	 * in C's referencingRelationsViaForeignKey.
91 	 */
92 	List *referencedRelationsViaForeignKey;
93 	List *referencingRelationsViaForeignKey;
94 
95 	/* pg_dist_placement metadata */
96 	GroupShardPlacement **arrayOfPlacementArrays;
97 	int *arrayOfPlacementArrayLengths;
98 } CitusTableCacheEntry;
99 
100 typedef struct DistObjectCacheEntryKey
101 {
102 	Oid classid;
103 	Oid objid;
104 	int32 objsubid;
105 } DistObjectCacheEntryKey;
106 
107 typedef struct DistObjectCacheEntry
108 {
109 	/* lookup key - must be first. */
110 	DistObjectCacheEntryKey key;
111 
112 	bool isValid;
113 	bool isDistributed;
114 
115 	int distributionArgIndex;
116 	int colocationId;
117 } DistObjectCacheEntry;
118 
119 typedef enum
120 {
121 	HASH_DISTRIBUTED,
122 	APPEND_DISTRIBUTED,
123 	RANGE_DISTRIBUTED,
124 
125 	/* hash, range or append distributed table */
126 	DISTRIBUTED_TABLE,
127 
128 	/* hash- or range-distributed table */
129 	STRICTLY_PARTITIONED_DISTRIBUTED_TABLE,
130 
131 	REFERENCE_TABLE,
132 	CITUS_LOCAL_TABLE,
133 
134 	/* table without a dist key such as reference table */
135 	CITUS_TABLE_WITH_NO_DIST_KEY,
136 
137 	ANY_CITUS_TABLE_TYPE
138 } CitusTableType;
139 
140 extern List * AllCitusTableIds(void);
141 extern bool IsCitusTableType(Oid relationId, CitusTableType tableType);
142 extern bool IsCitusTableTypeCacheEntry(CitusTableCacheEntry *tableEtnry,
143 									   CitusTableType tableType);
144 
145 extern bool IsCitusTable(Oid relationId);
146 extern char PgDistPartitionViaCatalog(Oid relationId);
147 extern List * LookupDistShardTuples(Oid relationId);
148 extern char PartitionMethodViaCatalog(Oid relationId);
149 extern bool IsCitusLocalTableByDistParams(char partitionMethod, char replicationModel);
150 extern List * CitusTableList(void);
151 extern ShardInterval * LoadShardInterval(uint64 shardId);
152 extern Oid RelationIdForShard(uint64 shardId);
153 extern bool ReferenceTableShardId(uint64 shardId);
154 extern ShardPlacement * ShardPlacementOnGroupIncludingOrphanedPlacements(int32 groupId,
155 																		 uint64 shardId);
156 extern ShardPlacement * ActiveShardPlacementOnGroup(int32 groupId, uint64 shardId);
157 extern GroupShardPlacement * LoadGroupShardPlacement(uint64 shardId, uint64 placementId);
158 extern ShardPlacement * LoadShardPlacement(uint64 shardId, uint64 placementId);
159 extern CitusTableCacheEntry * GetCitusTableCacheEntry(Oid distributedRelationId);
160 extern CitusTableCacheEntry * LookupCitusTableCacheEntry(Oid relationId);
161 extern DistObjectCacheEntry * LookupDistObjectCacheEntry(Oid classid, Oid objid, int32
162 														 objsubid);
163 extern int32 GetLocalGroupId(void);
164 extern void CitusTableCacheFlushInvalidatedEntries(void);
165 extern Oid LookupShardRelationFromCatalog(int64 shardId, bool missing_ok);
166 extern List * ShardPlacementListIncludingOrphanedPlacements(uint64 shardId);
167 extern bool ShardExists(int64 shardId);
168 extern void CitusInvalidateRelcacheByRelid(Oid relationId);
169 extern void CitusInvalidateRelcacheByShardId(int64 shardId);
170 extern void InvalidateForeignKeyGraph(void);
171 extern void FlushDistTableCache(void);
172 extern void InvalidateMetadataSystemCache(void);
173 extern List * CitusTableTypeIdList(CitusTableType citusTableType);
174 extern Datum DistNodeMetadata(void);
175 extern bool ClusterHasReferenceTable(void);
176 extern bool HasUniformHashDistribution(ShardInterval **shardIntervalArray,
177 									   int shardIntervalArrayLength);
178 extern bool HasUninitializedShardInterval(ShardInterval **sortedShardIntervalArray,
179 										  int shardCount);
180 extern bool HasOverlappingShardInterval(ShardInterval **shardIntervalArray,
181 										int shardIntervalArrayLength,
182 										Oid shardIntervalCollation,
183 										FmgrInfo *shardIntervalSortCompareFunction);
184 
185 extern ShardPlacement * ShardPlacementForFunctionColocatedWithReferenceTable(
186 	CitusTableCacheEntry *cacheEntry);
187 extern ShardPlacement * ShardPlacementForFunctionColocatedWithDistTable(
188 	DistObjectCacheEntry *procedure, FuncExpr *funcExpr, Var *partitionColumn,
189 	CitusTableCacheEntry
190 	*cacheEntry,
191 	PlannedStmt *plan);
192 
193 extern bool CitusHasBeenLoaded(void);
194 extern bool CheckCitusVersion(int elevel);
195 extern bool CheckAvailableVersion(int elevel);
196 extern bool InstalledAndAvailableVersionsSame(void);
197 extern bool MajorVersionsCompatible(char *leftVersion, char *rightVersion);
198 extern void ErrorIfInconsistentShardIntervals(CitusTableCacheEntry *cacheEntry);
199 extern void EnsureModificationsCanRun(void);
200 extern char LookupDistributionMethod(Oid distributionMethodOid);
201 extern bool RelationExists(Oid relationId);
202 extern ShardInterval * TupleToShardInterval(HeapTuple heapTuple,
203 											TupleDesc tupleDescriptor, Oid intervalTypeId,
204 											int32 intervalTypeMod);
205 
206 /* access WorkerNodeHash */
207 extern bool HasAnyNodes(void);
208 extern HTAB * GetWorkerNodeHash(void);
209 extern WorkerNode * LookupNodeByNodeId(uint32 nodeId);
210 extern WorkerNode * LookupNodeByNodeIdOrError(uint32 nodeId);
211 extern WorkerNode * LookupNodeForGroup(int32 groupId);
212 
213 /* namespace oids */
214 extern Oid CitusCatalogNamespaceId(void);
215 
216 /* relation oids */
217 extern Oid DistColocationRelationId(void);
218 extern Oid DistColocationConfigurationIndexId(void);
219 extern Oid DistPartitionRelationId(void);
220 extern Oid DistShardRelationId(void);
221 extern Oid DistPlacementRelationId(void);
222 extern Oid DistNodeRelationId(void);
223 extern Oid DistRebalanceStrategyRelationId(void);
224 extern Oid DistLocalGroupIdRelationId(void);
225 extern Oid DistObjectRelationId(void);
226 extern Oid DistEnabledCustomAggregatesId(void);
227 
228 /* index oids */
229 extern Oid DistNodeNodeIdIndexId(void);
230 extern Oid DistPartitionLogicalRelidIndexId(void);
231 extern Oid DistPartitionColocationidIndexId(void);
232 extern Oid DistShardLogicalRelidIndexId(void);
233 extern Oid DistShardShardidIndexId(void);
234 extern Oid DistPlacementShardidIndexId(void);
235 extern Oid DistPlacementPlacementidIndexId(void);
236 extern Oid DistTransactionRelationId(void);
237 extern Oid DistTransactionGroupIndexId(void);
238 extern Oid DistPlacementGroupidIndexId(void);
239 extern Oid DistObjectPrimaryKeyIndexId(void);
240 
241 /* type oids */
242 extern Oid LookupTypeOid(char *schemaNameSting, char *typeNameString);
243 extern Oid CitusCopyFormatTypeId(void);
244 
245 /* function oids */
246 extern Oid CitusReadIntermediateResultFuncId(void);
247 Oid CitusReadIntermediateResultArrayFuncId(void);
248 extern Oid CitusExtraDataContainerFuncId(void);
249 extern Oid CitusAnyValueFunctionId(void);
250 extern Oid PgTableVisibleFuncId(void);
251 extern Oid CitusTableVisibleFuncId(void);
252 extern Oid JsonbExtractPathFuncId(void);
253 
254 /* enum oids */
255 extern Oid PrimaryNodeRoleId(void);
256 extern Oid SecondaryNodeRoleId(void);
257 extern Oid CitusCopyFormatTypeId(void);
258 extern Oid TextCopyFormatId(void);
259 extern Oid BinaryCopyFormatId(void);
260 
261 /* user related functions */
262 extern Oid CitusExtensionOwner(void);
263 extern char * CitusExtensionOwnerName(void);
264 extern char * CurrentUserName(void);
265 extern const char * CurrentDatabaseName(void);
266 
267 #endif /* METADATA_CACHE_H */
268