PostgreSQL Source Code git master
Loading...
Searching...
No Matches
pgpa_ast.h File Reference
#include "pgpa_identifier.h"
#include "nodes/pg_list.h"
Include dependency graph for pgpa_ast.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  pgpa_index_target
 
struct  pgpa_advice_target
 
struct  pgpa_advice_item
 

Macros

#define YY_TYPEDEF_YY_SCANNER_T
 

Typedefs

typedef struct pgpa_index_target pgpa_index_target
 
typedef struct pgpa_advice_target pgpa_advice_target
 
typedef enum pgpa_advice_tag_type pgpa_advice_tag_type
 
typedef struct pgpa_advice_item pgpa_advice_item
 
typedef voidyyscan_t
 

Enumerations

enum  pgpa_target_type { PGPA_TARGET_IDENTIFIER , PGPA_TARGET_ORDERED_LIST , PGPA_TARGET_UNORDERED_LIST }
 
enum  pgpa_advice_tag_type {
  PGPA_TAG_BITMAP_HEAP_SCAN , PGPA_TAG_DO_NOT_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 , PGPA_TAG_TID_SCAN
}
 
enum  pgpa_itm_type {
  PGPA_ITM_EQUAL , PGPA_ITM_KEYS_ARE_SUBSET , PGPA_ITM_TARGETS_ARE_SUBSET , PGPA_ITM_INTERSECTING ,
  PGPA_ITM_DISJOINT
}
 

Functions

int pgpa_yylex (union YYSTYPE *yylval_param, List **result, char **parse_error_msg_p, yyscan_t yyscanner)
 
void pgpa_yyerror (List **result, char **parse_error_msg_p, yyscan_t yyscanner, const char *message)
 
void pgpa_scanner_init (const char *str, yyscan_t *yyscannerp)
 
void pgpa_scanner_finish (yyscan_t yyscanner)
 
int pgpa_yyparse (List **result, char **parse_error_msg_p, yyscan_t yyscanner)
 
Listpgpa_parse (const char *advice_string, char **error_p)
 
charpgpa_cstring_advice_tag (pgpa_advice_tag_type advice_tag)
 
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)
 
bool pgpa_index_targets_equal (pgpa_index_target *i1, pgpa_index_target *i2)
 
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)
 

Macro Definition Documentation

◆ YY_TYPEDEF_YY_SCANNER_T

#define YY_TYPEDEF_YY_SCANNER_T

Definition at line 153 of file pgpa_ast.h.

Typedef Documentation

◆ pgpa_advice_item

◆ pgpa_advice_tag_type

◆ pgpa_advice_target

◆ pgpa_index_target

◆ yyscan_t

Definition at line 154 of file pgpa_ast.h.

Enumeration Type Documentation

◆ pgpa_advice_tag_type

Enumerator
PGPA_TAG_BITMAP_HEAP_SCAN 
PGPA_TAG_DO_NOT_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 
PGPA_TAG_TID_SCAN 

Definition at line 80 of file pgpa_ast.h.

