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

Add hook for OSM runtime chunk exclusion #6688

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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
44 changes: 44 additions & 0 deletions src/nodes/chunk_append/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
#include <optimizer/prep.h>
#include <optimizer/restrictinfo.h>
#include <parser/parsetree.h>
#include <parser/parse_expr.h>
#include <parser/parse_relation.h>
#include <parser/parse_coerce.h>
#include <parser/parse_collate.h>
#include <rewrite/rewriteManip.h>
#include <utils/builtins.h>
#include <utils/memutils.h>
Expand All @@ -30,6 +34,9 @@
#include "loader/lwlocks.h"
#include "planner/planner.h"
#include "transform.h"
#include "dimension_slice.h"
#include "chunk.h"
#include "osm_callbacks.h"

#define INVALID_SUBPLAN_INDEX (-1)
#define NO_MATCHING_SUBPLANS (-2)
Expand Down Expand Up @@ -256,6 +263,43 @@
}
restrictinfos = constify_restrictinfos(&root, restrictinfos);

#if PG14_GE
// this is where we run the OSM chunk exclusion code
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this code should be moved inside can_exclude_chunk
can_exclude_chunk will do the usual predicate_refuted_by for the chunk AND if it is an OSM chunk, it will execute this additional logic.

Then all callers of can_exclude_chunk will do the right thing.
WDYT @zilder @konskov

chunk_startup_exclusion_hook_type osm_chunk_exclusion_hook =
ts_get_osm_chunk_startup_exclusion_hook();

