PostgreSQL Source Code git master
Loading...
Searching...
No Matches
pgpa_ast.c File Reference
#include "postgres.h"
#include "pgpa_ast.h"
#include "funcapi.h"
#include "utils/array.h"
#include "utils/builtins.h"
Include dependency graph for pgpa_ast.c:

Go to the source code of this file.

Functions

static bool pgpa_identifiers_cover_target (int nrids, pgpa_identifier *rids, pgpa_advice_target *target, bool *rids_used)
 
charpgpa_cstring_advice_tag (pgpa_advice_tag_type advice_tag)
 
pgpa_advice_tag_type pgpa_parse_advice_tag (const char *tag, bool *fail)
 
void pgpa_format_advice_target (StringInfo str, pgpa_advice_target *target)
 
void pgpa_format_index_target (StringInfo str, pgpa_index_target *itarget)
 
bool pgpa_index_targets_equal (pgpa_index_target *i1, pgpa_index_target *i2)
 
bool pgpa_identifier_matches_target (pgpa_identifier *rid, pgpa_advice_target *target)
 
pgpa_itm_type pgpa_identifiers_match_target (int nrids, pgpa_identifier *rids, pgpa_advice_target *target)
 

Function Documentation

◆ pgpa_cstring_advice_tag()

char * pgpa_cstring_advice_tag ( pgpa_advice_tag_type  advice_tag)

Definition at line 29 of file pgpa_ast.c.

30{
31 switch (advice_tag)
32 {
34 return "BITMAP_HEAP_SCAN";
36 return "FOREIGN_JOIN";
37 case PGPA_TAG_GATHER:
38 return "GATHER";
40 return "GATHER_MERGE";
42 return "HASH_JOIN";
44 return "INDEX_ONLY_SCAN";
46 return "INDEX_SCAN";
48 return "JOIN_ORDER";
50 return "MERGE_JOIN_MATERIALIZE";
52 return "MERGE_JOIN_PLAIN";
54 return "NESTED_LOOP_MATERIALIZE";
56 return "NESTED_LOOP_MEMOIZE";
58 return "NESTED_LOOP_PLAIN";
60 return "NO_GATHER";
62 return "PARTITIONWISE";
64 return "SEMIJOIN_NON_UNIQUE";
66 return "SEMIJOIN_UNIQUE";
68 return "SEQ_SCAN";
70 return "TID_SCAN";
71 }
72
74 return NULL;
75}
#define pg_unreachable()
Definition c.h:361
@ PGPA_TAG_INDEX_SCAN
Definition pgpa_ast.h:88
@ PGPA_TAG_NESTED_LOOP_MATERIALIZE
Definition pgpa_ast.h:92
@ PGPA_TAG_MERGE_JOIN_PLAIN
Definition pgpa_ast.h:91
@ PGPA_TAG_GATHER_MERGE
Definition pgpa_ast.h:85
@ PGPA_TAG_GATHER
Definition pgpa_ast.h:84
@ PGPA_TAG_NESTED_LOOP_MEMOIZE
Definition pgpa_ast.h:93
@ PGPA_TAG_SEMIJOIN_NON_UNIQUE
Definition pgpa_ast.h:97
@ PGPA_TAG_BITMAP_HEAP_SCAN
Definition pgpa_ast.h:82
@ PGPA_TAG_PARTITIONWISE
Definition pgpa_ast.h:96
@ PGPA_TAG_NO_GATHER
Definition pgpa_ast.h:95
@ PGPA_TAG_INDEX_ONLY_SCAN
Definition pgpa_ast.h:87
@ PGPA_TAG_SEQ_SCAN
Definition pgpa_ast.h:99
@ PGPA_TAG_HASH_JOIN
Definition pgpa_ast.h:86
@ PGPA_TAG_SEMIJOIN_UNIQUE
Definition pgpa_ast.h:98
@ PGPA_TAG_JOIN_ORDER
Definition pgpa_ast.h:89
@ PGPA_TAG_TID_SCAN
Definition pgpa_ast.h:100
@ PGPA_TAG_FOREIGN_JOIN
Definition pgpa_ast.h:83
@ PGPA_TAG_NESTED_LOOP_PLAIN
Definition pgpa_ast.h:94
@ PGPA_TAG_MERGE_JOIN_MATERIALIZE
Definition pgpa_ast.h:90
static int fb(int x)

