Move FK query handling into own function

Split off the code for dealing with FK queries into own function.
No code is changed within this PR just moved around.
This commit is contained in:
Sven Klemm 2025-02-17 21:31:17 +01:00 committed by Sven Klemm
parent 424642a26e
commit 0be697a4b1

View File

@ -288,6 +288,8 @@ typedef struct
PlannerInfo *root;
} PreprocessQueryContext;
static void preprocess_fk_checks(Query *query, Cache *hcache, PreprocessQueryContext *context);
void
replace_now_mock_walker(PlannerInfo *root, Node *clause, Oid funcid)
{
@ -399,6 +401,81 @@ preprocess_query(Node *node, PreprocessQueryContext *context)
Index rti = 1;
bool ret;
if (ts_guc_enable_foreign_key_propagation)
{
preprocess_fk_checks(query, hcache, context);
}
foreach (lc, query->rtable)
{
RangeTblEntry *rte = lfirst_node(RangeTblEntry, lc);
Hypertable *ht;
switch (rte->rtekind)
{
case RTE_SUBQUERY:
if (ts_guc_enable_optimizations && ts_guc_enable_cagg_reorder_groupby &&
query->commandType == CMD_SELECT)
{
/* applicable to selects on continuous aggregates */
List *outer_tlist = query->targetList;
List *outer_sortcl = query->sortClause;
cagg_reorder_groupby_clause(rte, rti, outer_sortcl, outer_tlist);
}
break;
case RTE_RELATION:
/* This lookup will warm the cache with all hypertables in the query */
ht = ts_hypertable_cache_get_entry(hcache, rte->relid, CACHE_FLAG_MISSING_OK);
if (ht)
{
/* Mark hypertable RTEs we'd like to expand ourselves */
if (ts_guc_enable_optimizations && ts_guc_enable_constraint_exclusion &&
!IS_UPDL_CMD(context->rootquery) && query->resultRelation == 0 &&
query->rowMarks == NIL && rte->inh)
rte_mark_for_expansion(rte);
if (TS_HYPERTABLE_HAS_COMPRESSION_TABLE(ht))
{
int compr_htid = ht->fd.compressed_hypertable_id;
/* Also warm the cache with the compressed
* companion hypertable */
ts_hypertable_cache_get_entry_by_id(hcache, compr_htid);
}
}
else
{
/* To properly keep track of SELECT FROM ONLY <chunk> we
* have to mark the rte here because postgres will set
* rte->inh to false (when it detects the chunk has no
* children which is true for all our chunks) before it
* reaches set_rel_pathlist hook. But chunks from queries
* like SELECT .. FROM ONLY <chunk> has rte->inh set to
* false and other chunks have rte->inh set to true.
* We want to distinguish between the two cases here by
* marking the chunk when rte->inh is true.
*/
Chunk *chunk = ts_chunk_get_by_relid(rte->relid, false);
if (chunk && rte->inh)
rte_mark_for_expansion(rte);
}
break;
default:
break;
}
rti++;
}
prev_query = context->current_query;
context->current_query = query;
ret = query_tree_walker(query, preprocess_query, context, 0);
context->current_query = prev_query;
return ret;
}
return expression_tree_walker(node, preprocess_query, context);
}
/*
* Detect FOREIGN KEY lookup queries and mark the RTE for expansion.
* Unfortunately postgres will create lookup queries for foreign keys
@ -410,8 +487,8 @@ preprocess_query(Node *node, PreprocessQueryContext *context)
* The implementation of this on the postgres side can be found in
* src/backend/utils/adt/ri_triggers.c
*/
if (ts_guc_enable_foreign_key_propagation)
static void
preprocess_fk_checks(Query *query, Cache *hcache, PreprocessQueryContext *context)
{
/*
* RI_FKey_cascade_del
@ -514,76 +591,6 @@ preprocess_query(Node *node, PreprocessQueryContext *context)
}
}
foreach (lc, query->rtable)
{
RangeTblEntry *rte = lfirst_node(RangeTblEntry, lc);
Hypertable *ht;
switch (rte->rtekind)
{
case RTE_SUBQUERY:
if (ts_guc_enable_optimizations && ts_guc_enable_cagg_reorder_groupby &&
query->commandType == CMD_SELECT)
{
/* applicable to selects on continuous aggregates */
List *outer_tlist = query->targetList;
List *outer_sortcl = query->sortClause;
cagg_reorder_groupby_clause(rte, rti, outer_sortcl, outer_tlist);
}
break;
case RTE_RELATION:
/* This lookup will warm the cache with all hypertables in the query */
ht = ts_hypertable_cache_get_entry(hcache, rte->relid, CACHE_FLAG_MISSING_OK);
if (ht)
{
/* Mark hypertable RTEs we'd like to expand ourselves */
if (ts_guc_enable_optimizations && ts_guc_enable_constraint_exclusion &&
!IS_UPDL_CMD(context->rootquery) && query->resultRelation == 0 &&
query->rowMarks == NIL && rte->inh)
rte_mark_for_expansion(rte);
if (TS_HYPERTABLE_HAS_COMPRESSION_TABLE(ht))
{
int compr_htid = ht->fd.compressed_hypertable_id;
/* Also warm the cache with the compressed
* companion hypertable */
ts_hypertable_cache_get_entry_by_id(hcache, compr_htid);
}
}
else
{
/* To properly keep track of SELECT FROM ONLY <chunk> we
* have to mark the rte here because postgres will set
* rte->inh to false (when it detects the chunk has no
* children which is true for all our chunks) before it
* reaches set_rel_pathlist hook. But chunks from queries
* like SELECT .. FROM ONLY <chunk> has rte->inh set to
* false and other chunks have rte->inh set to true.
* We want to distinguish between the two cases here by
* marking the chunk when rte->inh is true.
*/
Chunk *chunk = ts_chunk_get_by_relid(rte->relid, false);
if (chunk && rte->inh)
rte_mark_for_expansion(rte);
}
break;
default:
break;
}
rti++;
}
prev_query = context->current_query;
context->current_query = query;
ret = query_tree_walker(query, preprocess_query, context, 0);
context->current_query = prev_query;
return ret;
}
return expression_tree_walker(node, preprocess_query, context);
}
static PlannedStmt *
timescaledb_planner(Query *parse, const char *query_string, int cursor_opts,
ParamListInfo bound_params)