81{
pgpa_advice_tag_type
Definition pgpa_ast.h:81
@ PGPA_TAG_INDEX_SCAN
Definition pgpa_ast.h:89
@ PGPA_TAG_NESTED_LOOP_MATERIALIZE
Definition pgpa_ast.h:93
@ PGPA_TAG_MERGE_JOIN_PLAIN
Definition pgpa_ast.h:92
@ PGPA_TAG_GATHER_MERGE
Definition pgpa_ast.h:86
@ PGPA_TAG_GATHER
Definition pgpa_ast.h:85
@ PGPA_TAG_NESTED_LOOP_MEMOIZE
Definition pgpa_ast.h:94
@ PGPA_TAG_SEMIJOIN_NON_UNIQUE
Definition pgpa_ast.h:98
@ PGPA_TAG_BITMAP_HEAP_SCAN
Definition pgpa_ast.h:82
@ PGPA_TAG_PARTITIONWISE
Definition pgpa_ast.h:97
@ PGPA_TAG_NO_GATHER
Definition pgpa_ast.h:96
@ PGPA_TAG_INDEX_ONLY_SCAN
Definition pgpa_ast.h:88
@ PGPA_TAG_SEQ_SCAN
Definition pgpa_ast.h:100
@ PGPA_TAG_HASH_JOIN
Definition pgpa_ast.h:87
@ PGPA_TAG_SEMIJOIN_UNIQUE
Definition pgpa_ast.h:99
@ PGPA_TAG_DO_NOT_SCAN
Definition pgpa_ast.h:83
@ PGPA_TAG_JOIN_ORDER
Definition pgpa_ast.h:90
@ PGPA_TAG_TID_SCAN
Definition pgpa_ast.h:101
@ PGPA_TAG_FOREIGN_JOIN
Definition pgpa_ast.h:84
@ PGPA_TAG_NESTED_LOOP_PLAIN
Definition pgpa_ast.h:95
@ PGPA_TAG_MERGE_JOIN_MATERIALIZE
Definition pgpa_ast.h:91

◆ pgpa_itm_type

Enumerator
PGPA_ITM_EQUAL 
PGPA_ITM_KEYS_ARE_SUBSET 
PGPA_ITM_TARGETS_ARE_SUBSET 
PGPA_ITM_INTERSECTING 
PGPA_ITM_DISJOINT 

Definition at line 141 of file pgpa_ast.h.

142{
pgpa_itm_type
Definition pgpa_ast.h:142
@ PGPA_ITM_EQUAL
Definition pgpa_ast.h:143
@ PGPA_ITM_DISJOINT
Definition pgpa_ast.h:147
@ PGPA_ITM_KEYS_ARE_SUBSET
Definition pgpa_ast.h:144
@ PGPA_ITM_TARGETS_ARE_SUBSET
Definition pgpa_ast.h:145
@ PGPA_ITM_INTERSECTING
Definition pgpa_ast.h:146

◆ pgpa_target_type

Enumerator
PGPA_TARGET_IDENTIFIER 
PGPA_TARGET_ORDERED_LIST 
PGPA_TARGET_UNORDERED_LIST 

Definition at line 25 of file pgpa_ast.h.

26{
27 PGPA_TARGET_IDENTIFIER, /* relation identifier */
28 PGPA_TARGET_ORDERED_LIST, /* (item ...) */
29 PGPA_TARGET_UNORDERED_LIST /* {item ...} */
pgpa_target_type
Definition pgpa_ast.h:26
@ PGPA_TARGET_UNORDERED_LIST
Definition pgpa_ast.h:29
@ PGPA_TARGET_IDENTIFIER
Definition pgpa_ast.h:27
@ PGPA_TARGET_ORDERED_LIST
Definition pgpa_ast.h:28

Function Documentation

◆ pgpa_cstring_advice_tag()

char * pgpa_cstring_advice_tag ( pgpa_advice_tag_type  advice_tag)
extern

Definition at line 29 of file pgpa_ast.c.

30{
31 switch (advice_tag)
32 {
34 return "BITMAP_HEAP_SCAN";
36 return "DO_NOT_SCAN";
38 return "FOREIGN_JOIN";
39 case PGPA_TAG_GATHER:
40 return "GATHER";
42 return "GATHER_MERGE";
44 return "HASH_JOIN";
46 return "INDEX_ONLY_SCAN";
48 return "INDEX_SCAN";
50 return "JOIN_ORDER";
52 return "MERGE_JOIN_MATERIALIZE";
54 return "MERGE_JOIN_PLAIN";
56 return "NESTED_LOOP_MATERIALIZE";
58 return "NESTED_LOOP_MEMOIZE";
60 return "NESTED_LOOP_PLAIN";
62 return "NO_GATHER";
64 return "PARTITIONWISE";
66 return "SEMIJOIN_NON_UNIQUE";
68 return "SEMIJOIN_UNIQUE";
70 return "SEQ_SCAN";
72 return "TID_SCAN";
73 }
74
76 return NULL;
77}
#define pg_unreachable()
Definition c.h:367
static int fb(int x)

References fb(), pg_unreachable, PGPA_TAG_BITMAP_HEAP_SCAN, PGPA_TAG_DO_NOT_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 
)
extern

Definition at line 170 of file pgpa_ast.c.

171{
172 if (target->ttype != PGPA_TARGET_IDENTIFIER)
173 {
174 bool first = true;
175 char *delims;
176
177 if (target->ttype == PGPA_TARGET_UNORDERED_LIST)
178 delims = "{}";
179 else
180 delims = "()";
181
184 {
185 if (first)
186 first = false;
187 else
190 }
192 }
193 else
194 {
195 const char *rt_identifier;
196
199 }
200}
const char * str
#define foreach_ptr(type, var, lst)
Definition pg_list.h:501
void pgpa_format_advice_target(StringInfo str, pgpa_advice_target *target)
Definition pgpa_ast.c:170
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 
)
extern

Definition at line 206 of file pgpa_ast.c.

207{
208 if (itarget->indnamespace != NULL)
209 appendStringInfo(str, "%s.",
212}
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 
)
extern

Definition at line 235 of file pgpa_ast.c.

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

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

Definition at line 283 of file pgpa_ast.c.

285{
286 bool all_rids_used = true;
287 bool any_rids_used = false;
288 bool all_targets_used;
289 bool *rids_used = palloc0_array(bool, nrids);
290
293
294 for (int i = 0; i < nrids; ++i)
295 {
296 if (rids_used[i])
297 any_rids_used = true;
298 else
299 all_rids_used = false;
300 }
301
302 if (all_rids_used)
303 {
305 return PGPA_ITM_EQUAL;
306 else
308 }
309 else
310 {
313 else if (any_rids_used)
315 else
316 return PGPA_ITM_DISJOINT;
317 }
318}
#define palloc0_array(type, count)
Definition fe_memutils.h:77
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:328

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 
)
extern