References fb(), pg_unreachable, PGPA_TAG_BITMAP_HEAP_SCAN, PGPA_TAG_FOREIGN_JOIN, PGPA_TAG_GATHER, PGPA_TAG_GATHER_MERGE, PGPA_TAG_HASH_JOIN, PGPA_TAG_INDEX_ONLY_SCAN, PGPA_TAG_INDEX_SCAN, PGPA_TAG_JOIN_ORDER, PGPA_TAG_MERGE_JOIN_MATERIALIZE, PGPA_TAG_MERGE_JOIN_PLAIN, PGPA_TAG_NESTED_LOOP_MATERIALIZE, PGPA_TAG_NESTED_LOOP_MEMOIZE, PGPA_TAG_NESTED_LOOP_PLAIN, PGPA_TAG_NO_GATHER, PGPA_TAG_PARTITIONWISE, PGPA_TAG_SEMIJOIN_NON_UNIQUE, PGPA_TAG_SEMIJOIN_UNIQUE, PGPA_TAG_SEQ_SCAN, and PGPA_TAG_TID_SCAN.

Referenced by pgpa_cstring_trove_entry().

◆ pgpa_format_advice_target()

void pgpa_format_advice_target ( StringInfo  str,
pgpa_advice_target target 
)

Definition at line 164 of file pgpa_ast.c.

165{
166 if (target->ttype != PGPA_TARGET_IDENTIFIER)
167 {
168 bool first = true;
169 char *delims;
170
171 if (target->ttype == PGPA_TARGET_UNORDERED_LIST)
172 delims = "{}";
173 else
174 delims = "()";
175
178 {
179 if (first)
180 first = false;
181 else
184 }
186 }
187 else
188 {
189 const char *rt_identifier;
190
193 }
194}
const char * str
#define foreach_ptr(type, var, lst)
Definition pg_list.h:469
void pgpa_format_advice_target(StringInfo str, pgpa_advice_target *target)
Definition pgpa_ast.c:164
@ PGPA_TARGET_UNORDERED_LIST
Definition pgpa_ast.h:29
@ PGPA_TARGET_IDENTIFIER
Definition pgpa_ast.h:27
const char * pgpa_identifier_string(const pgpa_identifier *rid)
void appendStringInfoString(StringInfo str, const char *s)
Definition stringinfo.c:230
void appendStringInfoChar(StringInfo str, char ch)
Definition stringinfo.c:242
pgpa_identifier rid
Definition pgpa_ast.h:58
pgpa_target_type ttype
Definition pgpa_ast.h:49

References appendStringInfoChar(), appendStringInfoString(), pgpa_advice_target::children, fb(), foreach_ptr, pgpa_format_advice_target(), pgpa_identifier_string(), PGPA_TARGET_IDENTIFIER, PGPA_TARGET_UNORDERED_LIST, pgpa_advice_target::rid, str, and pgpa_advice_target::ttype.

Referenced by pgpa_cstring_trove_entry(), and pgpa_format_advice_target().

◆ pgpa_format_index_target()

void pgpa_format_index_target ( StringInfo  str,
pgpa_index_target itarget 
)

Definition at line 200 of file pgpa_ast.c.

