-- Sets a database and hostname as a meta node. CREATE OR REPLACE FUNCTION set_meta( hostname TEXT = gethostname(), port INT = inet_server_port(), database_name NAME = current_database(), username TEXT = current_user, password TEXT = NULL ) RETURNS VOID LANGUAGE PLPGSQL VOLATILE AS $BODY$ DECLARE meta_row _timescaledb_catalog.meta; BEGIN SELECT * INTO meta_row FROM _timescaledb_catalog.meta LIMIT 1; IF meta_row IS NULL THEN IF port IS NULL THEN port = 5432; END IF; PERFORM add_cluster_user(username, password); PERFORM _timescaledb_internal.setup_meta(); INSERT INTO _timescaledb_catalog.meta (database_name, hostname, port, server_name) VALUES (database_name, hostname, port, database_name); ELSE IF meta_row.database_name <> database_name OR meta_row.hostname <> hostname THEN RAISE EXCEPTION 'Changing meta info is not supported' USING ERRCODE = 'IO101'; END IF; END IF; END $BODY$; -- Adds a new node to the cluster, with its database name and hostname. CREATE OR REPLACE FUNCTION add_node( database_name NAME, hostname TEXT, port INT ) RETURNS VOID LANGUAGE PLPGSQL VOLATILE AS $BODY$ DECLARE schema_name NAME; new_id REGCLASS; BEGIN BEGIN new_id := nextval(pg_get_serial_sequence('_timescaledb_catalog.node', 'id')); schema_name := format('remote_%s_%s', new_id, database_name); IF database_name = current_database() THEN schema_name = '_timescaledb_catalog'; END IF; INSERT INTO _timescaledb_catalog.node (database_name, schema_name, server_name, hostname, port, id) VALUES (database_name, schema_name, database_name, hostname, port, new_id); EXCEPTION WHEN SQLSTATE '42710' THEN RAISE EXCEPTION 'Node % already exists', database_name USING ERRCODE = 'IO120'; END; END $BODY$; -- Adds new user credentials for the cluster. CREATE OR REPLACE FUNCTION add_cluster_user( username TEXT = current_user, password TEXT = NULL ) RETURNS VOID LANGUAGE PLPGSQL VOLATILE AS $BODY$ DECLARE BEGIN INSERT INTO _timescaledb_catalog.cluster_user (username, password) VALUES (username, password); EXCEPTION WHEN unique_violation THEN RAISE EXCEPTION 'User % already exists', username USING ERRCODE = 'IO130'; END $BODY$; CREATE OR REPLACE FUNCTION setup_timescaledb( database NAME = current_database(), username TEXT = current_user, password TEXT = NULL, hostname TEXT = gethostname(), port INT = inet_server_port() ) RETURNS VOID LANGUAGE PLPGSQL VOLATILE AS $BODY$ DECLARE meta_row _timescaledb_catalog.meta; BEGIN SELECT * INTO meta_row FROM _timescaledb_catalog.meta LIMIT 1; IF port IS NULL THEN port = 5432; END IF; IF meta_row IS NULL THEN PERFORM set_meta(hostname, port, database, username, password); PERFORM _timescaledb_internal.setup_main(); PERFORM add_node(database, hostname, port); ELSE RAISE EXCEPTION 'The node is already configured' USING ERRCODE = 'IO501'; END IF; END $BODY$; CREATE OR REPLACE FUNCTION add_partition_epoch( hypertable_id INTEGER, keyspace_start SMALLINT [], number_partitions SMALLINT, partitioning_column NAME, partitioning_func_schema NAME, partitioning_func NAME, tablespace_name NAME ) RETURNS VOID LANGUAGE SQL VOLATILE AS $BODY$ WITH epoch AS ( INSERT INTO _timescaledb_catalog.partition_epoch (hypertable_id, start_time, end_time, num_partitions, partitioning_func_schema, partitioning_func, partitioning_mod, partitioning_column) VALUES (hypertable_id, NULL, NULL, number_partitions, partitioning_func_schema, partitioning_func, 32768, partitioning_column) RETURNING id ) INSERT INTO _timescaledb_catalog.partition (epoch_id, keyspace_start, keyspace_end, tablespace) SELECT epoch.id, lag(start, 1, 0) OVER (), start - 1, tablespace_name FROM unnest(keyspace_start :: INT [] || (32768) :: INT) start, epoch $BODY$; CREATE OR REPLACE FUNCTION add_equi_partition_epoch( hypertable_id INTEGER, number_partitions SMALLINT, partitioning_column NAME, partitioning_func_schema NAME, partitioning_func NAME, tablespace_name NAME ) RETURNS VOID LANGUAGE SQL VOLATILE AS $BODY$ SELECT add_partition_epoch( hypertable_id, (SELECT ARRAY(SELECT start * 32768 / (number_partitions) FROM generate_series(1, number_partitions - 1) AS start) :: SMALLINT []), number_partitions, partitioning_column, partitioning_func_schema, partitioning_func, tablespace_name ) $BODY$;