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:
Sven Klemm 2019-10-28 12:36:20 +01:00 committed by Matvey Arye
parent 405c65fb99
commit e2df62c81c
8 changed files with 22 additions and 36 deletions

View File

@ -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)
{

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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,

View File

@ -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),

View File

@ -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);

View File

@ -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 ? */