mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-20 04:35:00 +08:00
Do not add broken compressed join clauses
We used to add join clauses that referenced a compressed column at the level of the compressed scan, and later remove them. This is wrong and useless, just don't add them.
This commit is contained in:
parent
22a2f49a2f
commit
d088b3a5d9
@ -1170,6 +1170,49 @@ chunk_joininfo_mutator(Node *node, CompressionInfo *context)
|
||||
return expression_tree_mutator(node, chunk_joininfo_mutator, context);
|
||||
}
|
||||
|
||||
/* Check if the expression references a compressed column in compressed chunk. */
|
||||
static bool
|
||||
has_compressed_vars_walker(Node *node, CompressionInfo *info)
|
||||
{
|
||||
if (node == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsA(node, Var))
|
||||
{
|
||||
Var *var = castNode(Var, node);
|
||||
if ((Index) var->varno != (Index) info->compressed_rel->relid)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (var->varattno <= 0)
|
||||
{
|
||||
/*
|
||||
* Shouldn't see a system var here, might be a whole row var?
|
||||
* In any case, we can't push it down to the compressed scan level.
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
if (bms_is_member(var->varattno, info->compressed_attnos_in_compressed_chunk))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return expression_tree_walker(node, has_compressed_vars_walker, info);
|
||||
}
|
||||
|
||||
static bool
|
||||
has_compressed_vars(RestrictInfo *ri, CompressionInfo *info)
|
||||
{
|
||||
return expression_tree_walker((Node *) ri->clause, has_compressed_vars_walker, info);
|
||||
}
|
||||
|
||||
/* translate chunk_rel->joininfo for compressed_rel
|
||||
* this is necessary for create_index_path which gets join clauses from
|
||||
* rel->joininfo and sets up parameterized paths (in rel->ppilist).
|
||||
@ -1186,12 +1229,21 @@ compressed_rel_setup_joininfo(RelOptInfo *compressed_rel, CompressionInfo *info)
|
||||
List *compress_joininfo = NIL;
|
||||
foreach (lc, chunk_rel->joininfo)
|
||||
{
|
||||
RestrictInfo *compress_ri;
|
||||
RestrictInfo *ri = (RestrictInfo *) lfirst(lc);
|
||||
Node *result = chunk_joininfo_mutator((Node *) ri, info);
|
||||
Assert(IsA(result, RestrictInfo));
|
||||
compress_ri = (RestrictInfo *) result;
|
||||
compress_joininfo = lappend(compress_joininfo, compress_ri);
|
||||
|
||||
RestrictInfo *adjusted = (RestrictInfo *) chunk_joininfo_mutator((Node *) ri, info);
|
||||
Assert(IsA(adjusted, RestrictInfo));
|
||||
|
||||
if (has_compressed_vars(adjusted, info))
|
||||
{
|
||||
/*
|
||||
* We can't check clauses that refer to compressed columns during
|
||||
* the compressed scan.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
compress_joininfo = lappend(compress_joininfo, adjusted);
|
||||
}
|
||||
compressed_rel->joininfo = compress_joininfo;
|
||||
}
|
||||
@ -1481,8 +1533,8 @@ decompress_chunk_add_plannerinfo(PlannerInfo *root, CompressionInfo *info, Chunk
|
||||
/* store attnos for the compressed chunk here */
|
||||
AttrNumber compressed_chunk_attno =
|
||||
get_attnum(info->compressed_rte->relid, NameStr(fd->attname));
|
||||
info->compressed_chunk_compressed_attnos =
|
||||
bms_add_member(info->compressed_chunk_compressed_attnos, compressed_chunk_attno);
|
||||
info->compressed_attnos_in_compressed_chunk =
|
||||
bms_add_member(info->compressed_attnos_in_compressed_chunk, compressed_chunk_attno);
|
||||
}
|
||||
}
|
||||
compressed_rel_setup_reltarget(compressed_rel, info, needs_sequence_num);
|
||||
|
@ -35,7 +35,7 @@ typedef struct CompressionInfo
|
||||
*/
|
||||
Bitmapset *chunk_const_segmentby;
|
||||
/* compressed chunk attribute numbers for columns that are compressed */
|
||||
Bitmapset *compressed_chunk_compressed_attnos;
|
||||
Bitmapset *compressed_attnos_in_compressed_chunk;
|
||||
|
||||
bool single_chunk; /* query on explicit chunk */
|
||||
|
||||
|
@ -322,33 +322,6 @@ replace_compressed_vars(Node *node, CompressionInfo *info)
|
||||
return expression_tree_mutator(node, replace_compressed_vars, (void *) info);
|
||||
}
|
||||
|
||||
typedef struct CompressedAttnoContext
|
||||
{
|
||||
Bitmapset *compressed_attnos;
|
||||
Index compress_relid;
|
||||
} CompressedAttnoContext;
|
||||
|
||||
/* check if the clause refers to any attributes that are in compressed
|
||||
* form.
|
||||
*/
|
||||
static bool
|
||||
clause_has_compressed_attrs(Node *node, void *context)
|
||||
{
|
||||
if (node == NULL)
|
||||
return true;
|
||||
if (IsA(node, Var))
|
||||
{
|
||||
CompressedAttnoContext *cxt = (CompressedAttnoContext *) context;
|
||||
Var *var = (Var *) node;
|
||||
if ((Index) var->varno == cxt->compress_relid)
|
||||
{
|
||||
if (bms_is_member(var->varattno, cxt->compressed_attnos))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return expression_tree_walker(node, clause_has_compressed_attrs, context);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the resno of the given attribute in the provided target list
|
||||
*/
|
||||
@ -410,8 +383,6 @@ decompress_chunk_plan_create(PlannerInfo *root, RelOptInfo *rel, CustomPath *pat
|
||||
* IndexClause's, so we use some custom code based on it.
|
||||
*/
|
||||
IndexPath *ipath = castNode(IndexPath, compressed_path);
|
||||
List *indexqual = NIL;
|
||||
Plan *indexplan;
|
||||
foreach (lc, clauses)
|
||||
{
|
||||
RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc);
|
||||
@ -443,30 +414,6 @@ decompress_chunk_plan_create(PlannerInfo *root, RelOptInfo *rel, CustomPath *pat
|
||||
decompress_plan->scan.plan.qual =
|
||||
lappend(decompress_plan->scan.plan.qual, rinfo->clause);
|
||||
}
|
||||
|
||||
/* joininfo clauses on the compressed chunk rel have to
|
||||
* contain clauses on both compressed and
|
||||
* decompressed attnos. joininfo clauses get translated into
|
||||
* ParamPathInfo for the indexpath. But the index scans can't
|
||||
* handle compressed attributes, so remove them from the
|
||||
* indexscans here. (these are included in the `clauses` passed in
|
||||
* to the function and so were added as filters
|
||||
* for decompress_plan->scan.plan.qual in the loop above. )
|
||||
*/
|
||||
indexplan = linitial(custom_plans);
|
||||
Assert(IsA(indexplan, IndexScan) || IsA(indexplan, IndexOnlyScan));
|
||||
foreach (lc, indexplan->qual)
|
||||
{
|
||||
Node *expr = (Node *) lfirst(lc);
|
||||
CompressedAttnoContext cxt;
|
||||
Index compress_relid = dcpath->info->compressed_rel->relid;
|
||||
cxt.compress_relid = compress_relid;
|
||||
cxt.compressed_attnos = dcpath->info->compressed_chunk_compressed_attnos;
|
||||
|
||||
if (!clause_has_compressed_attrs((Node *) expr, &cxt))
|
||||
indexqual = lappend(indexqual, expr);
|
||||
}
|
||||
indexplan->qual = indexqual;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user