Skip to content

Commit

Permalink
Add GUC for hypercore_use_access_method default
Browse files Browse the repository at this point in the history
Add the GUC `timescaledb.hypercore_use_access_method` for dealing with
the default value to use for functions accepting the
`hypercore_use_access_method` parameter (`compress_chunk`,
`add_compression_policy`, etc.)

Value can be "none" (not set, will typically use the "heap" method),
"on" (use the hypercore access method) and "off" (do not use the
hypercore access method).
  • Loading branch information
mkindahl committed Oct 31, 2024
1 parent 0dfefaa commit 1554e7c
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 17 deletions.
30 changes: 30 additions & 0 deletions src/guc.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "guc.h"
#include "hypertable_cache.h"
#include "license_guc.h"

#ifdef USE_TELEMETRY
#include "telemetry/telemetry.h"
#endif
Expand Down Expand Up @@ -138,6 +139,7 @@ bool ts_guc_enable_vectorized_aggregation = true;
TSDLLEXPORT bool ts_guc_enable_compression_indexscan = false;
TSDLLEXPORT bool ts_guc_enable_bulk_decompression = true;
TSDLLEXPORT bool ts_guc_auto_sparse_indexes = true;
TSDLLEXPORT int ts_guc_default_hypercore_use_access_method = USE_AM_NULL;
bool ts_guc_enable_chunk_skipping = false;

/* Enable of disable columnar scans for columnar-oriented storage engines. If
Expand Down Expand Up @@ -411,6 +413,20 @@ ts_guc_default_orderby_fn_oid()
return get_orderby_func(ts_guc_default_orderby_fn);
}

/*
* Options for the default value of hypercore_use_access_method.
*
* We are following the convensions use by PostgreSQL and use "none" for the
* "unset" value.
*/
static const struct config_enum_entry useam_options[] = {
{ "none", USE_AM_NULL, false }, { "on", USE_AM_TRUE, false },
{ "off", USE_AM_FALSE, false }, { "true", USE_AM_TRUE, true },
{ "false", USE_AM_FALSE, true }, { "yes", USE_AM_TRUE, true },
{ "no", USE_AM_FALSE, true }, { "1", USE_AM_TRUE, true },
{ "0", USE_AM_FALSE, true }, { NULL, 0, false }
};

void
_guc_init(void)
{
Expand Down Expand Up @@ -1093,6 +1109,20 @@ _guc_init(void)
/* show_hook= */ NULL);
#endif

DefineCustomEnumVariable(MAKE_EXTOPTION("default_hypercore_use_access_method"),
gettext_noop(
"Whether to use access method for compression by default."),
gettext_noop(
"Sets the global default for compression technique to use."),
&ts_guc_default_hypercore_use_access_method,
USE_AM_NULL,
/* options= */ useam_options,
/* context= */ PGC_USERSET,
/* flags= */ 0,
/* check_hook= */ NULL,
/* assign_hook= */ NULL,
/* show_hook= */ NULL);

/* register feature flags */
ts_feature_flag_add(FEATURE_HYPERTABLE);
ts_feature_flag_add(FEATURE_HYPERTABLE_COMPRESSION);
Expand Down
17 changes: 17 additions & 0 deletions src/guc.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@
#include "config.h"
#include "export.h"

/*
* Decide if the access method should be used for compression, or if it is
* undefined. Used for parameter values to PostgreSQL functions and is a
* nullable boolean.
*
* Using explicit values of TRUE = 1 and FALSE = 0 since this enum is cast to
* boolean value in the code.
*/
typedef enum UseAccessMethod
{
USE_AM_FALSE = 0,
USE_AM_TRUE = 1,
USE_AM_NULL = 2,
} UseAccessMethod;

#ifdef USE_TELEMETRY
extern bool ts_telemetry_on(void);
extern bool ts_function_telemetry_on(void);
Expand Down Expand Up @@ -100,6 +115,7 @@ extern TSDLLEXPORT DebugRequireOption ts_guc_debug_require_vector_agg;

extern TSDLLEXPORT bool ts_guc_debug_compression_path_info;
extern TSDLLEXPORT bool ts_guc_enable_rowlevel_compression_locking;
extern TSDLLEXPORT int ts_guc_default_hypercore_use_access_method;

