102 const char *query_string,
104 double *tuple_fraction,
202 int cursorOptions,
double *tuple_fraction,
208 bool generate_advice_feedback =
false;
209 bool generate_advice_string =
false;
221 if (generate_advice_string)
248 errmsg(
"could not parse supplied advice: %s",
error));
265 generate_advice_feedback =
true;
285 pps->generate_advice_feedback = generate_advice_feedback;
286 pps->generate_advice_string = generate_advice_string;
293 (*prev_planner_setup) (glob,
parse, query_string, cursorOptions,
307 bool generate_advice_feedback =
false;
308 bool generate_advice_string =
false;
318 generate_advice_feedback =
pps->generate_advice_feedback;
319 generate_advice_string =
pps->generate_advice_string;
333 if (generate_advice_string || generate_advice_feedback)
340 if (generate_advice_string)
361 if (generate_advice_feedback)
398 (*prev_planner_shutdown) (glob,
parse, query_string, pstmt);
453 (
errmsg(
"strategy mask for RTI %u in subplan \"%s\" changed from 0x%" PRIx64 " to 0x%" PRIx64,
467 (*prev_build_simple_rel) (
root, rel,
rte);
504 (
errmsg(
"strategy mask for join on RTIs %s in subplan \"%s\" changed from 0x%" PRIx64 " to 0x%" PRIx64,
520 (*prev_joinrel_setup) (
root, joinrel, outerrel, innerrel,
521 sjinfo, restrictlist);
549 (
pps->generate_advice_string ||
pps->generate_advice_feedback))
590 (
errmsg(
"strategy mask for %s join on %s with outer %s and inner %s in subplan \"%s\" changed from 0x%" PRIx64 " to 0x%" PRIx64,
600 (
errmsg(
"strategy mask for %s join on %s with outer %s and inner %s changed from 0x%" PRIx64 " to 0x%" PRIx64,
612 (*prev_join_path_setup) (
root, joinrel, outerrel, innerrel,
656 if (
pjs->outerrel == outerrel &&
pjs->innerrel == innerrel)
684 pjs->outerrel = outerrel;
685 pjs->innerrel = innerrel;
690 pjs->rids +
pjs->outer_count);
704 pjs->outer_count +
pjs->inner_count,
705 pjs->rids, &tresult);
711 pjs->outer_count +
pjs->inner_count,
712 pjs->rids, &tresult);
981 pjs->rids +
pjs->outer_count,
1809 index->disabled =
true;
1871 for (
int i = 0;
i < nentries; ++
i)
1945 errmsg(
"supplied plan advice was not enforced"),
1967 if (
pps->last_proot->plan_name ==
NULL)
1968 return pps->last_proot;
1981 if (
pps->last_proot->plan_name !=
NULL &&
1983 return pps->last_proot;
2002 new_proot->alternative_plan_name =
root->alternative_plan_name;
2050 if (
proot->rid_array_size == 0)
2055 proot->rid_array_size,
2112 proot->has_rtoffset =
true;
2127#ifdef USE_ASSERT_CHECKING
2137 if (!
proot->has_rtoffset)
2140 for (
int rti = 1; rti <=
proot->rid_array_size; ++rti)
2207 return "right semi";
2209 return "right anti";
2211 return "unique outer";
2213 return "unique inner";
int bms_next_member(const Bitmapset *a, int prevbit)
int bms_num_members(const Bitmapset *a)
Bitmapset * bms_add_member(Bitmapset *a, int x)
BMS_Membership bms_membership(const Bitmapset *a)
Bitmapset * bms_copy(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_array(type, count)
#define palloc0_array(type, count)
#define palloc0_object(type)
join_path_setup_hook_type join_path_setup_hook
List * lappend(List *list, void *datum)
void list_free(List *list)
bool list_member(const List *list, const void *datum)
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
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
#define repalloc0_array(pointer, type, oldcount, count)
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 uint32 pg_nextpower2_32(uint32 num)
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)
static bool strings_equal_or_both_null(const char *a, const char *b)
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 void pgpa_compute_rt_offsets(pgpa_planner_state *pps, PlannedStmt *pstmt)
static pgpa_planner_info * pgpa_planner_get_proot(pgpa_planner_state *pps, PlannerInfo *root)
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_build_simple_rel(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
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_validate_rt_identifiers(pgpa_planner_state *pps, PlannedStmt *pstmt)
static void pgpa_compute_rt_identifier(pgpa_planner_info *proot, PlannerInfo *root, RelOptInfo *rel)
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
void pgpa_plan_walker(pgpa_plan_walker_context *walker, PlannedStmt *pstmt, List *proots)
bool pgpa_walker_would_advise(pgpa_plan_walker_context *walker, pgpa_identifier *rt_identifiers, pgpa_advice_tag_type tag, pgpa_advice_target *target)
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
pgpa_planner_info * last_proot
bool generate_advice_string
bool generate_advice_feedback
pgpa_advice_target * target
pgpa_trove_entry * entries
Integer * makeInteger(int i)
String * makeString(char *str)