201{
202 if (itarget->indnamespace != NULL)
203 appendStringInfo(str, "%s.",
206}
const char * quote_identifier(const char *ident)
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition stringinfo.c:145
char * indnamespace
Definition pgpa_ast.h:38

References appendStringInfo(), appendStringInfoString(), fb(), pgpa_index_target::indname, pgpa_index_target::indnamespace, quote_identifier(), and str.

Referenced by pgpa_cstring_trove_entry().

◆ pgpa_identifier_matches_target()

bool pgpa_identifier_matches_target ( pgpa_identifier rid,
pgpa_advice_target target 
)

Definition at line 229 of file pgpa_ast.c.

230{
231 /* For non-identifiers, check all descendants. */
232 if (target->ttype != PGPA_TARGET_IDENTIFIER)
233 {
235 {
237 return true;
238 }
239 return false;
240 }
241
242 /* Straightforward comparisons of alias name and occurrence number. */
243 if (strcmp(rid->alias_name, target->rid.alias_name) != 0)
244 return false;
245 if (rid->occurrence != target->rid.occurrence)
246 return false;
247
248 /*
249 * If a relation identifier mentions a partition name, it should also
250 * specify a partition schema. But the target may leave the schema NULL to
251 * match anything.
252 */
253 Assert(rid->partnsp != NULL || rid->partrel == NULL);
254 if (rid->partnsp != NULL && target->rid.partnsp != NULL &&
255 strcmp(rid->partnsp, target->rid.partnsp) != 0)
256 return false;
257
258 /*
259 * These fields can be NULL on either side, but NULL only matches another
260 * NULL.
261 */
262 if (!strings_equal_or_both_null(rid->partrel, target->rid.partrel))
263 return false;
265 return false;
266
267 return true;
268}
#define Assert(condition)
Definition c.h:927
bool pgpa_identifier_matches_target(pgpa_identifier *rid, pgpa_advice_target *target)
Definition pgpa_ast.c:229
static bool strings_equal_or_both_null(const char *a, const char *b)
const char * alias_name
const char * partnsp
const char * partrel
const char * plan_name

References pgpa_identifier::alias_name, Assert, pgpa_advice_target::children, fb(), foreach_ptr, pgpa_identifier::occurrence, pgpa_identifier::partnsp, pgpa_identifier::partrel, pgpa_identifier_matches_target(), PGPA_TARGET_IDENTIFIER, pgpa_identifier::plan_name, pgpa_advice_target::rid, strings_equal_or_both_null(), and pgpa_advice_target::ttype.

Referenced by pgpa_identifier_matches_target(), pgpa_identifiers_cover_target(), and pgpa_trove_slice_lookup().

◆ pgpa_identifiers_cover_target()

static bool pgpa_identifiers_cover_target ( int  nrids,
pgpa_identifier rids,
pgpa_advice_target target,
bool rids_used 
)
static

Definition at line 322 of file pgpa_ast.c.

324{
325 bool result = false;
326
327 if (target->ttype != PGPA_TARGET_IDENTIFIER)
328 {
329 result = true;
330
332 {
334 rids_used))
335 result = false;
336 }
337 }
338 else
339 {
340 for (int i = 0; i < nrids; ++i)
341 {
342 if (pgpa_identifier_matches_target(&rids[i], target))
343 {
344 rids_used[i] = true;
345 result = true;
346 }
347 }
348 }
349
350 return result;
351}
int i
Definition isn.c:77
static bool pgpa_identifiers_cover_target(int nrids, pgpa_identifier *rids, pgpa_advice_target *target, bool *rids_used)
Definition pgpa_ast.c:322

References pgpa_advice_target::children, fb(), foreach_ptr, i, pgpa_identifier_matches_target(), pgpa_identifiers_cover_target(), PGPA_TARGET_IDENTIFIER, and pgpa_advice_target::ttype.

Referenced by pgpa_identifiers_cover_target(), and pgpa_identifiers_match_target().

◆ pgpa_identifiers_match_target()

pgpa_itm_type pgpa_identifiers_match_target ( int  nrids,
pgpa_identifier rids,
pgpa_advice_target target 
)

Definition at line 277 of file pgpa_ast.c.

279{
280 bool all_rids_used = true;
281 bool any_rids_used = false;
282 bool all_targets_used;
283 bool *rids_used = palloc0_array(bool, nrids);
284
287
288 for (int i = 0; i < nrids; ++i)
289 {
290 if (rids_used[i])
291 any_rids_used = true;
292 else
293 all_rids_used = false;
294 }
295
296 if (all_rids_used)
297 {
299 return PGPA_ITM_EQUAL;
300 else
302 }
303 else
304 {
307 else if (any_rids_used)
309 else
310 return PGPA_ITM_DISJOINT;
311 }
312}
#define palloc0_array(type, count)
Definition fe_memutils.h:77
@ PGPA_ITM_EQUAL
Definition pgpa_ast.h:142
@ PGPA_ITM_DISJOINT
Definition pgpa_ast.h:146
@ PGPA_ITM_KEYS_ARE_SUBSET
Definition pgpa_ast.h:143
@ PGPA_ITM_TARGETS_ARE_SUBSET
Definition pgpa_ast.h:144
@ PGPA_ITM_INTERSECTING
Definition pgpa_ast.h:145

References fb(), i, palloc0_array, pgpa_identifiers_cover_target(), PGPA_ITM_DISJOINT, PGPA_ITM_EQUAL, PGPA_ITM_INTERSECTING, PGPA_ITM_KEYS_ARE_SUBSET, and PGPA_ITM_TARGETS_ARE_SUBSET.