extern TSDLLEXPORT bool ts_guc_debug_require_batch_sorted_merge;

Expand All @@ -119,4 +135,5 @@ typedef enum
extern TSDLLEXPORT void ts_feature_flag_check(FeatureFlagType);
extern TSDLLEXPORT Oid ts_guc_default_segmentby_fn_oid(void);
extern TSDLLEXPORT Oid ts_guc_default_orderby_fn_oid(void);

extern TSDLLEXPORT bool ts_is_whitelisted_indexam(const char *amname);
3 changes: 2 additions & 1 deletion tsl/src/bgw_policy/compression_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
#pragma once

#include <postgres.h>
#include "compression/api.h"
#include <utils/jsonb.h>
#include <utils/timestamp.h>

#include "guc.h"

/* User-facing API functions */
extern Datum policy_compression_add(PG_FUNCTION_ARGS);
extern Datum policy_compression_remove(PG_FUNCTION_ARGS);
Expand Down
12 changes: 11 additions & 1 deletion tsl/src/compression/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -838,13 +838,23 @@ compress_hypercore(Chunk *chunk, bool rel_is_hypercore, UseAccessMethod useam,
return relid;
}

/*
* Check the value of the use_access_method argument and use the default value
* otherwise.
*/
static UseAccessMethod
check_useam(UseAccessMethod arg)
{
return arg == USE_AM_NULL ? (UseAccessMethod) ts_guc_default_hypercore_use_access_method : arg;
}

