Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow pushdown of reference table joins #5212

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -42,6 +42,7 @@ Sooner to that time, we will announce the specific version of TimescaleDB in whi
* #5262 Extend enabling compression on a continuous aggregrate with 'compress_segmentby' and 'compress_orderby' parameters
* #5343 Set PortalContext when starting job
* #5312 Add timeout support to the ping_data_node()
* #5212 Allow pushdown of reference table joins

**Bugfixes**
* #5214 Fix use of prepared statement in async module
Expand Down
8 changes: 8 additions & 0 deletions src/cross_module_fn.c
Expand Up @@ -402,6 +402,13 @@ ts_tsl_loaded(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(ts_cm_functions != &ts_cm_functions_default);
}

static void
mn_get_foreign_join_path_default_fn_pg_community(PlannerInfo *root, RelOptInfo *joinrel,
RelOptInfo *outerrel, RelOptInfo *innerrel,
JoinType jointype, JoinPathExtraData *extra)
{
}

/*
* Define cross-module functions' default values:
* If the submodule isn't activated, using one of the cm functions will throw an
Expand Down Expand Up @@ -555,6 +562,7 @@ TSDLLEXPORT CrossModuleFunctions ts_cm_functions_default = {
.hypertable_distributed_set_replication_factor = error_no_default_fn_pg_community,
.update_compressed_chunk_relstats = update_compressed_chunk_relstats_default,
.health_check = error_no_default_fn_pg_community,
.mn_get_foreign_join_paths = mn_get_foreign_join_path_default_fn_pg_community,
};

TSDLLEXPORT CrossModuleFunctions *ts_cm_functions = &ts_cm_functions_default;
3 changes: 3 additions & 0 deletions src/cross_module_fn.h
Expand Up @@ -203,6 +203,9 @@ typedef struct CrossModuleFunctions
PGFunction chunks_drop_stale;
void (*update_compressed_chunk_relstats)(Oid uncompressed_relid, Oid compressed_relid);
PGFunction health_check;
void (*mn_get_foreign_join_paths)(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outerrel,
RelOptInfo *innerrel, JoinType jointype,
JoinPathExtraData *extra);
} CrossModuleFunctions;

extern TSDLLEXPORT CrossModuleFunctions *ts_cm_functions;
Expand Down
25 changes: 25 additions & 0 deletions src/planner/planner.c
Expand Up @@ -110,6 +110,7 @@ void _planner_fini(void);

static planner_hook_type prev_planner_hook;
static set_rel_pathlist_hook_type prev_set_rel_pathlist_hook;
static set_join_pathlist_hook_type prev_set_join_pathlist_hook;
static get_relation_info_hook_type prev_get_relation_info_hook;
static create_upper_paths_hook_type prev_create_upper_paths_hook;
static void cagg_reorder_groupby_clause(RangeTblEntry *subq_rte, Index rtno, List *outer_sortcl,
Expand Down Expand Up @@ -1662,13 +1663,36 @@ cagg_reorder_groupby_clause(RangeTblEntry *subq_rte, Index rtno, List *outer_sor
}
}

/* Register our join pushdown hook. Becuase for PostgreSQL the tables we are operating
* on are local tables. So, the FDW hooks are not called. Register our join path
* generation as a generic planer hook.
*/

static void
timescaledb_set_join_pathlist_hook(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outerrel,
RelOptInfo *innerrel, JoinType jointype,
JoinPathExtraData *extra)
{
/* Left table has to be a distributed hypertable */
TimescaleDBPrivate *outerrel_private = outerrel->fdw_private;
if (outerrel_private != NULL && outerrel_private->fdw_relation_info != NULL)
ts_cm_functions
->mn_get_foreign_join_paths(root, joinrel, outerrel, innerrel, jointype, extra);

/* Call next hook in chain */
if (prev_set_join_pathlist_hook != NULL)
(*prev_set_join_pathlist_hook)(root, joinrel, outerrel, innerrel, jointype, extra);
}

void
_planner_init(void)
{
prev_planner_hook = planner_hook;
planner_hook = timescaledb_planner;
prev_set_rel_pathlist_hook = set_rel_pathlist_hook;
prev_set_join_pathlist_hook = set_join_pathlist_hook;
set_rel_pathlist_hook = timescaledb_set_rel_pathlist;
set_join_pathlist_hook = timescaledb_set_join_pathlist_hook;

prev_get_relation_info_hook = get_relation_info_hook;
get_relation_info_hook = timescaledb_get_relation_info_hook;
Expand All @@ -1682,6 +1706,7 @@ _planner_fini(void)
{
planner_hook = prev_planner_hook;
set_rel_pathlist_hook = prev_set_rel_pathlist_hook;
set_join_pathlist_hook = prev_set_join_pathlist_hook;
get_relation_info_hook = prev_get_relation_info_hook;
create_upper_paths_hook = prev_create_upper_paths_hook;
}