mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-16 02:23:49 +08:00
Fix transparent decompression interaction with first/last
Queries with the first/last optimization on compressed chunks would not properly decompress data but instead access the uncompressed chunk. This patch fixes the behaviour and also unifies the check whether a hypertable has compression.
This commit is contained in:
parent
405c65fb99
commit
e2df62c81c
@ -384,7 +384,7 @@ hypertable_tuple_update(TupleInfo *ti, void *data)
|
||||
elog(ERROR, "hypertable_tuple_update chunk_sizing_function cannot be NULL");
|
||||
}
|
||||
values[AttrNumberGetAttrOffset(Anum_hypertable_compressed)] = BoolGetDatum(ht->fd.compressed);
|
||||
if (ht->fd.compressed_hypertable_id == INVALID_HYPERTABLE_ID)
|
||||
if (!TS_HYPERTABLE_HAS_COMPRESSION(ht))
|
||||
{
|
||||
nulls[AttrNumberGetAttrOffset(Anum_hypertable_compressed_hypertable_id)] = true;
|
||||
}
|
||||
@ -2129,7 +2129,7 @@ ts_hypertable_clone_constraints_to_compressed(Hypertable *user_ht, List *constra
|
||||
CatalogSecurityContext sec_ctx;
|
||||
|
||||
ListCell *lc;
|
||||
Assert(user_ht->fd.compressed_hypertable_id != 0);
|
||||
Assert(TS_HYPERTABLE_HAS_COMPRESSION(user_ht));
|
||||
ts_catalog_database_info_become_owner(ts_catalog_database_info_get(), &sec_ctx);
|
||||
foreach (lc, constraint_list)
|
||||
{
|
||||
|
@ -30,7 +30,9 @@
|
||||
typedef struct SubspaceStore SubspaceStore;
|
||||
typedef struct Chunk Chunk;
|
||||
|
||||
#define TS_HYPERTABLE_HAS_COMPRESSION_ON(ht) (ht->fd.compressed_hypertable_id > 0)
|
||||
#define TS_HYPERTABLE_HAS_COMPRESSION(ht) \
|
||||
((ht)->fd.compressed_hypertable_id != INVALID_HYPERTABLE_ID)
|
||||
|
||||
typedef struct Hypertable
|
||||
{
|
||||
FormData_hypertable fd;
|
||||
|
@ -294,24 +294,6 @@ is_append_parent(RelOptInfo *rel, RangeTblEntry *rte)
|
||||
rte->relkind == RELKIND_RELATION;
|
||||
}
|
||||
|
||||
static RelOptInfo *
|
||||
get_parentrel(PlannerInfo *root, Index rti)
|
||||
{
|
||||
#if PG11_LT
|
||||
ListCell *lc;
|
||||
foreach (lc, root->append_rel_list)
|
||||
{
|
||||
AppendRelInfo *appinfo = lfirst(lc);
|
||||
if (appinfo->child_relid == rti)
|
||||
return root->simple_rel_array[appinfo->parent_relid];
|
||||
}
|
||||
#else
|
||||
if (root->append_rel_array[rti])
|
||||
return root->simple_rel_array[root->append_rel_array[rti]->parent_relid];
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Oid
|
||||
get_parentoid(PlannerInfo *root, Index rti)
|
||||
{
|
||||
@ -521,8 +503,8 @@ timescaledb_get_relation_info_hook(PlannerInfo *root, Oid relation_objectid, boo
|
||||
|
||||
Assert(ht != NULL);
|
||||
|
||||
Assert(rel->fdw_private == NULL);
|
||||
rel->fdw_private = palloc0(sizeof(TimescaleDBPrivate));
|
||||
((TimescaleDBPrivate *) rel->fdw_private)->compressed = ht->fd.compressed_hypertable_id > 0;
|
||||
|
||||
ts_plan_expand_hypertable_chunks(ht, root, relation_objectid, inhparent, rel);
|
||||
#if PG11_GE
|
||||
@ -534,15 +516,17 @@ timescaledb_get_relation_info_hook(PlannerInfo *root, Oid relation_objectid, boo
|
||||
|
||||
if (ts_guc_enable_transparent_decompression && is_append_child(rel, rte))
|
||||
{
|
||||
RelOptInfo *parent = get_parentrel(root, rel->relid);
|
||||
Oid ht_oid = get_parentoid(root, rel->relid);
|
||||
Cache *hcache = ts_hypertable_cache_pin();
|
||||
Hypertable *ht = ts_hypertable_cache_get_entry(hcache, ht_oid);
|
||||
|
||||
if (parent != NULL && parent->fdw_private != NULL &&
|
||||
((TimescaleDBPrivate *) parent->fdw_private)->compressed)
|
||||
if (ht != NULL && TS_HYPERTABLE_HAS_COMPRESSION(ht))
|
||||
{
|
||||
Chunk *chunk = ts_chunk_get_by_relid(rte->relid, 0, true);
|
||||
|
||||
if (chunk->fd.compressed_chunk_id > 0)
|
||||
{
|
||||
Assert(rel->fdw_private == NULL);
|
||||
rel->fdw_private = palloc0(sizeof(TimescaleDBPrivate));
|
||||
((TimescaleDBPrivate *) rel->fdw_private)->compressed = true;
|
||||
|
||||
@ -555,6 +539,7 @@ timescaledb_get_relation_info_hook(PlannerInfo *root, Oid relation_objectid, boo
|
||||
rel->indexlist = NIL;
|
||||
}
|
||||
}
|
||||
ts_cache_release(hcache);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,7 +201,7 @@ static void
|
||||
check_alter_table_allowed_on_ht_with_compression(Hypertable *ht, AlterTableStmt *stmt)
|
||||
{
|
||||
ListCell *lc;
|
||||
if (ht->fd.compressed_hypertable_id == INVALID_HYPERTABLE_ID)
|
||||
if (!TS_HYPERTABLE_HAS_COMPRESSION(ht))
|
||||
return;
|
||||
|
||||
/* only allow if all commands are allowed */
|
||||
@ -736,7 +736,7 @@ process_truncate(ProcessUtilityArgs *args)
|
||||
foreach_chunk(ht, process_truncate_chunk, stmt);
|
||||
|
||||
/* propogate to the compressed hypertable */
|
||||
if (ht->fd.compressed_hypertable_id != INVALID_HYPERTABLE_ID)
|
||||
if (TS_HYPERTABLE_HAS_COMPRESSION(ht))
|
||||
{
|
||||
Hypertable *compressed_ht =
|
||||
ts_hypertable_cache_get_entry_by_id(hcache,
|
||||
@ -866,8 +866,7 @@ process_drop_hypertable(ProcessUtilityArgs *args, DropStmt *stmt)
|
||||
* DROP_RESTRICT But if we are using DROP_CASCADE we should propagate that down to
|
||||
* the compressed hypertable.
|
||||
*/
|
||||
if (stmt->behavior == DROP_CASCADE &&
|
||||
ht->fd.compressed_hypertable_id != INVALID_HYPERTABLE_ID)
|
||||
if (stmt->behavior == DROP_CASCADE && TS_HYPERTABLE_HAS_COMPRESSION(ht))
|
||||
{
|
||||
Hypertable *compressed_hypertable =
|
||||
ts_hypertable_get_by_id(ht->fd.compressed_hypertable_id);
|
||||
@ -1414,7 +1413,7 @@ process_altertable_change_owner(Hypertable *ht, AlterTableCmd *cmd)
|
||||
|
||||
foreach_chunk(ht, process_altertable_change_owner_chunk, cmd);
|
||||
|
||||
if (ht->fd.compressed_hypertable_id != INVALID_HYPERTABLE_ID)
|
||||
if (TS_HYPERTABLE_HAS_COMPRESSION(ht))
|
||||
{
|
||||
Hypertable *compressed_hypertable =
|
||||
ts_hypertable_get_by_id(ht->fd.compressed_hypertable_id);
|
||||
@ -2268,7 +2267,7 @@ process_altertable_set_tablespace_end(Hypertable *ht, AlterTableCmd *cmd)
|
||||
|
||||
ts_tablespace_attach_internal(&tspc_name, ht->main_table_relid, true);
|
||||
foreach_chunk(ht, process_altertable_chunk, cmd);
|
||||
if (ht->fd.compressed_hypertable_id != INVALID_HYPERTABLE_ID)
|
||||
if (TS_HYPERTABLE_HAS_COMPRESSION(ht))
|
||||
{
|
||||
Hypertable *compressed_hypertable =
|
||||
ts_hypertable_get_by_id(ht->fd.compressed_hypertable_id);
|
||||
|
@ -83,7 +83,7 @@ compress_chunks_add_policy(PG_FUNCTION_ARGS)
|
||||
/* check if this is a table with compression enabled */
|
||||
hcache = ts_hypertable_cache_pin();
|
||||
hypertable = ts_hypertable_cache_get_entry(hcache, ht_oid);
|
||||
if (!hypertable || !TS_HYPERTABLE_HAS_COMPRESSION_ON(hypertable))
|
||||
if (!hypertable || !TS_HYPERTABLE_HAS_COMPRESSION(hypertable))
|
||||
{
|
||||
ts_cache_release(hcache);
|
||||
ereport(ERROR,
|
||||
|
@ -169,7 +169,7 @@ compresschunkcxt_init(CompressChunkCxt *cxt, Cache *hcache, Oid hypertable_relid
|
||||
(errcode(ERRCODE_TS_HYPERTABLE_NOT_EXIST),
|
||||
errmsg("table \"%s\" is not a hypertable", get_rel_name(hypertable_relid))));
|
||||
ts_hypertable_permissions_check(srcht->main_table_relid, GetUserId());
|
||||
if (!TS_HYPERTABLE_HAS_COMPRESSION_ON(srcht))
|
||||
if (!TS_HYPERTABLE_HAS_COMPRESSION(srcht))
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
|
@ -805,7 +805,7 @@ tsl_process_compress_table(AlterTableCmd *cmd, Hypertable *ht,
|
||||
segmentby_cols = ts_compress_hypertable_parse_segment_by(with_clause_options, ht);
|
||||
orderby_cols = ts_compress_hypertable_parse_order_by(with_clause_options, ht);
|
||||
orderby_cols = add_time_to_order_by_if_not_included(orderby_cols, segmentby_cols, ht);
|
||||
compression_already_enabled = TS_HYPERTABLE_HAS_COMPRESSION_ON(ht);
|
||||
compression_already_enabled = TS_HYPERTABLE_HAS_COMPRESSION(ht);
|
||||
compressed_chunks_exist =
|
||||
compression_already_enabled && ts_chunk_exists_with_compression(ht->fd.id);
|
||||
|
||||
|
@ -34,7 +34,7 @@ tsl_set_rel_pathlist_query(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeT
|
||||
Hypertable *ht)
|
||||
{
|
||||
if (ts_guc_enable_transparent_decompression && ht != NULL &&
|
||||
rel->reloptkind == RELOPT_OTHER_MEMBER_REL && ht->fd.compressed_hypertable_id > 0 &&
|
||||
rel->reloptkind == RELOPT_OTHER_MEMBER_REL && TS_HYPERTABLE_HAS_COMPRESSION(ht) &&
|
||||
rel->fdw_private != NULL && ((TimescaleDBPrivate *) rel->fdw_private)->compressed)
|
||||
{
|
||||
Chunk *chunk = ts_chunk_get_by_relid(rte->relid, 0, true);
|
||||
@ -47,7 +47,7 @@ void
|
||||
tsl_set_rel_pathlist_dml(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTblEntry *rte,
|
||||
Hypertable *ht)
|
||||
{
|
||||
if (ht != NULL && TS_HYPERTABLE_HAS_COMPRESSION_ON(ht))
|
||||
if (ht != NULL && TS_HYPERTABLE_HAS_COMPRESSION(ht))
|
||||
{
|
||||
ListCell *lc;
|
||||
/* is this a chunk under compressed hypertable ? */
|
||||
|
Loading…
x
Reference in New Issue
Block a user