Referenced by pgpa_join_method_permits_join(), pgpa_join_order_permits_join(), pgpa_opaque_join_permits_join(), pgpa_planner_apply_join_path_advice(), pgpa_planner_apply_joinrel_advice(), and pgpa_semijoin_permits_join().

◆ pgpa_index_targets_equal()

bool pgpa_index_targets_equal ( pgpa_index_target i1,
pgpa_index_target i2 
)

Definition at line 212 of file pgpa_ast.c.

213{
214 /* indnamespace can be NULL, and two NULL values are equal */
215 if ((i1->indnamespace != NULL || i2->indnamespace != NULL) &&
216 (i1->indnamespace == NULL || i2->indnamespace == NULL ||
217 strcmp(i1->indnamespace, i2->indnamespace) != 0))
218 return false;
219 if (strcmp(i1->indname, i2->indname) != 0)
220 return false;
221
222 return true;
223}

References fb(), pgpa_index_target::indname, and pgpa_index_target::indnamespace.

Referenced by pgpa_planner_apply_scan_advice().

◆ pgpa_parse_advice_tag()

pgpa_advice_tag_type pgpa_parse_advice_tag ( const char tag,
bool fail 
)

Definition at line 85 of file pgpa_ast.c.

86{
87 *fail = false;
88
89 switch (tag[0])
90 {
91 case 'b':
92 if (strcmp(tag, "bitmap_heap_scan") == 0)
94 break;
95 case 'f':
96 if (strcmp(tag, "foreign_join") == 0)
98 break;
99 case 'g':
100 if (strcmp(tag, "gather") == 0)
101 return PGPA_TAG_GATHER;
102 if (strcmp(tag, "gather_merge") == 0)
104 break;
105 case 'h':
106 if (strcmp(tag, "hash_join") == 0)
107 return PGPA_TAG_HASH_JOIN;
108 break;
109 case 'i':
110 if (strcmp(tag, "index_scan") == 0)
111 return PGPA_TAG_INDEX_SCAN;
112 if (strcmp(tag, "index_only_scan") == 0)
114 break;
115 case 'j':
116 if (strcmp(tag, "join_order") == 0)
117 return PGPA_TAG_JOIN_ORDER;
118 break;
119 case 'm':
120 if (strcmp(tag, "merge_join_materialize") == 0)
122 if (strcmp(tag, "merge_join_plain") == 0)
124 break;
125 case 'n':
126 if (strcmp(tag, "nested_loop_materialize") == 0)
128 if (strcmp(tag, "nested_loop_memoize") == 0)
130 if (strcmp(tag, "nested_loop_plain") == 0)
132 if (strcmp(tag, "no_gather") == 0)
133 return PGPA_TAG_NO_GATHER;
134 break;
135 case 'p':
136 if (strcmp(tag, "partitionwise") == 0)
138 break;
139 case 's':
140 if (strcmp(tag, "semijoin_non_unique") == 0)
142 if (strcmp(tag, "semijoin_unique") == 0)
144 if (strcmp(tag, "seq_scan") == 0)
145 return PGPA_TAG_SEQ_SCAN;
146 break;
147 case 't':
148 if (strcmp(tag, "tid_scan") == 0)
149 return PGPA_TAG_TID_SCAN;
150 break;
151 }
152
153 /* didn't work out */
154 *fail = true;
155
156 /* return an arbitrary value to unwind the call stack */
157 return PGPA_TAG_SEQ_SCAN;
158}

References fb(), PGPA_TAG_BITMAP_HEAP_SCAN, PGPA_TAG_FOREIGN_JOIN, PGPA_TAG_GATHER, PGPA_TAG_GATHER_MERGE, PGPA_TAG_HASH_JOIN, PGPA_TAG_INDEX_ONLY_SCAN, PGPA_TAG_INDEX_SCAN, PGPA_TAG_JOIN_ORDER, PGPA_TAG_MERGE_JOIN_MATERIALIZE, PGPA_TAG_MERGE_JOIN_PLAIN, PGPA_TAG_NESTED_LOOP_MATERIALIZE, PGPA_TAG_NESTED_LOOP_MEMOIZE, PGPA_TAG_NESTED_LOOP_PLAIN, PGPA_TAG_NO_GATHER, PGPA_TAG_PARTITIONWISE, PGPA_TAG_SEMIJOIN_NON_UNIQUE, PGPA_TAG_SEMIJOIN_UNIQUE, PGPA_TAG_SEQ_SCAN, and PGPA_TAG_TID_SCAN.