Definition at line 218 of file pgpa_ast.c.

219{
220 /* indnamespace can be NULL, and two NULL values are equal */
221 if ((i1->indnamespace != NULL || i2->indnamespace != NULL) &&
222 (i1->indnamespace == NULL || i2->indnamespace == NULL ||
223 strcmp(i1->indnamespace, i2->indnamespace) != 0))
224 return false;
225 if (strcmp(i1->indname, i2->indname) != 0)
226 return false;
227
228 return true;
229}

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

Referenced by pgpa_planner_apply_scan_advice().

◆ pgpa_parse()

List * pgpa_parse ( const char advice_string,
char **  error_p 
)
extern

◆ pgpa_parse_advice_tag()

pgpa_advice_tag_type pgpa_parse_advice_tag ( const char tag,
bool fail 
)
extern

Definition at line 87 of file pgpa_ast.c.

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

References fb(), PGPA_TAG_BITMAP_HEAP_SCAN, PGPA_TAG_DO_NOT_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.

◆ pgpa_scanner_finish()

void pgpa_scanner_finish ( yyscan_t  yyscanner)
extern

Definition at line 267 of file pgpa_scanner.l.

268{
269 yylex_destroy(yyscanner);
270}

References fb().

◆ pgpa_scanner_init()

void pgpa_scanner_init ( const char str,
yyscan_t yyscannerp 
)
extern

Definition at line 244 of file pgpa_scanner.l.

245{
246 yyscan_t yyscanner;
248
249 if (yylex_init(yyscannerp) != 0)
250 elog(ERROR, "yylex_init() failed: %m");
251
252 yyscanner = *yyscannerp;
253
254 initStringInfo(&yyext->litbuf);
255 pgpa_yyset_extra(yyext, yyscanner);
256
257 yy_scan_string(str, yyscanner);
258}
void * yyscan_t
Definition cubedata.h:65
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:227
#define palloc0_object(type)
Definition fe_memutils.h:75
void initStringInfo(StringInfo str)
Definition stringinfo.c:97

References elog, ERROR, fb(), initStringInfo(), palloc0_object, and str.

◆ pgpa_yyerror()

void pgpa_yyerror ( List **  result,
char **  parse_error_msg_p,
yyscan_t  yyscanner,
const char message 
)
extern

Definition at line 221 of file pgpa_scanner.l.

223{
224 struct yyguts_t *yyg = (struct yyguts_t *) yyscanner; /* needed for yytext
225 * macro */
226
227
228 /* report only the first error in a parse operation */
230 return;
231
232 if (yytext[0])
233 *parse_error_msg_p = psprintf("%s at or near \"%s\"", message, yytext);
234 else
235 *parse_error_msg_p = psprintf("%s at end of input", message);
236}
char * psprintf(const char *fmt,...)
Definition psprintf.c:43

References fb(), and psprintf().

◆ pgpa_yylex()

int pgpa_yylex ( union YYSTYPE yylval_param,
List **  result,
char **  parse_error_msg_p,
yyscan_t  yyscanner 
)
extern

◆ pgpa_yyparse()

int pgpa_yyparse ( List **  result,
char **  parse_error_msg_p,
yyscan_t  yyscanner 
)
extern