Datum
tsl_compress_chunk(PG_FUNCTION_ARGS)
{
Oid uncompressed_chunk_id = PG_ARGISNULL(0) ? InvalidOid : PG_GETARG_OID(0);
bool if_not_compressed = PG_ARGISNULL(1) ? true : PG_GETARG_BOOL(1);
bool recompress = PG_ARGISNULL(2) ? false : PG_GETARG_BOOL(2);
UseAccessMethod useam = PG_ARGISNULL(3) ? USE_AM_NULL : PG_GETARG_BOOL(3);
UseAccessMethod useam = check_useam(PG_ARGISNULL(3) ? USE_AM_NULL : PG_GETARG_BOOL(3));

ts_feature_flag_check(FEATURE_HYPERTABLE_COMPRESSION);

Expand Down
15 changes: 0 additions & 15 deletions tsl/src/compression/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,6 @@

#include "chunk.h"

/*
* Decide if the access method should be used for compression, or if it is
* undefined. Used for parameter values to PostgreSQL functions and is a
* nullable boolean.
*
* Using explicit values of TRUE = 1 and FALSE = 0 since this enum is cast to
* boolean value in the code.
*/
typedef enum UseAccessMethod
{
USE_AM_FALSE = 0,
USE_AM_TRUE = 1,
USE_AM_NULL = 2,
} UseAccessMethod;

extern Datum tsl_create_compressed_chunk(PG_FUNCTION_ARGS);
extern Datum tsl_compress_chunk(PG_FUNCTION_ARGS);
extern Datum tsl_decompress_chunk(PG_FUNCTION_ARGS);
Expand Down
71 changes: 71 additions & 0 deletions tsl/test/expected/hypercore_create.out
Original file line number Diff line number Diff line change
Expand Up @@ -921,3 +921,74 @@ select * from rides order by pickup_datetime;
745233436676 | Fri Jan 01 00:00:03 2016 PST | Fri Jan 01 00:11:14 2016 PST | 1 | 6.00 | -73.947151184082031 | 40.791046142578125 | 1 | -73.920768737792969 | 40.865577697753906 | 2 | 9 | 0.5 | 0.5 | 0 | 0 | 0.3 | 19.3
(3 rows)

-- All these are valid methods to set the default
show timescaledb.default_hypercore_use_access_method;
timescaledb.default_hypercore_use_access_method
-------------------------------------------------
none
(1 row)

set timescaledb.default_hypercore_use_access_method to on;
set timescaledb.default_hypercore_use_access_method to off;
set timescaledb.default_hypercore_use_access_method to true;
set timescaledb.default_hypercore_use_access_method to false;
set timescaledb.default_hypercore_use_access_method to yes;
set timescaledb.default_hypercore_use_access_method to no;
set timescaledb.default_hypercore_use_access_method to 0;
set timescaledb.default_hypercore_use_access_method to 1;
show timescaledb.default_hypercore_use_access_method;
timescaledb.default_hypercore_use_access_method
-------------------------------------------------
on
(1 row)

-- This should generate an error and not change the value
\set ON_ERROR_STOP 0
\set VERBOSITY default
set timescaledb.default_hypercore_use_access_method to magic;
ERROR: invalid value for parameter "timescaledb.default_hypercore_use_access_method": "magic"
HINT: Available values: none, on, off.
show timescaledb.default_hypercore_use_access_method;
timescaledb.default_hypercore_use_access_method
-------------------------------------------------
on
(1 row)

\set VERBOSITY terse
\set ON_ERROR_STOP 1
-- This should unset the value
reset timescaledb.default_hypercore_use_access_method;
show timescaledb.default_hypercore_use_access_method;
timescaledb.default_hypercore_use_access_method
-------------------------------------------------
none
(1 row)

-- Using GUC should compress using the hyperstore
set timescaledb.default_hypercore_use_access_method to on;
create table test5 (time timestamptz not null, device int, temp float);
select created from create_hypertable('test5', 'time');
created
---------
t
(1 row)

insert into test5 values ('2022-06-01', 1, 1.0), ('2022-08-01', 1, 1.0);
select ch as chunk from show_chunks('test5') ch limit 1 \gset
alter table test5 set (timescaledb.compress);
WARNING: there was some uncertainty picking the default segment by for the hypertable: You do not have any indexes on columns that can be used for segment_by and thus we are not using segment_by for compression. Please make sure you are not missing any indexes
NOTICE: default segment by for hypertable "test5" is set to ""
NOTICE: default order by for hypertable "test5" is set to ""time" DESC"
select compress_chunk(:'chunk');
compress_chunk
------------------------------------------
_timescaledb_internal._hyper_10_46_chunk
(1 row)

select * from amrels where relparent = 'test5'::regclass;
rel | amname | relparent
------------------------------------------+-----------+-----------
_timescaledb_internal._hyper_10_46_chunk | hypercore | test5
_timescaledb_internal._hyper_10_47_chunk | heap | test5
(2 rows)

35 changes: 35 additions & 0 deletions tsl/test/sql/hypercore_create.sql
Original file line number Diff line number Diff line change
Expand Up @@ -446,3 +446,38 @@ analyze rides;
explain (costs off)
select * from rides order by pickup_datetime;
select * from rides order by pickup_datetime;

-- All these are valid methods to set the default
show timescaledb.default_hypercore_use_access_method;
set timescaledb.default_hypercore_use_access_method to on;
set timescaledb.default_hypercore_use_access_method to off;
set timescaledb.default_hypercore_use_access_method to true;
set timescaledb.default_hypercore_use_access_method to false;
set timescaledb.default_hypercore_use_access_method to yes;
set timescaledb.default_hypercore_use_access_method to no;
set timescaledb.default_hypercore_use_access_method to 0;
set timescaledb.default_hypercore_use_access_method to 1;
show timescaledb.default_hypercore_use_access_method;

-- This should generate an error and not change the value
\set ON_ERROR_STOP 0
\set VERBOSITY default
set timescaledb.default_hypercore_use_access_method to magic;
show timescaledb.default_hypercore_use_access_method;
\set VERBOSITY terse
\set ON_ERROR_STOP 1

-- This should unset the value
reset timescaledb.default_hypercore_use_access_method;
show timescaledb.default_hypercore_use_access_method;

-- Using GUC should compress using the hyperstore
set timescaledb.default_hypercore_use_access_method to on;
create table test5 (time timestamptz not null, device int, temp float);
select created from create_hypertable('test5', 'time');
insert into test5 values ('2022-06-01', 1, 1.0), ('2022-08-01', 1, 1.0);

select ch as chunk from show_chunks('test5') ch limit 1 \gset
alter table test5 set (timescaledb.compress);
select compress_chunk(:'chunk');
select * from amrels where relparent = 'test5'::regclass;

0 comments on commit 1554e7c

Please sign in to comment.