if (osm_chunk_exclusion_hook)
{
Index rt_index = scan->scanrelid;
EState *estate = state->csstate.ss.ps.state;
RangeTblEntry *rte = rt_fetch(rt_index, estate->es_range_table);

Check warning on line 275 in src/nodes/chunk_append/exec.c

View check run for this annotation

Codecov / codecov/patch

src/nodes/chunk_append/exec.c#L273-L275

Added lines #L273 - L275 were not covered by tests
// relation_constraints = ca_get_relation_constraints(rte->relid, rt_index, true);
// need to get chunk from the relid
Oid relid = rte->relid;
Chunk *chunk = ts_chunk_get_by_relid(relid, false);
Hypertable *ht = ts_hypertable_get_by_id(chunk->fd.hypertable_id);
int tiered_chunks_match = 0;

Check warning on line 281 in src/nodes/chunk_append/exec.c

View check run for this annotation

Codecov / codecov/patch

src/nodes/chunk_append/exec.c#L278-L281

Added lines #L278 - L281 were not covered by tests
// Index varno = rt_index;
if (chunk && IS_OSM_CHUNK(chunk))
{
tiered_chunks_match = osm_chunk_exclusion_hook(NameStr(ht->fd.schema_name),
NameStr(ht->fd.table_name),

Check warning on line 286 in src/nodes/chunk_append/exec.c

View check run for this annotation

Codecov / codecov/patch

src/nodes/chunk_append/exec.c#L285-L286

Added lines #L285 - L286 were not covered by tests
relid,
(ForeignScan *) scan,
restrictinfos,
rt_index);
if (tiered_chunks_match == 0)
{
// the OSM chunk can be skipped entirely
if (i < state->first_partial_plan)
filtered_first_partial_plan--;

Check warning on line 295 in src/nodes/chunk_append/exec.c

View check run for this annotation

Codecov / codecov/patch

src/nodes/chunk_append/exec.c#L295

Added line #L295 was not covered by tests

continue;

Check warning on line 297 in src/nodes/chunk_append/exec.c

View check run for this annotation

Codecov / codecov/patch

src/nodes/chunk_append/exec.c#L297

Added line #L297 was not covered by tests
}
}
// root->simple_rte_array[scan->scanrelid]->relid
}
#endif
if (can_exclude_chunk(lfirst(lc_constraints), restrictinfos))
{
if (i < state->first_partial_plan)
Expand Down
32 changes: 32 additions & 0 deletions src/nodes/constraint_aware_append/constraint_aware_append.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
#include "nodes/chunk_append/transform.h"
#include "guc.h"
#include "utils.h"
#include "osm_callbacks.h"
#include "chunk.h"

/*
* Exclude child relations (chunks) at execution time based on constraints.
Expand Down Expand Up @@ -255,7 +257,37 @@
restrictinfos = lappend(restrictinfos, ri);
}
restrictinfos = constify_restrictinfos(&root, restrictinfos);
#if PG14_GE
chunk_startup_exclusion_hook_type osm_chunk_exclusion_hook =
ts_get_osm_chunk_startup_exclusion_hook();

if (osm_chunk_exclusion_hook)
{
Index rt_index = scanrelid;
RangeTblEntry *rte = rt_fetch(rt_index, estate->es_range_table);
Oid relid = rte->relid;
Chunk *chunk = ts_chunk_get_by_relid(relid, false);
Hypertable *ht = ts_hypertable_get_by_id(chunk->fd.hypertable_id);
int tiered_chunks_match = 0;

Check warning on line 271 in src/nodes/constraint_aware_append/constraint_aware_append.c

View check run for this annotation

Codecov / codecov/patch

src/nodes/constraint_aware_append/constraint_aware_append.c#L266-L271

Added lines #L266 - L271 were not covered by tests
// Index varno = rt_index;
if (chunk && IS_OSM_CHUNK(chunk))
{
tiered_chunks_match = osm_chunk_exclusion_hook(NameStr(ht->fd.schema_name),
NameStr(ht->fd.table_name),

Check warning on line 276 in src/nodes/constraint_aware_append/constraint_aware_append.c

View check run for this annotation

Codecov / codecov/patch

src/nodes/constraint_aware_append/constraint_aware_append.c#L275-L276

Added lines #L275 - L276 were not covered by tests
relid,
(ForeignScan *) plan,
restrictinfos,
rt_index);
if (tiered_chunks_match == 0)
{
// the OSM chunk can be skipped entirely
continue;

Check warning on line 284 in src/nodes/constraint_aware_append/constraint_aware_append.c

View check run for this annotation

Codecov / codecov/patch

src/nodes/constraint_aware_append/constraint_aware_append.c#L284

Added line #L284 was not covered by tests
}
}
}
#endif
// this expects the chunk to already have check constraints, which are used in
// can_exclude_chunk -> calling relation_excluded_by_constraints
if (can_exclude_chunk(&root, estate, scanrelid, restrictinfos))
continue;

Expand Down
9 changes: 9 additions & 0 deletions src/osm_callbacks.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,12 @@
return ptr->hypertable_drop_chunks_hook;
return NULL;
}

chunk_startup_exclusion_hook_type
ts_get_osm_chunk_startup_exclusion_hook()
{
OsmCallbacks_Versioned *ptr = ts_get_osm_callbacks();
if (ptr && ptr->version_num == 1)
return ptr->chunk_startup_exclusion_hook;

Check warning on line 83 in src/osm_callbacks.c

View check run for this annotation

Codecov / codecov/patch

src/osm_callbacks.c#L83

Added line #L83 was not covered by tests
return NULL;
}
7 changes: 7 additions & 0 deletions src/osm_callbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <postgres.h>
#include <catalog/objectaddress.h>
#include <nodes/plannodes.h>

/* range_start and range_end are in PG internal timestamp format. */
typedef int (*chunk_insert_check_hook_type)(Oid ht_oid, int64 range_start, int64 range_end);
Expand All @@ -15,6 +16,10 @@ typedef List *(*hypertable_drop_chunks_hook_type)(Oid osm_chunk_oid,
const char *hypertable_schema_name,
const char *hypertable_name, int64 range_start,
int64 range_end);
typedef int (*chunk_startup_exclusion_hook_type)(const char *hypertable_schema_name,
const char *hypertable_name, Oid relid,
ForeignScan *scan, List *constified_restrictinfos,
int32 varno); // scan->plan->fdw_private

/*
* Object Storage Manager callbacks.
Expand All @@ -37,8 +42,10 @@ typedef struct
chunk_insert_check_hook_type chunk_insert_check_hook;
hypertable_drop_hook_type hypertable_drop_hook;
hypertable_drop_chunks_hook_type hypertable_drop_chunks_hook;
chunk_startup_exclusion_hook_type chunk_startup_exclusion_hook;
} OsmCallbacks_Versioned;

extern chunk_insert_check_hook_type ts_get_osm_chunk_insert_hook(void);
extern hypertable_drop_hook_type ts_get_osm_hypertable_drop_hook(void);
extern hypertable_drop_chunks_hook_type ts_get_osm_hypertable_drop_chunks_hook(void);
extern chunk_startup_exclusion_hook_type ts_get_osm_chunk_startup_exclusion_hook(void);