Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support continuous aggregates table access method #2347

Merged
merged 1 commit into from Sep 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 21 additions & 4 deletions tsl/src/continuous_aggs/create.c
Expand Up @@ -204,6 +204,9 @@ static int32 mattablecolumninfo_create_materialization_table(MatTableColumnInfo
CAggTimebucketInfo *origquery_tblinfo,
bool create_addl_index,
char *tablespacename,
#if PG12_GE
char *table_access_method,
#endif
ObjectAddress *mataddress);
static Query *mattablecolumninfo_get_partial_select_query(MatTableColumnInfo *matcolinfo,
Query *userview_query);
Expand Down Expand Up @@ -451,17 +454,25 @@ mattablecolumninfo_add_mattable_index(MatTableColumnInfo *matcolinfo, Hypertable
* Reuse the information from ViewStmt:
* Remove the options on the into clause that we will not honour
* Modify the relname to ts_internal_<name>
*
* Parameters:
* mat_rel - relation information for the materialization table
* origquery_tblinfo - user query's tbale information. used for setting up thr partitioning of the
* hypertable mataddress - return the ObjectAddress RETURNS: hypertable id of the materialization
* table
* mat_rel: relation information for the materialization table
* origquery_tblinfo: - user query's tbale information. used for setting up
* thr partitioning of the hypertable.
* tablespace_name: Name of the tablespace for the materialization table.
* table_access_method: Name of the table access method to use for the
* materialization table.
* mataddress: return the ObjectAddress RETURNS: hypertable id of the
* materialization table
*/
static int32
mattablecolumninfo_create_materialization_table(MatTableColumnInfo *matcolinfo, int32 hypertable_id,
RangeVar *mat_rel,
CAggTimebucketInfo *origquery_tblinfo,
bool create_addl_index, char *const tablespacename,
#if PG12_GE
char *const table_access_method,
#endif
ObjectAddress *mataddress)
{
Oid uid, saved_uid;
Expand All @@ -488,6 +499,9 @@ mattablecolumninfo_create_materialization_table(MatTableColumnInfo *matcolinfo,
create->options = NULL;
create->oncommit = ONCOMMIT_NOOP;
create->tablespacename = tablespacename;
#if PG12_GE
create->accessMethod = table_access_method;
#endif
create->if_not_exists = false;

/* Create the materialization table. */
Expand Down Expand Up @@ -1718,6 +1732,9 @@ cagg_create(const CreateTableAsStmt *create_stmt, ViewStmt *stmt, Query *panquer
origquery_ht,
is_create_mattbl_index,
create_stmt->into->tableSpaceName,
#if PG12_GE
create_stmt->into->accessMethod,
#endif
&mataddress);
/* Step 2: create view with select finalize from materialization
* table
Expand Down
4 changes: 2 additions & 2 deletions tsl/test/expected/continuous_aggs_ddl.out
Expand Up @@ -899,12 +899,12 @@ SELECT set_integer_now_func('whatever', 'integer_now_test');

CREATE MATERIALIZED VIEW whatever_view_1
WITH (timescaledb.continuous, timescaledb.materialized_only=true) AS
SELECT time_bucket('2', time), COUNT(data)
SELECT time_bucket('5', time), COUNT(data)
FROM whatever GROUP BY 1;
CREATE MATERIALIZED VIEW whatever_view_2
WITH (timescaledb.continuous, timescaledb.materialized_only=true)
TABLESPACE tablespace1 AS
SELECT time_bucket('2', time), COUNT(data)
SELECT time_bucket('5', time), COUNT(data)
FROM whatever GROUP BY 1;
INSERT INTO whatever SELECT i, i FROM generate_series(0, 29) AS i;
CALL refresh_continuous_aggregate('whatever_view_1', NULL, NULL);
Expand Down
94 changes: 94 additions & 0 deletions tsl/test/expected/continuous_aggs_tableam.out
@@ -0,0 +1,94 @@
-- This file and its contents are licensed under the Timescale License.
-- Please see the included NOTICE for copyright information and
-- LICENSE-TIMESCALE for a copy of the license.
\c :TEST_DBNAME :ROLE_SUPERUSER
CREATE ACCESS METHOD heap2 TYPE TABLE HANDLER heap_tableam_handler;
SET ROLE :ROLE_DEFAULT_PERM_USER;
CREATE VIEW cagg_info AS
WITH
caggs AS (
SELECT format('%s.%s', user_view_schema, user_view_name)::regclass AS user_view,
format('%s.%s', ht.schema_name, ht.table_name)::regclass AS mat_relid
FROM _timescaledb_catalog.hypertable ht,
_timescaledb_catalog.continuous_agg cagg
WHERE ht.id = cagg.mat_hypertable_id
)
SELECT user_view,
relname AS mat_table,
(SELECT spcname FROM pg_tablespace WHERE oid = reltablespace) AS tablespace
FROM pg_class JOIN caggs ON pg_class.oid = caggs.mat_relid;
CREATE TABLE whatever(time BIGINT NOT NULL, data INTEGER);
SELECT hypertable_id AS whatever_nid
FROM create_hypertable('whatever', 'time', chunk_time_interval => 10)
\gset
CREATE OR REPLACE FUNCTION integer_now_test() RETURNS bigint
LANGUAGE SQL STABLE AS $$
SELECT coalesce(max(time), bigint '0') FROM whatever
$$;
SELECT set_integer_now_func('whatever', 'integer_now_test');
set_integer_now_func
----------------------

(1 row)

INSERT INTO whatever SELECT i, i FROM generate_series(0, 29) AS i;
-- Checking that the access method for the materialized hypertable is
-- set to the correct access method.
CREATE MATERIALIZED VIEW tableam_view USING heap2
WITH (timescaledb.continuous, timescaledb.materialized_only=true) AS
SELECT time_bucket('5', time), COUNT(data)
FROM whatever GROUP BY 1;
CREATE MATERIALIZED VIEW notableam_view
WITH (timescaledb.continuous, timescaledb.materialized_only=true) AS
SELECT time_bucket('5', time), COUNT(data)
FROM whatever GROUP BY 1;
SELECT user_view, mat_table, amname
FROM cagg_info,
LATERAL (SELECT relam FROM pg_class WHERE relname = mat_table) AS cls,
LATERAL (SELECT amname FROM pg_am WHERE oid = relam) AS am
WHERE user_view::text IN ('tableam_view', 'notableam_view');
user_view | mat_table | amname
----------------+----------------------------+--------
tableam_view | _materialized_hypertable_2 | heap2
notableam_view | _materialized_hypertable_3 | heap
(2 rows)

-- Check that the view with the other access method actually works.
SELECT * FROM notableam_view ORDER BY 1;
time_bucket | count
-------------+-------
(0 rows)

SELECT * FROM tableam_view ORDER BY 1;
time_bucket | count
-------------+-------
(0 rows)

CALL refresh_continuous_aggregate('notableam_view', NULL, NULL);
CALL refresh_continuous_aggregate('tableam_view', NULL, NULL);
SELECT * FROM notableam_view ORDER BY 1;
time_bucket | count
-------------+-------
0 | 5
5 | 5
10 | 5
15 | 5
20 | 5
25 | 5
(6 rows)

SELECT * FROM tableam_view ORDER BY 1;
time_bucket | count
-------------+-------
0 | 5
5 | 5
10 | 5
15 | 5
20 | 5
25 | 5
(6 rows)

DROP MATERIALIZED VIEW notableam_view;
NOTICE: drop cascades to table _timescaledb_internal._hyper_3_4_chunk
DROP MATERIALIZED VIEW tableam_view;
NOTICE: drop cascades to table _timescaledb_internal._hyper_2_5_chunk
1 change: 1 addition & 0 deletions tsl/test/sql/CMakeLists.txt
Expand Up @@ -101,6 +101,7 @@ endif()
if (${PG_VERSION_MAJOR} GREATER_EQUAL "12")
list(APPEND TEST_FILES_DEBUG
dist_hypertable_am.sql
continuous_aggs_tableam.sql
)
endif()

Expand Down
4 changes: 2 additions & 2 deletions tsl/test/sql/continuous_aggs_ddl.sql
Expand Up @@ -540,13 +540,13 @@ SELECT set_integer_now_func('whatever', 'integer_now_test');

CREATE MATERIALIZED VIEW whatever_view_1
WITH (timescaledb.continuous, timescaledb.materialized_only=true) AS
SELECT time_bucket('2', time), COUNT(data)
SELECT time_bucket('5', time), COUNT(data)
FROM whatever GROUP BY 1;

CREATE MATERIALIZED VIEW whatever_view_2
WITH (timescaledb.continuous, timescaledb.materialized_only=true)
TABLESPACE tablespace1 AS
SELECT time_bucket('2', time), COUNT(data)
SELECT time_bucket('5', time), COUNT(data)
FROM whatever GROUP BY 1;

INSERT INTO whatever SELECT i, i FROM generate_series(0, 29) AS i;
Expand Down
66 changes: 66 additions & 0 deletions tsl/test/sql/continuous_aggs_tableam.sql
@@ -0,0 +1,66 @@
-- This file and its contents are licensed under the Timescale License.
-- Please see the included NOTICE for copyright information and
-- LICENSE-TIMESCALE for a copy of the license.

\c :TEST_DBNAME :ROLE_SUPERUSER
CREATE ACCESS METHOD heap2 TYPE TABLE HANDLER heap_tableam_handler;

SET ROLE :ROLE_DEFAULT_PERM_USER;

CREATE VIEW cagg_info AS
WITH
caggs AS (
SELECT format('%s.%s', user_view_schema, user_view_name)::regclass AS user_view,
format('%s.%s', ht.schema_name, ht.table_name)::regclass AS mat_relid
FROM _timescaledb_catalog.hypertable ht,
_timescaledb_catalog.continuous_agg cagg
WHERE ht.id = cagg.mat_hypertable_id
)
SELECT user_view,
relname AS mat_table,
(SELECT spcname FROM pg_tablespace WHERE oid = reltablespace) AS tablespace
FROM pg_class JOIN caggs ON pg_class.oid = caggs.mat_relid;

CREATE TABLE whatever(time BIGINT NOT NULL, data INTEGER);

SELECT hypertable_id AS whatever_nid
FROM create_hypertable('whatever', 'time', chunk_time_interval => 10)
\gset

CREATE OR REPLACE FUNCTION integer_now_test() RETURNS bigint
LANGUAGE SQL STABLE AS $$
SELECT coalesce(max(time), bigint '0') FROM whatever
$$;

SELECT set_integer_now_func('whatever', 'integer_now_test');

INSERT INTO whatever SELECT i, i FROM generate_series(0, 29) AS i;

-- Checking that the access method for the materialized hypertable is
-- set to the correct access method.
CREATE MATERIALIZED VIEW tableam_view USING heap2
WITH (timescaledb.continuous, timescaledb.materialized_only=true) AS
SELECT time_bucket('5', time), COUNT(data)
FROM whatever GROUP BY 1;

CREATE MATERIALIZED VIEW notableam_view
WITH (timescaledb.continuous, timescaledb.materialized_only=true) AS
SELECT time_bucket('5', time), COUNT(data)
FROM whatever GROUP BY 1;

SELECT user_view, mat_table, amname
FROM cagg_info,
LATERAL (SELECT relam FROM pg_class WHERE relname = mat_table) AS cls,
LATERAL (SELECT amname FROM pg_am WHERE oid = relam) AS am
WHERE user_view::text IN ('tableam_view', 'notableam_view');

-- Check that the view with the other access method actually works.
SELECT * FROM notableam_view ORDER BY 1;
SELECT * FROM tableam_view ORDER BY 1;
CALL refresh_continuous_aggregate('notableam_view', NULL, NULL);
CALL refresh_continuous_aggregate('tableam_view', NULL, NULL);
SELECT * FROM notableam_view ORDER BY 1;
SELECT * FROM tableam_view ORDER BY 1;

DROP MATERIALIZED VIEW notableam_view;
DROP MATERIALIZED VIEW tableam_view;