37#ifdef USE_ASSERT_CHECKING
64 if (
a.plan_name ==
NULL)
65 return (
b.plan_name ==
NULL);
66 if (
b.plan_name ==
NULL)
68 return strcmp(
a.plan_name,
b.plan_name) == 0;
71#define SH_PREFIX pgpa_ri_check
72#define SH_ELEMENT_TYPE pgpa_ri_checker
73#define SH_KEY_TYPE pgpa_ri_checker_key
75#define SH_HASH_KEY(tb, key) pgpa_ri_checker_hash_key(key)
76#define SH_EQUAL(tb, a, b) pgpa_ri_checker_compare_key(a, b)
77#define SH_SCOPE static inline
98#ifdef USE_ASSERT_CHECKING
151 const char *query_string,
153 double *tuple_fraction,
246 int cursorOptions,
double *tuple_fraction,
252 bool generate_advice_feedback =
false;
253 bool generate_advice_string =
false;
265 if (generate_advice_string)
292 errmsg(
"could not parse supplied advice: %s",
error));
309 generate_advice_feedback =
true;
313#ifdef USE_ASSERT_CHECKING
331 pps->generate_advice_feedback = generate_advice_feedback;
332 pps->generate_advice_string = generate_advice_string;
334#ifdef USE_ASSERT_CHECKING
343 (*prev_planner_setup) (glob,
parse, query_string, cursorOptions,
357 bool generate_advice_feedback =
false;
358 bool generate_advice_string =
false;
367 generate_advice_feedback =
pps->generate_advice_feedback;
368 generate_advice_string =
pps->generate_advice_string;
376 if (generate_advice_string || generate_advice_feedback)
383 if (generate_advice_string)
404 if (generate_advice_feedback)
448 (*prev_planner_shutdown) (glob,
parse, query_string, pstmt);
500 (
errmsg(
"strategy mask for RTI %u in subplan \"%s\" changed from 0x%" PRIx64 " to 0x%" PRIx64,
514 (*prev_build_simple_rel) (
root, rel,
rte);
551 (
errmsg(
"strategy mask for join on RTIs %s in subplan \"%s\" changed from 0x%" PRIx64 " to 0x%" PRIx64,
567 (*prev_joinrel_setup) (
root, joinrel, outerrel, innerrel,
568 sjinfo, restrictlist);
597 (
pps->generate_advice_string ||
pps->generate_advice_feedback))
608 if (
root->plan_name ==
ur->plan_name &&
621 ur->plan_name =
root->plan_name;
646 (
errmsg(
"strategy mask for %s join on %s with outer %s and inner %s in subplan \"%s\" changed from 0x%" PRIx64 " to 0x%" PRIx64,
656 (
errmsg(
"strategy mask for %s join on %s with outer %s and inner %s changed from 0x%" PRIx64 " to 0x%" PRIx64,
668 (*prev_join_path_setup) (
root, joinrel, outerrel, innerrel,
712 if (
pjs->outerrel == outerrel &&
pjs->innerrel == innerrel)
740 pjs->outerrel = outerrel;
741 pjs->innerrel = innerrel;
746 pjs->rids +
pjs->outer_count);
760 pjs->outer_count +
pjs->inner_count,
761 pjs->rids, &tresult);
767 pjs->outer_count +
pjs->inner_count,
768 pjs->rids, &tresult);
1037 pjs->rids +
pjs->outer_count,
1861 index->disabled =
true;
1929 for (
int i = 0;
i < nentries; ++
i)
2003 errmsg(
"supplied plan advice was not enforced"),
2007#ifdef USE_ASSERT_CHECKING
2042#ifdef USE_ASSERT_CHECKING
2050 key.plan_name =
root->plan_name;
2066#ifdef USE_ASSERT_CHECKING
2087 if (check->key.plan_name !=
NULL)
2110 if (
strcmp(check->key.plan_name,
rtinfo->plan_name) == 0
2113 rtoffset =
rtinfo->rtoffset;
2134 flat_rti = check->key.rti + rtoffset;
2189 return "right semi";
2191 return "right anti";
2193 return "unique outer";
2195 return "unique inner";
bool bms_equal(const Bitmapset *a, const Bitmapset *b)
int bms_next_member(const Bitmapset *a, int prevbit)
int bms_singleton_member(const Bitmapset *a)
int bms_num_members(const Bitmapset *a)
Bitmapset * bms_add_member(Bitmapset *a, int x)
BMS_Membership bms_membership(const Bitmapset *a)
#define Assert(condition)
int32 defGetInt32(DefElem *def)
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define ereport(elevel,...)
void SetRelOptInfoExtensionState(RelOptInfo *rel, int extension_id, void *opaque)
int GetPlannerExtensionId(const char *extension_name)
void SetPlannerGlobalExtensionState(PlannerGlobal *glob, int extension_id, void *opaque)
static void * GetPlannerGlobalExtensionState(PlannerGlobal *glob, int extension_id)
static void * GetRelOptInfoExtensionState(RelOptInfo *rel, int extension_id)
#define palloc_object(type)
#define palloc_array(type, count)
#define palloc0_object(type)
static size_t fasthash_accum_cstring(fasthash_state *hs, const char *str)
static uint32 fasthash_final32(fasthash_state *hs, uint64 tweak)
static void fasthash_combine(fasthash_state *hs)
static void fasthash_init(fasthash_state *hs, uint64 seed)
join_path_setup_hook_type join_path_setup_hook
List * lappend(List *list, void *datum)
void list_free(List *list)
List * list_copy_head(const List *oldlist, int len)
char * get_rel_name(Oid relid)
Oid get_rel_namespace(Oid relid)
char * get_namespace_name_or_temp(Oid nspid)
DefElem * makeDefElem(char *name, Node *arg, int location)
MemoryContext CurrentMemoryContext
void(* joinrel_setup_hook_type)(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outer_rel, RelOptInfo *inner_rel, SpecialJoinInfo *sjinfo, List *restrictlist)
void(* build_simple_rel_hook_type)(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
#define PGS_NESTLOOP_MEMOIZE
#define PGS_CONSIDER_INDEXONLY
#define PGS_NESTLOOP_MATERIALIZE
#define PGS_MERGEJOIN_PLAIN
#define PGS_MERGEJOIN_MATERIALIZE
#define PGS_CONSIDER_NONPARTIAL
#define PGS_INDEXONLYSCAN
#define PGS_NESTLOOP_PLAIN
void(* join_path_setup_hook_type)(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outerrel, RelOptInfo *innerrel, JoinType jointype, JoinPathExtraData *extra)
static int list_length(const List *l)
#define foreach_ptr(type, var, lst)
static void * list_nth(const List *list, int n)
#define foreach_node(type, var, lst)
bool pg_plan_advice_trace_mask
bool pg_plan_advice_always_store_advice_details
bool pg_plan_advice_should_explain(ExplainState *es)
char * pg_plan_advice_get_supplied_query_advice(PlannerGlobal *glob, Query *parse, const char *query_string, int cursorOptions, ExplainState *es)
bool pg_plan_advice_feedback_warnings
static char buf[DEFAULT_XLOG_SEG_SIZE]
bool pgpa_index_targets_equal(pgpa_index_target *i1, pgpa_index_target *i2)
pgpa_itm_type pgpa_identifiers_match_target(int nrids, pgpa_identifier *rids, pgpa_advice_target *target)
@ PGPA_TAG_NESTED_LOOP_MATERIALIZE
@ PGPA_TAG_MERGE_JOIN_PLAIN
@ PGPA_TAG_NESTED_LOOP_MEMOIZE
@ PGPA_TAG_SEMIJOIN_NON_UNIQUE
@ PGPA_TAG_BITMAP_HEAP_SCAN
@ PGPA_TAG_INDEX_ONLY_SCAN
@ PGPA_TAG_SEMIJOIN_UNIQUE
@ PGPA_TAG_NESTED_LOOP_PLAIN
@ PGPA_TAG_MERGE_JOIN_MATERIALIZE
List * pgpa_parse(const char *advice_string, char **error_p)
@ PGPA_TARGET_UNORDERED_LIST
@ PGPA_TARGET_ORDERED_LIST
@ PGPA_ITM_KEYS_ARE_SUBSET
@ PGPA_ITM_TARGETS_ARE_SUBSET
void pgpa_compute_identifier_by_rti(PlannerInfo *root, Index rti, pgpa_identifier *rid)
pgpa_identifier * pgpa_create_identifiers_for_planned_stmt(PlannedStmt *pstmt)
int pgpa_compute_identifiers_by_relids(PlannerInfo *root, Bitmapset *relids, pgpa_identifier *rids)
const char * pgpa_identifier_string(const pgpa_identifier *rid)
void pgpa_output_advice(StringInfo buf, pgpa_plan_walker_context *walker, pgpa_identifier *rt_identifiers)
static void pgpa_planner_shutdown(PlannerGlobal *glob, Query *parse, const char *query_string, PlannedStmt *pstmt)
static planner_setup_hook_type prev_planner_setup
void pgpa_planner_install_hooks(void)
static void pgpa_planner_apply_scan_advice(RelOptInfo *rel, pgpa_trove_entry *scan_entries, Bitmapset *scan_indexes, pgpa_trove_entry *rel_entries, Bitmapset *rel_indexes)
static pgpa_join_state * pgpa_get_join_state(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outerrel, RelOptInfo *innerrel)
static joinrel_setup_hook_type prev_joinrel_setup
static build_simple_rel_hook_type prev_build_simple_rel
static void pgpa_ri_checker_validate(pgpa_planner_state *pps, PlannedStmt *pstmt)
static void pgpa_build_simple_rel(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
static void pgpa_ri_checker_save(pgpa_planner_state *pps, PlannerInfo *root, RelOptInfo *rel)
static bool pgpa_opaque_join_permits_join(int outer_count, int inner_count, pgpa_identifier *rids, pgpa_trove_entry *entry, bool *restrict_method)
static void pgpa_planner_setup(PlannerGlobal *glob, Query *parse, const char *query_string, int cursorOptions, double *tuple_fraction, ExplainState *es)
int pgpa_planner_generate_advice
static planner_shutdown_hook_type prev_planner_shutdown
static char * pgpa_bms_to_cstring(Bitmapset *bms)
static int planner_extension_id
static pgpa_jo_outcome pgpa_join_order_permits_join(int outer_count, int inner_count, pgpa_identifier *rids, pgpa_trove_entry *entry)
static bool pgpa_join_method_permits_join(int outer_count, int inner_count, pgpa_identifier *rids, pgpa_trove_entry *entry, bool *restrict_method)
static uint64 pgpa_join_strategy_mask_from_advice_tag(pgpa_advice_tag_type tag)
static const char * pgpa_jointype_to_cstring(JoinType jointype)
static List * pgpa_planner_append_feedback(List *list, pgpa_trove *trove, pgpa_trove_lookup_type type, pgpa_identifier *rt_identifiers, pgpa_plan_walker_context *walker)
static void pgpa_planner_feedback_warning(List *feedback)
static void pgpa_join_path_setup(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outerrel, RelOptInfo *innerrel, JoinType jointype, JoinPathExtraData *extra)
static bool pgpa_semijoin_permits_join(int outer_count, int inner_count, pgpa_identifier *rids, pgpa_trove_entry *entry, bool outer_is_nullable, bool *restrict_method)
static void pgpa_joinrel_setup(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outerrel, RelOptInfo *innerrel, SpecialJoinInfo *sjinfo, List *restrictlist)
static void pgpa_planner_apply_joinrel_advice(uint64 *pgs_mask_p, char *plan_name, pgpa_join_state *pjs)
static void pgpa_planner_apply_join_path_advice(JoinType jointype, uint64 *pgs_mask_p, char *plan_name, pgpa_join_state *pjs)
static join_path_setup_hook_type prev_join_path_setup
void pgpa_trove_set_flags(pgpa_trove_entry *entries, Bitmapset *indexes, int flags)
pgpa_trove * pgpa_build_trove(List *advice_items)
void pgpa_trove_append_flags(StringInfo buf, int flags)
void pgpa_trove_lookup_all(pgpa_trove *trove, pgpa_trove_lookup_type type, pgpa_trove_entry **entries, int *nentries)
char * pgpa_cstring_trove_entry(pgpa_trove_entry *entry)
void pgpa_trove_lookup(pgpa_trove *trove, pgpa_trove_lookup_type type, int nrids, pgpa_identifier *rids, pgpa_trove_result *result)
#define PGPA_TE_INAPPLICABLE
#define PGPA_TE_MATCH_FULL
#define PGPA_TE_MATCH_PARTIAL
#define PGPA_TE_CONFLICTING
bool pgpa_walker_would_advise(pgpa_plan_walker_context *walker, pgpa_identifier *rt_identifiers, pgpa_advice_tag_type tag, pgpa_advice_target *target)
void pgpa_plan_walker(pgpa_plan_walker_context *walker, PlannedStmt *pstmt, List *sj_unique_rels)
planner_shutdown_hook_type planner_shutdown_hook
planner_setup_hook_type planner_setup_hook
void(* planner_setup_hook_type)(PlannerGlobal *glob, Query *parse, const char *query_string, int cursorOptions, double *tuple_fraction, ExplainState *es)
void(* planner_shutdown_hook_type)(PlannerGlobal *glob, Query *parse, const char *query_string, PlannedStmt *pstmt)
joinrel_setup_hook_type joinrel_setup_hook
build_simple_rel_hook_type build_simple_rel_hook
void resetStringInfo(StringInfo str)
void appendStringInfo(StringInfo str, const char *fmt,...)
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
pgpa_trove_entry * join_entries
pgpa_trove_entry * rel_entries
bool generate_advice_string
bool generate_advice_feedback
pgpa_advice_target * target
pgpa_trove_entry * entries
Integer * makeInteger(int i)
String * makeString(char *str)