Merged in time-column-name (pull request #23)

Allow time columns to take arbitrary names as well as be integer or timestamp(with or without time zone) types.
This commit is contained in:
Matvey Arye 2017-01-05 12:37:50 -05:00
commit dd1f32bd43
19 changed files with 671 additions and 286 deletions

View File

@ -17,6 +17,7 @@ sql/meta/sync_triggers.sql
sql/meta/setup_meta.sql
sql/meta/deleted_triggers.sql
sql/meta/ddl.sql
sql/main/time_util.sql
sql/main/table_creation.sql
sql/main/tables.sql
sql/main/cluster_user_triggers.sql

View File

@ -1,3 +1,4 @@
CREATE OR REPLACE FUNCTION _sysinternal.lock_for_chunk_close(
chunk_id INTEGER
)
@ -26,10 +27,14 @@ DECLARE
BEGIN
EXECUTE format(
$$
SELECT max("time")
SELECT max(%s)
FROM %I.%I
$$,
schema_name, table_name)
_sysinternal.extract_time_sql(
format('%I', _sysinternal.time_col_name_for_crn(schema_name, table_name)),
_sysinternal.time_col_type_for_crn(schema_name, table_name)
),
schema_name, table_name)
INTO max_time;
RETURN max_time;

View File

@ -74,13 +74,15 @@ BEGIN
END
$BODY$;
-- Gets the value of a field from a given row.
-- Gets the value of the time field from a given row.
--
-- field_name - Name of field/column to fetch
-- field_name - Name of time field/column to fetch
-- field_type - Type of the time record
-- copy_record - Record/row from a table
-- copy_table_name - Name of the relation to cast the record to
CREATE OR REPLACE FUNCTION _sysinternal.get_field_from_record(
CREATE OR REPLACE FUNCTION _sysinternal.get_time_field_from_record(
field_name NAME,
field_type REGTYPE,
copy_record anyelement,
copy_table_name TEXT
)
@ -91,8 +93,8 @@ DECLARE
BEGIN
EXECUTE format(
$$
SELECT row.%I FROM (SELECT (%L::%s).*) as row LIMIT 1
$$, field_name, copy_record, copy_table_name)
SELECT %s FROM (SELECT (%L::%s).*) as row LIMIT 1
$$, _sysinternal.extract_time_sql(format('row.%I', field_name), field_type), copy_record, copy_table_name)
INTO STRICT t;
RETURN t;
@ -119,6 +121,7 @@ DECLARE
distinct_table_oid REGCLASS;
time_point BIGINT;
time_field_name_point NAME;
time_field_type_point REGTYPE;
partition_id INT;
distinct_field TEXT;
distinct_clauses TEXT;
@ -127,18 +130,20 @@ BEGIN
time_point := 1;
EXECUTE format(
$$
SELECT _sysinternal.get_field_from_record(h.time_field_name, ct, '%1$s'), h.time_field_name, p.id
SELECT _sysinternal.get_time_field_from_record(h.time_field_name, h.time_field_type, ct, '%1$s'), h.time_field_name, h.time_field_type, p.id
FROM ONLY %1$s ct
LEFT JOIN hypertable h ON (h.NAME = %2$L)
LEFT JOIN partition_epoch pe ON (
pe.hypertable_name = %2$L AND
(pe.start_time <= (SELECT _sysinternal.get_field_from_record(h.time_field_name, ct, '%1$s'))::bigint OR pe.start_time IS NULL) AND
(pe.end_time >= (SELECT _sysinternal.get_field_from_record(h.time_field_name, ct, '%1$s'))::bigint OR pe.end_time IS NULL)
(pe.start_time <= (SELECT _sysinternal.get_time_field_from_record(h.time_field_name, h.time_field_type, ct, '%1$s'))::bigint
OR pe.start_time IS NULL) AND
(pe.end_time >= (SELECT _sysinternal.get_time_field_from_record(h.time_field_name, h.time_field_type, ct, '%1$s'))::bigint
OR pe.end_time IS NULL)
)
LEFT JOIN _sysinternal.get_partition_for_epoch_row(pe, ct, '%1$s') AS p ON(true)
LIMIT 1
$$, copy_table_oid, hypertable_name)
INTO STRICT time_point, time_field_name_point, partition_id;
INTO STRICT time_point, time_field_name_point, time_field_type_point, partition_id;
IF time_point IS NOT NULL AND partition_id IS NULL THEN
RAISE EXCEPTION 'Should never happen: could not find partition for insert'
USING ERRCODE = 'IO501';
@ -190,13 +195,15 @@ BEGIN
WITH selected AS
(
DELETE FROM ONLY %2$s
WHERE (%7$I >= %3$L OR %3$L IS NULL) and (%7$I <= %4$L OR %4$L IS NULL)
WHERE (%7$I >= %3$s OR %3$s IS NULL) and (%7$I <= %4$s OR %4$s IS NULL)
RETURNING *
)%5$s
INSERT INTO %1$s (%6$s) SELECT %6$s FROM selected;
$$,
format('%I.%I', crn_record.schema_name, crn_record.table_name) :: REGCLASS,
copy_table_oid, crn_record.start_time, crn_record.end_time,
copy_table_oid,
_sysinternal.time_literal_sql(crn_record.start_time, time_field_type_point),
_sysinternal.time_literal_sql(crn_record.end_time, time_field_type_point),
distinct_clauses,
_sysinternal.get_field_list(hypertable_name),
time_field_name_point);
@ -204,18 +211,20 @@ BEGIN
EXECUTE format(
$$
SELECT _sysinternal.get_field_from_record(h.time_field_name, ct, '%1$s'), h.time_field_name, p.id
SELECT _sysinternal.get_time_field_from_record(h.time_field_name, h.time_field_type, ct, '%1$s'), h.time_field_name, h.time_field_type, p.id
FROM ONLY %1$s ct
LEFT JOIN hypertable h ON (h.NAME = %2$L)
LEFT JOIN partition_epoch pe ON (
pe.hypertable_name = %2$L AND
(pe.start_time <= (SELECT _sysinternal.get_field_from_record(h.time_field_name, ct, '%1$s'))::bigint OR pe.start_time IS NULL) AND
(pe.end_time >= (SELECT _sysinternal.get_field_from_record(h.time_field_name, ct, '%1$s'))::bigint OR pe.end_time IS NULL)
(pe.start_time <= (SELECT _sysinternal.get_time_field_from_record(h.time_field_name, h.time_field_type, ct, '%1$s'))::bigint
OR pe.start_time IS NULL) AND
(pe.end_time >= (SELECT _sysinternal.get_time_field_from_record(h.time_field_name, h.time_field_type, ct, '%1$s'))::bigint
OR pe.end_time IS NULL)
)
LEFT JOIN _sysinternal.get_partition_for_epoch_row(pe, ct, '%1$s') AS p ON(true)
LIMIT 1
$$, copy_table_oid, hypertable_name)
INTO time_point, time_field_name_point, partition_id;
INTO time_point, time_field_name_point, time_field_type_point, partition_id;
IF time_point IS NOT NULL AND partition_id IS NULL THEN
RAISE EXCEPTION 'Should never happen: could not find partition for insert'

View File

@ -19,11 +19,17 @@ BEGIN
CREATE TYPE limit_by_field_type AS (field TEXT, count INT);
CREATE TYPE aggregate_type AS (group_time BIGINT, group_field TEXT);
--Grouptime is in usec if timestamp type used for time column in the data.
--If time is numeric, unit used by grouptime needs to match units in the data inserted
--(this is determined by user: inserted data can be in sec, usec, nanosec, etc.).
CREATE TYPE aggregate_type AS (group_time BIGINT, group_field TEXT);
CREATE TYPE field_condition_type AS (conjunctive predicate_conjunctive, predicates field_predicate []);
CREATE TYPE time_condition_type AS (from_time BIGINT, to_time BIGINT); --from_time inclusive; to_time exclusive\
--From_time/to_time is in usec if timestamp type used for time column in the data.
--If time is numeric, unit used by these fields needs to match units in the data inserted
--(this is determined by user: inserted data can be in sec, usec, nanosec, etc.).
CREATE TYPE time_condition_type AS (from_time BIGINT, to_time BIGINT); --from_time inclusive; to_time exclusive
CREATE TYPE ioql_query AS (
namespace_name TEXT, -- NOT NULL

View File

@ -26,13 +26,13 @@ SELECT CASE
END;
$BODY$ LANGUAGE SQL IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION get_partial_aggregate_sql(items select_item [], agg aggregate_type)
CREATE OR REPLACE FUNCTION get_partial_aggregate_sql(time_col_name NAME, time_col_type regtype, items select_item [], agg aggregate_type)
RETURNS TEXT AS $BODY$
SELECT CASE
WHEN agg.group_field IS NOT NULL THEN
format('%s, %s as group_time, %s', agg.group_field, get_time_clause(agg.group_time), field_list)
format('%s, %s as group_time, %s', agg.group_field, get_time_clause(time_col_name, time_col_type, agg.group_time), field_list)
ELSE
format('%s as group_time, %s', get_time_clause(agg.group_time), field_list)
format('%s as group_time, %s', get_time_clause(time_col_name, time_col_type, agg.group_time), field_list)
END
FROM
(
@ -104,13 +104,13 @@ SELECT CASE
END;
$BODY$ LANGUAGE SQL IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION get_combine_partial_aggregate_zero_value_sql(items select_item [], agg aggregate_type)
CREATE OR REPLACE FUNCTION get_combine_partial_aggregate_zero_value_sql(time_col_type regtype, items select_item [], agg aggregate_type)
RETURNS TEXT AS $BODY$
SELECT CASE
WHEN agg.group_field IS NOT NULL THEN
format('NULL::text as %s, NULL::bigint as group_time, %s', agg.group_field, field_list)
format('NULL::text as %s, NULL::%s as group_time, %s', agg.group_field, time_col_type, field_list)
ELSE
format('NULL::bigint as group_time, %s', field_list)
format('NULL::%s as group_time, %s', time_col_type, field_list)
END
FROM
(
@ -145,11 +145,12 @@ CREATE OR REPLACE FUNCTION get_partial_aggregate_column_def(query ioql_query)
RETURNS TEXT AS $BODY$
SELECT CASE
WHEN (query.aggregate).group_field IS NOT NULL THEN
format('%I %s, group_time bigint, %s', (query.aggregate).group_field,
format('%I %s, group_time %s, %s', (query.aggregate).group_field,
get_field_type(query.namespace_name, (query.aggregate).group_field),
get_time_field_type(query.namespace_name),
field_list)
ELSE
format('group_time bigint, %s', field_list)
format('group_time %s, %s', get_time_field_type(query.namespace_name), field_list)
END
FROM
(
@ -216,7 +217,7 @@ DECLARE
BEGIN
select_clause :=
'SELECT ' || get_partial_aggregate_sql(query.select_items, query.aggregate);
'SELECT ' || get_partial_aggregate_sql(get_time_field(query.namespace_name), get_time_field_type(query.namespace_name), query.select_items, query.aggregate);
RETURN base_query_raw(
select_clause,
@ -390,7 +391,7 @@ END
$BODY$;
CREATE OR REPLACE FUNCTION get_max_time_on_partition(part_replica partition_replica, additional_constraints TEXT)
CREATE OR REPLACE FUNCTION get_max_time_on_partition(time_col_name NAME, time_col_type regtype, part_replica partition_replica, additional_constraints TEXT)
RETURNS BIGINT AS
$BODY$
DECLARE
@ -404,12 +405,12 @@ BEGIN
FROM get_local_chunk_replica_node_for_pr_time_desc(part_replica) LOOP
EXECUTE format(
$$
SELECT time
FROM %I.%I
%s
SELECT %1$s AS time
FROM %2$I.%3$I
%4$s
ORDER BY time DESC NULLS LAST
LIMIT 1
$$, crn_row.schema_name, crn_row.table_name, get_where_clause(additional_constraints))
$$, _sysinternal.extract_time_sql(format('%I',time_col_name), time_col_type), crn_row.schema_name, crn_row.table_name, get_where_clause(additional_constraints))
INTO time;
IF time IS NOT NULL THEN
@ -434,7 +435,7 @@ SELECT format('SELECT * FROM (%s) as combined_node ',
coalesce(
string_agg(code_part, ' UNION ALL '),
format('SELECT %s WHERE FALSE',
get_combine_partial_aggregate_zero_value_sql(query.select_items, query.aggregate))
get_combine_partial_aggregate_zero_value_sql(get_time_field_type(query.namespace_name), query.select_items, query.aggregate))
))
-- query.limit_rows + 1, needed since a group can span across time. +1 guarantees group was closed
FROM
@ -458,7 +459,7 @@ $BODY$
SELECT (get_time_periods_limit_for_max(max_time.max_time, period_length, num_periods)).*
FROM
(
SELECT max(get_max_time_on_partition(pr, additional_constraints)) AS max_time
SELECT max(get_max_time_on_partition(get_time_field(epoch.hypertable_name),get_time_field_type(epoch.hypertable_name),pr, additional_constraints)) AS max_time
FROM get_partition_replicas(epoch, replica_id) pr
) AS max_time
$BODY$;
@ -473,15 +474,21 @@ DECLARE
trange time_range;
ungrouped_sql TEXT;
grouped_sql TEXT;
time_col_type regtype;
BEGIN
IF query.limit_time_periods IS NOT NULL THEN
time_col_type := get_time_field_type(query.namespace_name);
trange := get_time_periods_limit(epoch,
replica_id,
combine_predicates(default_predicates(query, epoch), additional_constraints),
(query.aggregate).group_time,
query.limit_time_periods);
additional_constraints := combine_predicates(
format('time >= %L AND time <=%L', trange.start_time, trange.end_time),
format('%1$I >= %2$s AND %1$I <=%3$s',
get_time_field(query.namespace_name),
_sysinternal.time_literal_sql(trange.start_time, time_col_type),
_sysinternal.time_literal_sql(trange.end_time, time_col_type)
),
additional_constraints);
END IF;

View File

@ -13,6 +13,8 @@ DECLARE
index INT = 0;
previous_tables TEXT = '';
code TEXT = '';
time_col_name NAME;
time_col_type REGTYPE;
query_sql_scan_base_table TEXT = '';
query_sql_scan TEXT = '';
@ -20,7 +22,8 @@ DECLARE
crn_row chunk_replica_node;
partition_row partition;
BEGIN
time_col_name := get_time_field(query.namespace_name);
time_col_type := get_time_field_type(query.namespace_name);
IF epoch.partitioning_field = (query.limit_by_field).field THEN
SELECT *
@ -67,10 +70,10 @@ BEGIN
get_full_select_clause_nonagg(query),
'FROM %1$s',
get_where_clause(
get_time_predicate(query.time_condition)
get_time_predicate(time_col_name, time_col_type, query.time_condition)
),
NULL,
'ORDER BY time DESC NULLS LAST',
format('ORDER BY %I DESC NULLS LAST', time_col_name),
format('LIMIT (SELECT count(*) * %L FROM distinct_value)', (query.limit_by_field).count * 2)
);
@ -98,10 +101,10 @@ BEGIN
get_where_clause(
default_predicates(query, epoch),
format('%1$I::text = dv_counts_min_time.value AND %1$I IS NOT NULL', (query.limit_by_field).field),
'(time < dv_counts_min_time.min_time OR dv_counts_min_time.min_time IS NULL)'
format('(%I < dv_counts_min_time.min_time OR dv_counts_min_time.min_time IS NULL)', time_col_name)
),
get_groupby_clause(query.aggregate),
'ORDER BY time DESC NULLS LAST, ' || (query.limit_by_field).field,
'ORDER BY '||quote_ident(time_col_name)||' DESC NULLS LAST, ' || (query.limit_by_field).field,
'LIMIT dv_counts_min_time.remaining_cnt');
FOR crn_row IN SELECT *
@ -116,7 +119,7 @@ BEGIN
FROM
(
SELECT
ROW_NUMBER() OVER (PARTITION BY %2$I ORDER BY time DESC NULLS LAST) as rank,
ROW_NUMBER() OVER (PARTITION BY %2$I ORDER BY %5$I DESC NULLS LAST) as rank,
res.*
FROM (%3$s) as res
) AS with_rank
@ -126,7 +129,8 @@ BEGIN
get_full_select_clause_nonagg(query),
(query.limit_by_field).field,
format(query_sql_scan, format('%I.%I', crn_row.schema_name, crn_row.table_name)),
(query.limit_by_field).count
(query.limit_by_field).count,
time_col_name
);
previous_tables := 'SELECT * FROM result_scan';
@ -138,7 +142,7 @@ BEGIN
SELECT original.value AS value, original.cnt - coalesce(existing.cnt, 0) as remaining_cnt, min_time as min_time
FROM distinct_value as original
LEFT JOIN (
SELECT %1$s::text AS value, count(*) AS cnt, min(time) AS min_time
SELECT %1$s::text AS value, count(*) AS cnt, min(%5$I) AS min_time
FROM (%2$s) AS previous_results
GROUP BY %1$s
) as existing on (original.value = existing.value)
@ -153,7 +157,8 @@ BEGIN
(query.limit_by_field).field,
previous_tables,
index,
format(query_sql_jump, format('%I.%I', crn_row.schema_name, crn_row.table_name))
format(query_sql_jump, format('%I.%I', crn_row.schema_name, crn_row.table_name)),
time_col_name
);
previous_tables := previous_tables || format(' UNION ALL SELECT * FROM results_%s', index);
@ -228,12 +233,12 @@ BEGIN
FROM
(
SELECT
ROW_NUMBER() OVER (PARTITION BY %2$s ORDER BY time DESC NULLS LAST) as rank,
ROW_NUMBER() OVER (PARTITION BY %2$s ORDER BY %7$I DESC NULLS LAST) as rank,
combined_node.*
FROM (%4$s) as combined_node
) AS node_result
WHERE rank <= %5$L
ORDER BY time DESC NULLS LAST, %2$s
ORDER BY %7$I DESC NULLS LAST, %2$s
%6$s
$$,
get_result_column_def_list_nonagg(query),
@ -241,7 +246,8 @@ BEGIN
get_result_column_list_nonagg(query),
string_agg(code_part, ' UNION ALL '),
(query.limit_by_field).count,
get_limit_clause(query.limit_rows)
get_limit_clause(query.limit_rows),
get_time_field(query.namespace_name)
)
INTO STRICT code
FROM
@ -254,11 +260,12 @@ BEGIN
$$
SELECT *
FROM (%1$s) AS combined_node
ORDER BY time DESC NULLS LAST
ORDER BY %3$I DESC NULLS LAST
%2$s
$$,
string_agg(code_part, ' UNION ALL '),
get_limit_clause(query.limit_rows)
get_limit_clause(query.limit_rows),
get_time_field(query.namespace_name)
)
INTO STRICT code
FROM

View File

@ -29,10 +29,10 @@ SELECT CASE
ARRAY [
format('%I %s', (query.aggregate).group_field,
get_field_type(query.namespace_name, (query.aggregate).group_field)),
'time BIGINT'] ||
'time '|| get_time_field_type(query.namespace_name) ] ||
field_array
ELSE
ARRAY ['time bigint'] ||
ARRAY ['time '|| get_time_field_type(query.namespace_name)] ||
field_array
END
FROM

View File

@ -1,11 +1,18 @@
CREATE OR REPLACE FUNCTION get_time_clause(group_time BIGINT)
CREATE OR REPLACE FUNCTION get_time_clause(time_col_name NAME, time_col_type regtype, group_time BIGINT)
RETURNS TEXT LANGUAGE SQL IMMUTABLE AS
$BODY$
SELECT CASE
WHEN group_time IS NOT NULL THEN
format('(time - (time %% %L::bigint))::bigint', group_time)
ELSE
'time'
WHEN group_time IS NULL THEN
format('%I', time_col_name)
WHEN time_col_type IN ('BIGINT', 'INTEGER', 'SMALLINT') THEN
format('(%1$I - (%1$I %% %2$L::%3$s))::%3$s', time_col_name, group_time, time_col_type)
WHEN time_col_type IN ('TIMESTAMP', 'TIMESTAMPTZ') THEN
--NOTE: note the conversion at the end. important for timestamp without timezone. right conversion?
format('to_timestamp( (
(EXTRACT(EPOCH from %1$I)*1e6)::bigint -
( (EXTRACT(EPOCH from %1$I)*1e6)::bigint %% %2$L::bigint )
)::double precision / 1e6
)::%3$s', time_col_name, group_time, time_col_type) --group time is given in us
END;
$BODY$;
@ -30,11 +37,14 @@ FROM unnest(clauses) AS clause(val)
WHERE val IS NOT NULL;
$BODY$;
CREATE OR REPLACE FUNCTION get_time_predicate(cond time_condition_type)
CREATE OR REPLACE FUNCTION get_time_predicate(time_col_name NAME, time_col_type regtype, cond time_condition_type)
RETURNS TEXT LANGUAGE SQL IMMUTABLE AS
$BODY$
SELECT string_agg(clauses.val, ' AND ')
FROM (VALUES ('time>=' || cond.from_time), ('time<' || cond.to_time)) AS clauses(val);
FROM (
VALUES (format('%I >= ', time_col_name) || NULLIF(_sysinternal.time_literal_sql(cond.from_time, time_col_type), 'NULL')),
(format('%I < ', time_col_name) || NULLIF(_sysinternal.time_literal_sql(cond.to_time, time_col_type), 'NULL'))
) AS clauses(val);
$BODY$;
--TODO: Review this
@ -98,7 +108,7 @@ CREATE OR REPLACE FUNCTION default_predicates(query ioql_query, epoch partition_
RETURNS TEXT LANGUAGE SQL STABLE AS
$BODY$
SELECT combine_predicates(
get_time_predicate(query.time_condition),
get_time_predicate(get_time_field(query.namespace_name), get_time_field_type(query.namespace_name), query.time_condition),
get_field_predicate_clause(query.field_condition),
get_select_field_predicate(query.select_items),
get_partitioning_predicate(query, epoch)
@ -141,9 +151,9 @@ CREATE OR REPLACE FUNCTION get_orderby_clause_nonagg(query ioql_query)
$BODY$
SELECT CASE
WHEN query.limit_by_field IS NOT NULL THEN
'ORDER BY time DESC NULLS LAST, ' || (query.limit_by_field).field
ELSE
'ORDER BY time DESC NULLS LAST'
format('ORDER BY %I DESC NULLS LAST, %s', get_time_field(query.namespace_name), (query.limit_by_field).field)
ELSE
format('ORDER BY %I DESC NULLS LAST', get_time_field(query.namespace_name))
END;
$BODY$;

View File

@ -31,8 +31,8 @@ BEGIN
)
SELECT without_limit.*
FROM without_limit,
get_time_periods_limit_for_max((SELECT max(time) from without_limit), %4$L, %5$L) limits
WHERE time >= limits.start_time AND time <= limits.end_time
get_time_periods_limit_for_max((SELECT max(%6$s) from without_limit), %4$L, %5$L) limits
WHERE %7$s >= limits.start_time AND %7$s <= limits.end_time
%2$s
%3$s
$$,
@ -40,9 +40,11 @@ BEGIN
get_orderby_clause_agg(query, 'time'),
get_limit_clause(query.limit_rows),
(query.aggregate).group_time,
query.limit_time_periods
);
ELSE
query.limit_time_periods,
_sysinternal.extract_time_sql('time', get_time_field_type(query.namespace_name)),
_sysinternal.extract_time_sql('without_limit.time', get_time_field_type(query.namespace_name))
);
ELSE
RETURN format(
$$
SELECT *

View File

@ -9,14 +9,15 @@ BEGIN
FROM ioql_exec_query_nodes(
%2$L, %5$L, %1$L
) as res(%1$s)
ORDER BY time DESC NULLS LAST
ORDER BY %6$I DESC NULLS LAST
%4$s
$$,
get_result_column_def_list_nonagg(query),
query,
query.namespace_name,
get_limit_clause(query.limit_rows),
epoch
epoch,
get_time_field(query.namespace_name)
);
END
$BODY$;
@ -31,14 +32,14 @@ BEGIN
SELECT %4$s
FROM (
SELECT
ROW_NUMBER() OVER (PARTITION BY %2$s ORDER BY time DESC NULLS LAST) AS rank,
ROW_NUMBER() OVER (PARTITION BY %2$s ORDER BY %8$I DESC NULLS LAST) AS rank,
*
FROM (
%5$s
) as ieq
) as ranked
WHERE rank <= %7$L OR time IS NULL
ORDER BY time DESC NULLS LAST, %2$s
WHERE rank <= %7$L OR %8$I IS NULL
ORDER BY %8$I DESC NULLS LAST, %2$s
%6$s
$$,
get_result_column_def_list_nonagg(query),
@ -47,7 +48,8 @@ BEGIN
get_result_column_list_nonagg(query),
ioql_query_nonagg_without_limit_sql(query, epoch),
get_limit_clause(query.limit_rows),
(query.limit_by_field).count
(query.limit_by_field).count,
get_time_field(query.namespace_name)
);
ELSE
RETURN format(
@ -56,12 +58,13 @@ BEGIN
FROM (
%2$s
) as ieq(%1$s)
ORDER BY time DESC NULLS LAST
ORDER BY %4$I DESC NULLS LAST
%3$s
$$,
get_result_column_list_nonagg(query),
ioql_query_nonagg_without_limit_sql(query, epoch),
get_limit_clause(query.limit_rows)
get_limit_clause(query.limit_rows),
get_time_field(query.namespace_name)
);
END IF;
END;

View File

@ -22,6 +22,9 @@ $BODY$
SELECT get_distinct_table_oid(hypertable_name, replica_id, current_database())
$BODY$;
-- Get the name of the time column for a hypertable.
--
-- hypertable_name - name of the hypertable.
CREATE OR REPLACE FUNCTION get_time_field(
hypertable_name NAME
)
@ -32,6 +35,21 @@ $BODY$
WHERE h.name = hypertable_name;
$BODY$;
-- Get the type of the time column for a hypertable.
--
-- hypertable_name - name of the hypertable.
CREATE OR REPLACE FUNCTION get_time_field_type(
hypertable_name NAME
)
RETURNS REGTYPE LANGUAGE SQL STABLE AS
$BODY$
SELECT time_field_type
FROM hypertable h
WHERE h.name = hypertable_name;
$BODY$;
CREATE OR REPLACE FUNCTION get_field_names(
hypertable_name NAME
)
@ -181,5 +199,51 @@ $BODY$
WHERE c.OID = table_oid;
$BODY$;
-- Get the name of the time column for a chunk_replica_node.
--
-- schema_name, table_name - name of the schema and table for the table represented by the crn.
CREATE OR REPLACE FUNCTION _sysinternal.time_col_name_for_crn(
schema_name NAME,
table_name NAME
)
RETURNS NAME LANGUAGE PLPGSQL STABLE AS
$BODY$
DECLARE
time_col_name NAME;
BEGIN
SELECT h.time_field_name INTO STRICT time_col_name
FROM hypertable h
INNER JOIN partition_epoch pe ON (pe.hypertable_name = h.name)
INNER JOIN partition p ON (p.epoch_id = pe.id)
INNER JOIN chunk c ON (c.partition_id = p.id)
INNER JOIN chunk_replica_node crn ON (crn.chunk_id = c.id)
WHERE crn.schema_name = time_col_name_for_crn.schema_name AND
crn.table_name = time_col_name_for_crn.table_name;
RETURN time_col_name;
END
$BODY$;
-- Get the type of the time column for a chunk_replica_node.
--
-- schema_name, table_name - name of the schema and table for the table represented by the crn.
CREATE OR REPLACE FUNCTION _sysinternal.time_col_type_for_crn(
schema_name NAME,
table_name NAME
)
RETURNS REGTYPE LANGUAGE PLPGSQL STABLE AS
$BODY$
DECLARE
time_col_type REGTYPE;
BEGIN
SELECT h.time_field_type INTO STRICT time_col_type
FROM hypertable h
INNER JOIN partition_epoch pe ON (pe.hypertable_name = h.name)
INNER JOIN partition p ON (p.epoch_id = pe.id)
INNER JOIN chunk c ON (c.partition_id = p.id)
INNER JOIN chunk_replica_node crn ON (crn.chunk_id = c.id)
WHERE crn.schema_name = time_col_type_for_crn.schema_name AND
crn.table_name = time_col_type_for_crn.table_name;
RETURN time_col_type;
END
$BODY$;

View File

@ -224,31 +224,41 @@ CREATE OR REPLACE FUNCTION _sysinternal.set_time_constraint(
RETURNS VOID LANGUAGE PLPGSQL VOLATILE AS
$BODY$
DECLARE
time_col_type regtype;
BEGIN
time_col_type := _sysinternal.time_col_type_for_crn(schema_name, table_name);
EXECUTE format(
$$
ALTER TABLE %I.%I DROP CONSTRAINT IF EXISTS time_range
$$,
schema_name, table_name);
schema_name, table_name);
IF start_time IS NOT NULL AND end_time IS NOT NULL THEN
EXECUTE format(
$$
ALTER TABLE %I.%I ADD CONSTRAINT time_range CHECK(time >= %L AND time <= %L)
ALTER TABLE %2$I.%3$I ADD CONSTRAINT time_range CHECK(%1$I >= %4$s AND %1$I <= %5$s)
$$,
schema_name, table_name, start_time, end_time);
_sysinternal.time_col_name_for_crn(schema_name, table_name),
schema_name, table_name,
_sysinternal.time_literal_sql(start_time, time_col_type),
_sysinternal.time_literal_sql(end_time, time_col_type));
ELSIF start_time IS NOT NULL THEN
EXECUTE format(
$$
ALTER TABLE %I.%I ADD CONSTRAINT time_range CHECK(time >= %L)
ALTER TABLE %I.%I ADD CONSTRAINT time_range CHECK(%I >= %s)
$$,
schema_name, table_name, start_time);
ELSIF end_time IS NOT NULL THEN
schema_name, table_name,
_sysinternal.time_col_name_for_crn(schema_name, table_name),
_sysinternal.time_literal_sql(start_time, time_col_type));
ELSIF end_time IS NOT NULL THEN
EXECUTE format(
$$
ALTER TABLE %I.%I ADD CONSTRAINT time_range CHECK(time <= %L)
ALTER TABLE %I.%I ADD CONSTRAINT time_range CHECK(%I <= %s)
$$,
schema_name, table_name, end_time);
schema_name, table_name,
_sysinternal.time_col_name_for_crn(schema_name, table_name),
_sysinternal.time_literal_sql(end_time, time_col_type));
END IF;
END
$BODY$;

View File

@ -0,0 +1,47 @@
-- This file contains utilities for time conversion.
-- Time can be represented in a hypertable as an int* (bigint/integer/smallint) or as a timestamp type (
-- with or without timezones). In or metatables and other internal systems all time values are stored as bigint.
-- Converting from int* columns to internal representation is a cast to bigint.
-- Converting from timestamps to internal representation is conversion to epoch (in microseconds).
-- Gets the sql code for extracting the internal (bigint) time value from the identifier with the given field_type.
CREATE OR REPLACE FUNCTION _sysinternal.extract_time_sql(
identifier text,
field_type REGTYPE
)
RETURNS text LANGUAGE PLPGSQL STABLE AS
$BODY$
DECLARE
BEGIN
CASE field_type
WHEN 'BIGINT'::regtype, 'INTEGER'::regtype, 'SMALLINT'::regtype THEN
RETURN format('%s::bigint', identifier); --scale determined by user.
WHEN 'TIMESTAMP'::regtype, 'TIMESTAMPTZ'::regtype THEN
RETURN format('((EXTRACT(epoch FROM %s)*1e6)::bigint)', identifier); --microseconds
END CASE;
END
$BODY$;
-- Gets the sql code for representing the literal for the given time value (in the internal representation) as the field_type.
CREATE OR REPLACE FUNCTION _sysinternal.time_literal_sql(
time_value BIGINT,
field_type REGTYPE
)
RETURNS text LANGUAGE PLPGSQL STABLE AS
$BODY$
DECLARE
BEGIN
IF time_value IS NULL THEN
RETURN format('%L', NULL);
END IF;
CASE field_type
WHEN 'BIGINT'::regtype, 'INTEGER'::regtype, 'SMALLINT'::regtype THEN
RETURN format('%L', time_value); --scale determined by user.
WHEN 'TIMESTAMP'::regtype, 'TIMESTAMPTZ'::regtype THEN
--assume time_value is in microsec
RETURN format('%2$s %1$L', to_timestamp(time_value::double precision / 1e6), field_type); --microseconds
END CASE;
END
$BODY$;

View File

@ -40,22 +40,22 @@ SELECT add_node('test2' :: NAME, 'localhost');
\c Test1
CREATE TABLE PUBLIC."testNs" (
time BIGINT NOT NULL,
"timeCustom" BIGINT NOT NULL,
device_id TEXT NOT NULL,
series_0 DOUBLE PRECISION NULL,
series_1 DOUBLE PRECISION NULL,
series_2 DOUBLE PRECISION NULL,
series_bool BOOLEAN NULL
);
CREATE INDEX ON PUBLIC."testNs" (device_id, time DESC NULLS LAST) WHERE device_id IS NOT NULL;
CREATE INDEX ON PUBLIC."testNs" (time DESC NULLS LAST, series_0) WHERE series_0 IS NOT NULL;
CREATE INDEX ON PUBLIC."testNs" (time DESC NULLS LAST, series_1) WHERE series_1 IS NOT NULL;
CREATE INDEX ON PUBLIC."testNs" (time DESC NULLS LAST, series_2) WHERE series_2 IS NOT NULL;
CREATE INDEX ON PUBLIC."testNs" (time DESC NULLS LAST, series_bool) WHERE series_bool IS NOT NULL;
SELECT * FROM add_hypertable('"public"."testNs"', 'time', 'device_id', hypertable_name=>'testNs', associated_schema_name=>'testNs' );
CREATE INDEX ON PUBLIC."testNs" (device_id, "timeCustom" DESC NULLS LAST) WHERE device_id IS NOT NULL;
CREATE INDEX ON PUBLIC."testNs" ("timeCustom" DESC NULLS LAST, series_0) WHERE series_0 IS NOT NULL;
CREATE INDEX ON PUBLIC."testNs" ("timeCustom" DESC NULLS LAST, series_1) WHERE series_1 IS NOT NULL;
CREATE INDEX ON PUBLIC."testNs" ("timeCustom" DESC NULLS LAST, series_2) WHERE series_2 IS NOT NULL;
CREATE INDEX ON PUBLIC."testNs" ("timeCustom" DESC NULLS LAST, series_bool) WHERE series_bool IS NOT NULL;
SELECT * FROM add_hypertable('"public"."testNs"', 'timeCustom', 'device_id', hypertable_name=>'testNs', associated_schema_name=>'testNs' );
name | main_schema_name | main_table_name | associated_schema_name | associated_table_prefix | root_schema_name | root_table_name | distinct_schema_name | distinct_table_name | replication_factor | placement | time_field_name | time_field_type | created_on
--------+------------------+-----------------+------------------------+-------------------------+------------------+-----------------+----------------------+---------------------+--------------------+-----------+-----------------+-----------------+------------
testNs | public | testNs | testNs | _hyper_1 | testNs | _hyper_1_root | testNs | _hyper_1_distinct | 1 | STICKY | time | bigint | Test1
testNs | public | testNs | testNs | _hyper_1 | testNs | _hyper_1_root | testNs | _hyper_1_distinct | 1 | STICKY | timeCustom | bigint | Test1
(1 row)
SELECT set_is_distinct_flag('"public"."testNs"', 'device_id', TRUE);
@ -78,87 +78,87 @@ INNER JOIN chunk c ON (c.partition_id = part.id);
\c Test1
BEGIN;
INSERT INTO "testNs"(time, device_id, series_0, series_1) VALUES
INSERT INTO "testNs"("timeCustom", device_id, series_0, series_1) VALUES
(1257987600000000000, 'dev1', 1.5, 1),
(1257987600000000000, 'dev1', 1.5, 2),
(1257894002000000000, 'dev1', 2.5, 3);
COMMIT;
\c test2
BEGIN;
INSERT INTO "testNs"(time, device_id, series_0, series_1) VALUES
INSERT INTO "testNs"("timeCustom", device_id, series_0, series_1) VALUES
(1257894000000000000, 'dev2', 1.5, 1),
(1257894000000000000, 'dev2', 1.5, 2);
COMMIT;
\c Test1
\d+ "testNs".*
Index "testNs.1-testNs_device_id_time_idx"
Column | Type | Definition | Storage
-----------+--------+------------+----------
device_id | text | device_id | extended
time | bigint | "time" | plain
Index "testNs.1-testNs_device_id_timeCustom_idx"
Column | Type | Definition | Storage
------------+--------+--------------+----------
device_id | text | device_id | extended
timeCustom | bigint | "timeCustom" | plain
btree, for table "testNs._hyper_1_1_0_1_data", predicate (device_id IS NOT NULL)
Index "testNs.10-testNs_time_series_bool_idx"
Column | Type | Definition | Storage
-------------+---------+-------------+---------
time | bigint | "time" | plain
series_bool | boolean | series_bool | plain
Index "testNs.10-testNs_timeCustom_series_bool_idx"
Column | Type | Definition | Storage
-------------+---------+--------------+---------
timeCustom | bigint | "timeCustom" | plain
series_bool | boolean | series_bool | plain
btree, for table "testNs._hyper_1_1_0_2_data", predicate (series_bool IS NOT NULL)
Index "testNs.2-testNs_time_series_0_idx"
Column | Type | Definition | Storage
----------+------------------+------------+---------
time | bigint | "time" | plain
series_0 | double precision | series_0 | plain
Index "testNs.2-testNs_timeCustom_series_0_idx"
Column | Type | Definition | Storage
------------+------------------+--------------+---------
timeCustom | bigint | "timeCustom" | plain
series_0 | double precision | series_0 | plain
btree, for table "testNs._hyper_1_1_0_1_data", predicate (series_0 IS NOT NULL)
Index "testNs.3-testNs_time_series_1_idx"
Column | Type | Definition | Storage
----------+------------------+------------+---------
time | bigint | "time" | plain
series_1 | double precision | series_1 | plain
Index "testNs.3-testNs_timeCustom_series_1_idx"
Column | Type | Definition | Storage
------------+------------------+--------------+---------
timeCustom | bigint | "timeCustom" | plain
series_1 | double precision | series_1 | plain
btree, for table "testNs._hyper_1_1_0_1_data", predicate (series_1 IS NOT NULL)
Index "testNs.4-testNs_time_series_2_idx"
Column | Type | Definition | Storage
----------+------------------+------------+---------
time | bigint | "time" | plain
series_2 | double precision | series_2 | plain
Index "testNs.4-testNs_timeCustom_series_2_idx"
Column | Type | Definition | Storage
------------+------------------+--------------+---------
timeCustom | bigint | "timeCustom" | plain
series_2 | double precision | series_2 | plain
btree, for table "testNs._hyper_1_1_0_1_data", predicate (series_2 IS NOT NULL)
Index "testNs.5-testNs_time_series_bool_idx"
Column | Type | Definition | Storage
-------------+---------+-------------+---------
time | bigint | "time" | plain
series_bool | boolean | series_bool | plain
Index "testNs.5-testNs_timeCustom_series_bool_idx"
Column | Type | Definition | Storage
-------------+---------+--------------+---------
timeCustom | bigint | "timeCustom" | plain
series_bool | boolean | series_bool | plain
btree, for table "testNs._hyper_1_1_0_1_data", predicate (series_bool IS NOT NULL)
Index "testNs.6-testNs_device_id_time_idx"
Column | Type | Definition | Storage
-----------+--------+------------+----------
device_id | text | device_id | extended
time | bigint | "time" | plain
Index "testNs.6-testNs_device_id_timeCustom_idx"
Column | Type | Definition | Storage
------------+--------+--------------+----------
device_id | text | device_id | extended
timeCustom | bigint | "timeCustom" | plain
btree, for table "testNs._hyper_1_1_0_2_data", predicate (device_id IS NOT NULL)
Index "testNs.7-testNs_time_series_0_idx"
Column | Type | Definition | Storage
----------+------------------+------------+---------
time | bigint | "time" | plain
series_0 | double precision | series_0 | plain
Index "testNs.7-testNs_timeCustom_series_0_idx"
Column | Type | Definition | Storage
------------+------------------+--------------+---------
timeCustom | bigint | "timeCustom" | plain
series_0 | double precision | series_0 | plain
btree, for table "testNs._hyper_1_1_0_2_data", predicate (series_0 IS NOT NULL)
Index "testNs.8-testNs_time_series_1_idx"
Column | Type | Definition | Storage
----------+------------------+------------+---------
time | bigint | "time" | plain
series_1 | double precision | series_1 | plain
Index "testNs.8-testNs_timeCustom_series_1_idx"
Column | Type | Definition | Storage
------------+------------------+--------------+---------
timeCustom | bigint | "timeCustom" | plain
series_1 | double precision | series_1 | plain
btree, for table "testNs._hyper_1_1_0_2_data", predicate (series_1 IS NOT NULL)
Index "testNs.9-testNs_time_series_2_idx"
Column | Type | Definition | Storage
----------+------------------+------------+---------
time | bigint | "time" | plain
series_2 | double precision | series_2 | plain
Index "testNs.9-testNs_timeCustom_series_2_idx"
Column | Type | Definition | Storage
------------+------------------+--------------+---------
timeCustom | bigint | "timeCustom" | plain
series_2 | double precision | series_2 | plain
btree, for table "testNs._hyper_1_1_0_2_data", predicate (series_2 IS NOT NULL)
Table "testNs._hyper_1_0_1_distinct_data"
@ -188,7 +188,7 @@ Child tables: "testNs"._hyper_1_0_1_distinct_data
Table "testNs._hyper_1_0_replica"
Column | Type | Modifiers | Storage | Stats target | Description
-------------+------------------+-----------+----------+--------------+-------------
time | bigint | not null | plain | |
timeCustom | bigint | not null | plain | |
device_id | text | not null | extended | |
series_0 | double precision | | plain | |
series_1 | double precision | | plain | |
@ -201,47 +201,47 @@ Child tables: "testNs"._hyper_1_1_0_partition,
Table "testNs._hyper_1_1_0_1_data"
Column | Type | Modifiers | Storage | Stats target | Description
-------------+------------------+-----------+----------+--------------+-------------
time | bigint | not null | plain | |
timeCustom | bigint | not null | plain | |
device_id | text | not null | extended | |
series_0 | double precision | | plain | |
series_1 | double precision | | plain | |
series_2 | double precision | | plain | |
series_bool | boolean | | plain | |
Indexes:
"1-testNs_device_id_time_idx" btree (device_id, "time" DESC NULLS LAST) WHERE device_id IS NOT NULL
"2-testNs_time_series_0_idx" btree ("time" DESC NULLS LAST, series_0) WHERE series_0 IS NOT NULL
"3-testNs_time_series_1_idx" btree ("time" DESC NULLS LAST, series_1) WHERE series_1 IS NOT NULL
"4-testNs_time_series_2_idx" btree ("time" DESC NULLS LAST, series_2) WHERE series_2 IS NOT NULL
"5-testNs_time_series_bool_idx" btree ("time" DESC NULLS LAST, series_bool) WHERE series_bool IS NOT NULL
"1-testNs_device_id_timeCustom_idx" btree (device_id, "timeCustom" DESC NULLS LAST) WHERE device_id IS NOT NULL
"2-testNs_timeCustom_series_0_idx" btree ("timeCustom" DESC NULLS LAST, series_0) WHERE series_0 IS NOT NULL
"3-testNs_timeCustom_series_1_idx" btree ("timeCustom" DESC NULLS LAST, series_1) WHERE series_1 IS NOT NULL
"4-testNs_timeCustom_series_2_idx" btree ("timeCustom" DESC NULLS LAST, series_2) WHERE series_2 IS NOT NULL
"5-testNs_timeCustom_series_bool_idx" btree ("timeCustom" DESC NULLS LAST, series_bool) WHERE series_bool IS NOT NULL
Check constraints:
"partition" CHECK (get_partition_for_key(device_id, 32768) >= '0'::smallint AND get_partition_for_key(device_id, 32768) <= '16383'::smallint)
"time_range" CHECK ("time" <= '1257983999999999999'::bigint)
"time_range" CHECK ("timeCustom" <= '1257983999999999999'::bigint)
Inherits: "testNs"._hyper_1_1_0_partition
Table "testNs._hyper_1_1_0_2_data"
Column | Type | Modifiers | Storage | Stats target | Description
-------------+------------------+-----------+----------+--------------+-------------
time | bigint | not null | plain | |
timeCustom | bigint | not null | plain | |
device_id | text | not null | extended | |
series_0 | double precision | | plain | |
series_1 | double precision | | plain | |
series_2 | double precision | | plain | |
series_bool | boolean | | plain | |
Indexes:
"10-testNs_time_series_bool_idx" btree ("time" DESC NULLS LAST, series_bool) WHERE series_bool IS NOT NULL
"6-testNs_device_id_time_idx" btree (device_id, "time" DESC NULLS LAST) WHERE device_id IS NOT NULL
"7-testNs_time_series_0_idx" btree ("time" DESC NULLS LAST, series_0) WHERE series_0 IS NOT NULL
"8-testNs_time_series_1_idx" btree ("time" DESC NULLS LAST, series_1) WHERE series_1 IS NOT NULL
"9-testNs_time_series_2_idx" btree ("time" DESC NULLS LAST, series_2) WHERE series_2 IS NOT NULL
"10-testNs_timeCustom_series_bool_idx" btree ("timeCustom" DESC NULLS LAST, series_bool) WHERE series_bool IS NOT NULL
"6-testNs_device_id_timeCustom_idx" btree (device_id, "timeCustom" DESC NULLS LAST) WHERE device_id IS NOT NULL
"7-testNs_timeCustom_series_0_idx" btree ("timeCustom" DESC NULLS LAST, series_0) WHERE series_0 IS NOT NULL
"8-testNs_timeCustom_series_1_idx" btree ("timeCustom" DESC NULLS LAST, series_1) WHERE series_1 IS NOT NULL
"9-testNs_timeCustom_series_2_idx" btree ("timeCustom" DESC NULLS LAST, series_2) WHERE series_2 IS NOT NULL
Check constraints:
"partition" CHECK (get_partition_for_key(device_id, 32768) >= '0'::smallint AND get_partition_for_key(device_id, 32768) <= '16383'::smallint)
"time_range" CHECK ("time" >= '1257984000000000000'::bigint)
"time_range" CHECK ("timeCustom" >= '1257984000000000000'::bigint)
Inherits: "testNs"._hyper_1_1_0_partition
Table "testNs._hyper_1_1_0_partition"
Column | Type | Modifiers | Storage | Stats target | Description
-------------+------------------+-----------+----------+--------------+-------------
time | bigint | not null | plain | |
timeCustom | bigint | not null | plain | |
device_id | text | not null | extended | |
series_0 | double precision | | plain | |
series_1 | double precision | | plain | |
@ -256,7 +256,7 @@ Child tables: "testNs"._hyper_1_1_0_1_data,
Table "testNs._hyper_1_2_0_partition"
Column | Type | Modifiers | Storage | Stats target | Description
-------------+------------------+-----------+----------+--------------+-------------
time | bigint | not null | plain | |
timeCustom | bigint | not null | plain | |
device_id | text | not null | extended | |
series_0 | double precision | | plain | |
series_1 | double precision | | plain | |
@ -285,7 +285,7 @@ primary key, btree, for table "testNs._hyper_1_distinct"
Table "testNs._hyper_1_root"
Column | Type | Modifiers | Storage | Stats target | Description
-------------+------------------+-----------+----------+--------------+-------------
time | bigint | not null | plain | |
timeCustom | bigint | not null | plain | |
device_id | text | not null | extended | |
series_0 | double precision | | plain | |
series_1 | double precision | | plain | |
@ -315,7 +315,7 @@ Child tables: "testNs"._hyper_1_0_1_distinct_data
Table "testNs._hyper_1_0_replica"
Column | Type | Modifiers | Storage | Stats target | Description
-------------+------------------+-----------+----------+--------------+-------------
time | bigint | not null | plain | |
timeCustom | bigint | not null | plain | |
device_id | text | not null | extended | |
series_0 | double precision | | plain | |
series_1 | double precision | | plain | |
@ -328,7 +328,7 @@ Child tables: "testNs"._hyper_1_1_0_partition,
Foreign table "testNs._hyper_1_1_0_1_data"
Column | Type | Modifiers | FDW Options | Storage | Stats target | Description
-------------+------------------+-----------+-------------+----------+--------------+-------------
time | bigint | not null | | plain | |
timeCustom | bigint | not null | | plain | |
device_id | text | not null | | extended | |
series_0 | double precision | | | plain | |
series_1 | double precision | | | plain | |
@ -336,7 +336,7 @@ Child tables: "testNs"._hyper_1_1_0_partition,
series_bool | boolean | | | plain | |
Check constraints:
"partition" CHECK (get_partition_for_key(device_id, 32768) >= '0'::smallint AND get_partition_for_key(device_id, 32768) <= '16383'::smallint)
"time_range" CHECK ("time" <= '1257983999999999999'::bigint)
"time_range" CHECK ("timeCustom" <= '1257983999999999999'::bigint)
Server: Test1
FDW Options: (schema_name 'testNs', table_name '_hyper_1_1_0_1_data')
Inherits: "testNs"._hyper_1_1_0_partition
@ -344,7 +344,7 @@ Inherits: "testNs"._hyper_1_1_0_partition
Foreign table "testNs._hyper_1_1_0_2_data"
Column | Type | Modifiers | FDW Options | Storage | Stats target | Description
-------------+------------------+-----------+-------------+----------+--------------+-------------
time | bigint | not null | | plain | |
timeCustom | bigint | not null | | plain | |
device_id | text | not null | | extended | |
series_0 | double precision | | | plain | |
series_1 | double precision | | | plain | |
@ -352,7 +352,7 @@ Inherits: "testNs"._hyper_1_1_0_partition
series_bool | boolean | | | plain | |
Check constraints:
"partition" CHECK (get_partition_for_key(device_id, 32768) >= '0'::smallint AND get_partition_for_key(device_id, 32768) <= '16383'::smallint)
"time_range" CHECK ("time" >= '1257984000000000000'::bigint)
"time_range" CHECK ("timeCustom" >= '1257984000000000000'::bigint)
Server: Test1
FDW Options: (schema_name 'testNs', table_name '_hyper_1_1_0_2_data')
Inherits: "testNs"._hyper_1_1_0_partition
@ -360,7 +360,7 @@ Inherits: "testNs"._hyper_1_1_0_partition
Table "testNs._hyper_1_1_0_partition"
Column | Type | Modifiers | Storage | Stats target | Description
-------------+------------------+-----------+----------+--------------+-------------
time | bigint | not null | plain | |
timeCustom | bigint | not null | plain | |
device_id | text | not null | extended | |
series_0 | double precision | | plain | |
series_1 | double precision | | plain | |
@ -375,7 +375,7 @@ Child tables: "testNs"._hyper_1_1_0_1_data,
Table "testNs._hyper_1_2_0_partition"
Column | Type | Modifiers | Storage | Stats target | Description
-------------+------------------+-----------+----------+--------------+-------------
time | bigint | not null | plain | |
timeCustom | bigint | not null | plain | |
device_id | text | not null | extended | |
series_0 | double precision | | plain | |
series_1 | double precision | | plain | |
@ -404,7 +404,7 @@ primary key, btree, for table "testNs._hyper_1_distinct"
Table "testNs._hyper_1_root"
Column | Type | Modifiers | Storage | Stats target | Description
-------------+------------------+-----------+----------+--------------+-------------
time | bigint | not null | plain | |
timeCustom | bigint | not null | plain | |
device_id | text | not null | extended | |
series_0 | double precision | | plain | |
series_1 | double precision | | plain | |
@ -414,7 +414,7 @@ Child tables: "testNs"._hyper_1_0_replica
SELECT *
FROM "testNs"._hyper_1_0_replica;
time | device_id | series_0 | series_1 | series_2 | series_bool
timeCustom | device_id | series_0 | series_1 | series_2 | series_bool
---------------------+-----------+----------+----------+----------+-------------
1257894000000000000 | dev1 | 1.5 | 1 | 2 | t
1257894000000000000 | dev1 | 1.5 | 2 | |

View File

@ -40,22 +40,22 @@ SELECT add_node('test2' :: NAME, 'localhost');
\c Test1
CREATE TABLE PUBLIC."testNs" (
time BIGINT NOT NULL,
"timeCustom" BIGINT NOT NULL,
device_id TEXT NOT NULL,
series_0 DOUBLE PRECISION NULL,
series_1 DOUBLE PRECISION NULL,
series_2 DOUBLE PRECISION NULL,
series_bool BOOLEAN NULL
);
CREATE INDEX ON PUBLIC."testNs" (device_id, time DESC NULLS LAST) WHERE device_id IS NOT NULL;
CREATE INDEX ON PUBLIC."testNs" (time DESC NULLS LAST, series_0) WHERE series_0 IS NOT NULL;
CREATE INDEX ON PUBLIC."testNs" (time DESC NULLS LAST, series_1) WHERE series_1 IS NOT NULL;
CREATE INDEX ON PUBLIC."testNs" (time DESC NULLS LAST, series_2) WHERE series_2 IS NOT NULL;
CREATE INDEX ON PUBLIC."testNs" (time DESC NULLS LAST, series_bool) WHERE series_bool IS NOT NULL;
SELECT * FROM add_hypertable('"public"."testNs"', 'time', 'device_id', hypertable_name=>'testNs', associated_schema_name=>'testNs' );
CREATE INDEX ON PUBLIC."testNs" (device_id, "timeCustom" DESC NULLS LAST) WHERE device_id IS NOT NULL;
CREATE INDEX ON PUBLIC."testNs" ("timeCustom" DESC NULLS LAST, series_0) WHERE series_0 IS NOT NULL;
CREATE INDEX ON PUBLIC."testNs" ("timeCustom" DESC NULLS LAST, series_1) WHERE series_1 IS NOT NULL;
CREATE INDEX ON PUBLIC."testNs" ("timeCustom" DESC NULLS LAST, series_2) WHERE series_2 IS NOT NULL;
CREATE INDEX ON PUBLIC."testNs" ("timeCustom" DESC NULLS LAST, series_bool) WHERE series_bool IS NOT NULL;
SELECT * FROM add_hypertable('"public"."testNs"', 'timeCustom', 'device_id', hypertable_name=>'testNs', associated_schema_name=>'testNs' );
name | main_schema_name | main_table_name | associated_schema_name | associated_table_prefix | root_schema_name | root_table_name | distinct_schema_name | distinct_table_name | replication_factor | placement | time_field_name | time_field_type | created_on
--------+------------------+-----------------+------------------------+-------------------------+------------------+-----------------+----------------------+---------------------+--------------------+-----------+-----------------+-----------------+------------
testNs | public | testNs | testNs | _hyper_1 | testNs | _hyper_1_root | testNs | _hyper_1_distinct | 1 | STICKY | time | bigint | Test1
testNs | public | testNs | testNs | _hyper_1 | testNs | _hyper_1_root | testNs | _hyper_1_distinct | 1 | STICKY | timeCustom | bigint | Test1
(1 row)
SELECT set_is_distinct_flag('"public"."testNs"', 'device_id', TRUE);
@ -78,87 +78,87 @@ INNER JOIN chunk c ON (c.partition_id = part.id);
\c Test1
BEGIN;
INSERT INTO "testNs"(time, device_id, series_0, series_1) VALUES
INSERT INTO "testNs"("timeCustom", device_id, series_0, series_1) VALUES
(1257987600000000000, 'dev1', 1.5, 1),
(1257987600000000000, 'dev1', 1.5, 2),
(1257894002000000000, 'dev1', 2.5, 3);
COMMIT;
\c test2
BEGIN;
INSERT INTO "testNs"(time, device_id, series_0, series_1) VALUES
INSERT INTO "testNs"("timeCustom", device_id, series_0, series_1) VALUES
(1257894000000000000, 'dev2', 1.5, 1),
(1257894000000000000, 'dev2', 1.5, 2);
COMMIT;
\c Test1
\d+ "testNs".*
Index "testNs.1-testNs_device_id_time_idx"
Column | Type | Definition | Storage
-----------+--------+------------+----------
device_id | text | device_id | extended
time | bigint | "time" | plain
Index "testNs.1-testNs_device_id_timeCustom_idx"
Column | Type | Definition | Storage
------------+--------+--------------+----------
device_id | text | device_id | extended
timeCustom | bigint | "timeCustom" | plain
btree, for table "testNs._hyper_1_1_0_1_data", predicate (device_id IS NOT NULL)
Index "testNs.10-testNs_time_series_bool_idx"
Column | Type | Definition | Storage
-------------+---------+-------------+---------
time | bigint | "time" | plain
series_bool | boolean | series_bool | plain
Index "testNs.10-testNs_timeCustom_series_bool_idx"
Column | Type | Definition | Storage
-------------+---------+--------------+---------
timeCustom | bigint | "timeCustom" | plain
series_bool | boolean | series_bool | plain
btree, for table "testNs._hyper_1_1_0_2_data", predicate (series_bool IS NOT NULL)
Index "testNs.2-testNs_time_series_0_idx"
Column | Type | Definition | Storage
----------+------------------+------------+---------
time | bigint | "time" | plain
series_0 | double precision | series_0 | plain
Index "testNs.2-testNs_timeCustom_series_0_idx"
Column | Type | Definition | Storage
------------+------------------+--------------+---------
timeCustom | bigint | "timeCustom" | plain
series_0 | double precision | series_0 | plain
btree, for table "testNs._hyper_1_1_0_1_data", predicate (series_0 IS NOT NULL)
Index "testNs.3-testNs_time_series_1_idx"
Column | Type | Definition | Storage
----------+------------------+------------+---------
time | bigint | "time" | plain
series_1 | double precision | series_1 | plain
Index "testNs.3-testNs_timeCustom_series_1_idx"
Column | Type | Definition | Storage
------------+------------------+--------------+---------
timeCustom | bigint | "timeCustom" | plain
series_1 | double precision | series_1 | plain
btree, for table "testNs._hyper_1_1_0_1_data", predicate (series_1 IS NOT NULL)
Index "testNs.4-testNs_time_series_2_idx"
Column | Type | Definition | Storage
----------+------------------+------------+---------
time | bigint | "time" | plain
series_2 | double precision | series_2 | plain
Index "testNs.4-testNs_timeCustom_series_2_idx"
Column | Type | Definition | Storage
------------+------------------+--------------+---------
timeCustom | bigint | "timeCustom" | plain
series_2 | double precision | series_2 | plain
btree, for table "testNs._hyper_1_1_0_1_data", predicate (series_2 IS NOT NULL)
Index "testNs.5-testNs_time_series_bool_idx"
Column | Type | Definition | Storage
-------------+---------+-------------+---------
time | bigint | "time" | plain
series_bool | boolean | series_bool | plain
Index "testNs.5-testNs_timeCustom_series_bool_idx"
Column | Type | Definition | Storage
-------------+---------+--------------+---------
timeCustom | bigint | "timeCustom" | plain
series_bool | boolean | series_bool | plain
btree, for table "testNs._hyper_1_1_0_1_data", predicate (series_bool IS NOT NULL)
Index "testNs.6-testNs_device_id_time_idx"
Column | Type | Definition | Storage
-----------+--------+------------+----------
device_id | text | device_id | extended
time | bigint | "time" | plain
Index "testNs.6-testNs_device_id_timeCustom_idx"
Column | Type | Definition | Storage
------------+--------+--------------+----------
device_id | text | device_id | extended
timeCustom | bigint | "timeCustom" | plain
btree, for table "testNs._hyper_1_1_0_2_data", predicate (device_id IS NOT NULL)
Index "testNs.7-testNs_time_series_0_idx"
Column | Type | Definition | Storage
----------+------------------+------------+---------
time | bigint | "time" | plain
series_0 | double precision | series_0 | plain
Index "testNs.7-testNs_timeCustom_series_0_idx"
Column | Type | Definition | Storage
------------+------------------+--------------+---------
timeCustom | bigint | "timeCustom" | plain
series_0 | double precision | series_0 | plain
btree, for table "testNs._hyper_1_1_0_2_data", predicate (series_0 IS NOT NULL)
Index "testNs.8-testNs_time_series_1_idx"
Column | Type | Definition | Storage
----------+------------------+------------+---------
time | bigint | "time" | plain
series_1 | double precision | series_1 | plain
Index "testNs.8-testNs_timeCustom_series_1_idx"
Column | Type | Definition | Storage
------------+------------------+--------------+---------
timeCustom | bigint | "timeCustom" | plain
series_1 | double precision | series_1 | plain
btree, for table "testNs._hyper_1_1_0_2_data", predicate (series_1 IS NOT NULL)
Index "testNs.9-testNs_time_series_2_idx"
Column | Type | Definition | Storage
----------+------------------+------------+---------
time | bigint | "time" | plain
series_2 | double precision | series_2 | plain
Index "testNs.9-testNs_timeCustom_series_2_idx"
Column | Type | Definition | Storage
------------+------------------+--------------+---------
timeCustom | bigint | "timeCustom" | plain
series_2 | double precision | series_2 | plain
btree, for table "testNs._hyper_1_1_0_2_data", predicate (series_2 IS NOT NULL)
Table "testNs._hyper_1_0_1_distinct_data"
@ -188,7 +188,7 @@ Child tables: "testNs"._hyper_1_0_1_distinct_data
Table "testNs._hyper_1_0_replica"
Column | Type | Modifiers | Storage | Stats target | Description
-------------+------------------+-----------+----------+--------------+-------------
time | bigint | not null | plain | |
timeCustom | bigint | not null | plain | |
device_id | text | not null | extended | |
series_0 | double precision | | plain | |
series_1 | double precision | | plain | |
@ -201,47 +201,47 @@ Child tables: "testNs"._hyper_1_1_0_partition,
Table "testNs._hyper_1_1_0_1_data"
Column | Type | Modifiers | Storage | Stats target | Description
-------------+------------------+-----------+----------+--------------+-------------
time | bigint | not null | plain | |
timeCustom | bigint | not null | plain | |
device_id | text | not null | extended | |
series_0 | double precision | | plain | |
series_1 | double precision | | plain | |
series_2 | double precision | | plain | |
series_bool | boolean | | plain | |
Indexes:
"1-testNs_device_id_time_idx" btree (device_id, "time" DESC NULLS LAST) WHERE device_id IS NOT NULL
"2-testNs_time_series_0_idx" btree ("time" DESC NULLS LAST, series_0) WHERE series_0 IS NOT NULL
"3-testNs_time_series_1_idx" btree ("time" DESC NULLS LAST, series_1) WHERE series_1 IS NOT NULL
"4-testNs_time_series_2_idx" btree ("time" DESC NULLS LAST, series_2) WHERE series_2 IS NOT NULL
"5-testNs_time_series_bool_idx" btree ("time" DESC NULLS LAST, series_bool) WHERE series_bool IS NOT NULL
"1-testNs_device_id_timeCustom_idx" btree (device_id, "timeCustom" DESC NULLS LAST) WHERE device_id IS NOT NULL
"2-testNs_timeCustom_series_0_idx" btree ("timeCustom" DESC NULLS LAST, series_0) WHERE series_0 IS NOT NULL
"3-testNs_timeCustom_series_1_idx" btree ("timeCustom" DESC NULLS LAST, series_1) WHERE series_1 IS NOT NULL
"4-testNs_timeCustom_series_2_idx" btree ("timeCustom" DESC NULLS LAST, series_2) WHERE series_2 IS NOT NULL
"5-testNs_timeCustom_series_bool_idx" btree ("timeCustom" DESC NULLS LAST, series_bool) WHERE series_bool IS NOT NULL
Check constraints:
"partition" CHECK (get_partition_for_key(device_id, 32768) >= '0'::smallint AND get_partition_for_key(device_id, 32768) <= '16383'::smallint)
"time_range" CHECK ("time" <= '1257983999999999999'::bigint)
"time_range" CHECK ("timeCustom" <= '1257983999999999999'::bigint)
Inherits: "testNs"._hyper_1_1_0_partition
Table "testNs._hyper_1_1_0_2_data"
Column | Type | Modifiers | Storage | Stats target | Description
-------------+------------------+-----------+----------+--------------+-------------
time | bigint | not null | plain | |
timeCustom | bigint | not null | plain | |
device_id | text | not null | extended | |
series_0 | double precision | | plain | |
series_1 | double precision | | plain | |
series_2 | double precision | | plain | |
series_bool | boolean | | plain | |
Indexes:
"10-testNs_time_series_bool_idx" btree ("time" DESC NULLS LAST, series_bool) WHERE series_bool IS NOT NULL
"6-testNs_device_id_time_idx" btree (device_id, "time" DESC NULLS LAST) WHERE device_id IS NOT NULL
"7-testNs_time_series_0_idx" btree ("time" DESC NULLS LAST, series_0) WHERE series_0 IS NOT NULL
"8-testNs_time_series_1_idx" btree ("time" DESC NULLS LAST, series_1) WHERE series_1 IS NOT NULL
"9-testNs_time_series_2_idx" btree ("time" DESC NULLS LAST, series_2) WHERE series_2 IS NOT NULL
"10-testNs_timeCustom_series_bool_idx" btree ("timeCustom" DESC NULLS LAST, series_bool) WHERE series_bool IS NOT NULL
"6-testNs_device_id_timeCustom_idx" btree (device_id, "timeCustom" DESC NULLS LAST) WHERE device_id IS NOT NULL
"7-testNs_timeCustom_series_0_idx" btree ("timeCustom" DESC NULLS LAST, series_0) WHERE series_0 IS NOT NULL
"8-testNs_timeCustom_series_1_idx" btree ("timeCustom" DESC NULLS LAST, series_1) WHERE series_1 IS NOT NULL
"9-testNs_timeCustom_series_2_idx" btree ("timeCustom" DESC NULLS LAST, series_2) WHERE series_2 IS NOT NULL
Check constraints:
"partition" CHECK (get_partition_for_key(device_id, 32768) >= '0'::smallint AND get_partition_for_key(device_id, 32768) <= '16383'::smallint)
"time_range" CHECK ("time" >= '1257984000000000000'::bigint)
"time_range" CHECK ("timeCustom" >= '1257984000000000000'::bigint)
Inherits: "testNs"._hyper_1_1_0_partition
Table "testNs._hyper_1_1_0_partition"
Column | Type | Modifiers | Storage | Stats target | Description
-------------+------------------+-----------+----------+--------------+-------------
time | bigint | not null | plain | |
timeCustom | bigint | not null | plain | |
device_id | text | not null | extended | |
series_0 | double precision | | plain | |
series_1 | double precision | | plain | |
@ -256,7 +256,7 @@ Child tables: "testNs"._hyper_1_1_0_1_data,
Table "testNs._hyper_1_2_0_partition"
Column | Type | Modifiers | Storage | Stats target | Description
-------------+------------------+-----------+----------+--------------+-------------
time | bigint | not null | plain | |
timeCustom | bigint | not null | plain | |
device_id | text | not null | extended | |
series_0 | double precision | | plain | |
series_1 | double precision | | plain | |
@ -285,7 +285,7 @@ primary key, btree, for table "testNs._hyper_1_distinct"
Table "testNs._hyper_1_root"
Column | Type | Modifiers | Storage | Stats target | Description
-------------+------------------+-----------+----------+--------------+-------------
time | bigint | not null | plain | |
timeCustom | bigint | not null | plain | |
device_id | text | not null | extended | |
series_0 | double precision | | plain | |
series_1 | double precision | | plain | |
@ -315,7 +315,7 @@ Child tables: "testNs"._hyper_1_0_1_distinct_data
Table "testNs._hyper_1_0_replica"
Column | Type | Modifiers | Storage | Stats target | Description
-------------+------------------+-----------+----------+--------------+-------------
time | bigint | not null | plain | |
timeCustom | bigint | not null | plain | |
device_id | text | not null | extended | |
series_0 | double precision | | plain | |
series_1 | double precision | | plain | |
@ -328,7 +328,7 @@ Child tables: "testNs"._hyper_1_1_0_partition,
Foreign table "testNs._hyper_1_1_0_1_data"
Column | Type | Modifiers | FDW Options | Storage | Stats target | Description
-------------+------------------+-----------+-------------+----------+--------------+-------------
time | bigint | not null | | plain | |
timeCustom | bigint | not null | | plain | |
device_id | text | not null | | extended | |
series_0 | double precision | | | plain | |
series_1 | double precision | | | plain | |
@ -336,7 +336,7 @@ Child tables: "testNs"._hyper_1_1_0_partition,
series_bool | boolean | | | plain | |
Check constraints:
"partition" CHECK (get_partition_for_key(device_id, 32768) >= '0'::smallint AND get_partition_for_key(device_id, 32768) <= '16383'::smallint)
"time_range" CHECK ("time" <= '1257983999999999999'::bigint)
"time_range" CHECK ("timeCustom" <= '1257983999999999999'::bigint)
Server: Test1
FDW Options: (schema_name 'testNs', table_name '_hyper_1_1_0_1_data')
Inherits: "testNs"._hyper_1_1_0_partition
@ -344,7 +344,7 @@ Inherits: "testNs"._hyper_1_1_0_partition
Foreign table "testNs._hyper_1_1_0_2_data"
Column | Type | Modifiers | FDW Options | Storage | Stats target | Description
-------------+------------------+-----------+-------------+----------+--------------+-------------
time | bigint | not null | | plain | |
timeCustom | bigint | not null | | plain | |
device_id | text | not null | | extended | |
series_0 | double precision | | | plain | |
series_1 | double precision | | | plain | |
@ -352,7 +352,7 @@ Inherits: "testNs"._hyper_1_1_0_partition
series_bool | boolean | | | plain | |
Check constraints:
"partition" CHECK (get_partition_for_key(device_id, 32768) >= '0'::smallint AND get_partition_for_key(device_id, 32768) <= '16383'::smallint)
"time_range" CHECK ("time" >= '1257984000000000000'::bigint)
"time_range" CHECK ("timeCustom" >= '1257984000000000000'::bigint)
Server: Test1
FDW Options: (schema_name 'testNs', table_name '_hyper_1_1_0_2_data')
Inherits: "testNs"._hyper_1_1_0_partition
@ -360,7 +360,7 @@ Inherits: "testNs"._hyper_1_1_0_partition
Table "testNs._hyper_1_1_0_partition"
Column | Type | Modifiers | Storage | Stats target | Description
-------------+------------------+-----------+----------+--------------+-------------
time | bigint | not null | plain | |
timeCustom | bigint | not null | plain | |
device_id | text | not null | extended | |
series_0 | double precision | | plain | |
series_1 | double precision | | plain | |
@ -375,7 +375,7 @@ Child tables: "testNs"._hyper_1_1_0_1_data,
Table "testNs._hyper_1_2_0_partition"
Column | Type | Modifiers | Storage | Stats target | Description
-------------+------------------+-----------+----------+--------------+-------------
time | bigint | not null | plain | |
timeCustom | bigint | not null | plain | |
device_id | text | not null | extended | |
series_0 | double precision | | plain | |
series_1 | double precision | | plain | |
@ -404,7 +404,7 @@ primary key, btree, for table "testNs._hyper_1_distinct"
Table "testNs._hyper_1_root"
Column | Type | Modifiers | Storage | Stats target | Description
-------------+------------------+-----------+----------+--------------+-------------
time | bigint | not null | plain | |
timeCustom | bigint | not null | plain | |
device_id | text | not null | extended | |
series_0 | double precision | | plain | |
series_1 | double precision | | plain | |
@ -414,7 +414,7 @@ Child tables: "testNs"._hyper_1_0_replica
SELECT *
FROM "testNs"._hyper_1_0_replica;
time | device_id | series_0 | series_1 | series_2 | series_bool
timeCustom | device_id | series_0 | series_1 | series_2 | series_bool
---------------------+-----------+----------+----------+----------+-------------
1257894000000000000 | dev1 | 1.5 | 1 | 2 | t
1257894000000000000 | dev1 | 1.5 | 2 | |
@ -439,18 +439,18 @@ FROM "testNs"._hyper_1_0_distinct;
\c Test1
SELECT *
FROM ioql_exec_query(new_ioql_query(namespace_name => 'testNs'));
json
-----------------------------------------------------------------------------------------------------------------
{"time":1257987600000000000,"device_id":"dev1","series_0":1.5,"series_1":1,"series_2":null,"series_bool":null}
{"time":1257987600000000000,"device_id":"dev1","series_0":1.5,"series_1":2,"series_2":null,"series_bool":null}
{"time":1257897600000000000,"device_id":"dev1","series_0":4.5,"series_1":5,"series_2":null,"series_bool":false}
{"time":1257894002000000000,"device_id":"dev1","series_0":2.5,"series_1":3,"series_2":null,"series_bool":null}
{"time":1257894001000000000,"device_id":"dev1","series_0":3.5,"series_1":4,"series_2":null,"series_bool":null}
{"time":1257894000000001000,"device_id":"dev1","series_0":2.5,"series_1":3,"series_2":null,"series_bool":null}
{"time":1257894000000000000,"device_id":"dev2","series_0":1.5,"series_1":2,"series_2":null,"series_bool":null}
{"time":1257894000000000000,"device_id":"dev1","series_0":1.5,"series_1":2,"series_2":null,"series_bool":null}
{"time":1257894000000000000,"device_id":"dev2","series_0":1.5,"series_1":1,"series_2":null,"series_bool":null}
{"time":1257894000000000000,"device_id":"dev1","series_0":1.5,"series_1":1,"series_2":2,"series_bool":true}
json
-----------------------------------------------------------------------------------------------------------------------
{"timeCustom":1257987600000000000,"device_id":"dev1","series_0":1.5,"series_1":1,"series_2":null,"series_bool":null}
{"timeCustom":1257987600000000000,"device_id":"dev1","series_0":1.5,"series_1":2,"series_2":null,"series_bool":null}
{"timeCustom":1257897600000000000,"device_id":"dev1","series_0":4.5,"series_1":5,"series_2":null,"series_bool":false}
{"timeCustom":1257894002000000000,"device_id":"dev1","series_0":2.5,"series_1":3,"series_2":null,"series_bool":null}
{"timeCustom":1257894001000000000,"device_id":"dev1","series_0":3.5,"series_1":4,"series_2":null,"series_bool":null}
{"timeCustom":1257894000000001000,"device_id":"dev1","series_0":2.5,"series_1":3,"series_2":null,"series_bool":null}
{"timeCustom":1257894000000000000,"device_id":"dev2","series_0":1.5,"series_1":2,"series_2":null,"series_bool":null}
{"timeCustom":1257894000000000000,"device_id":"dev1","series_0":1.5,"series_1":2,"series_2":null,"series_bool":null}
{"timeCustom":1257894000000000000,"device_id":"dev2","series_0":1.5,"series_1":1,"series_2":null,"series_bool":null}
{"timeCustom":1257894000000000000,"device_id":"dev1","series_0":1.5,"series_1":1,"series_2":2,"series_bool":true}
(10 rows)
\set ON_ERROR_STOP 0
@ -523,10 +523,10 @@ FROM ioql_exec_query(new_ioql_query(namespace_name => 'testNs',
select_items => ARRAY [new_select_item('series_0')],
limit_by_field => new_limit_by_field('device_id', 1)
));
json
----------------------------------------------------------------
{"time":1257987600000000000,"series_0":1.5,"device_id":"dev1"}
{"time":1257894000000000000,"series_0":1.5,"device_id":"dev2"}
json
----------------------------------------------------------------------
{"timeCustom":1257987600000000000,"series_0":1.5,"device_id":"dev1"}
{"timeCustom":1257894000000000000,"series_0":1.5,"device_id":"dev2"}
(2 rows)
SELECT *
@ -534,8 +534,8 @@ FROM ioql_exec_query(new_ioql_query(namespace_name => 'testNs',
select_items => ARRAY [new_select_item('series_0')],
limit_rows => 1
));
json
---------------------------------------------
{"time":1257987600000000000,"series_0":1.5}
json
---------------------------------------------------
{"timeCustom":1257987600000000000,"series_0":1.5}
(1 row)

View File

@ -0,0 +1,142 @@
setup_meta
------------
(1 row)
setup_main
------------
(1 row)
setup_main
------------
(1 row)
\c meta
SELECT add_cluster_user('postgres', NULL);
add_cluster_user
------------------
(1 row)
SELECT set_meta('meta' :: NAME, 'localhost');
set_meta
----------
(1 row)
SELECT add_node('Test1' :: NAME, 'localhost');
add_node
----------
(1 row)
SELECT add_node('test2' :: NAME, 'localhost');
add_node
----------
(1 row)
\c Test1
CREATE TABLE PUBLIC."testNs" (
"timeCustom" TIMESTAMP NOT NULL,
device_id TEXT NOT NULL,
series_0 DOUBLE PRECISION NULL,
series_1 DOUBLE PRECISION NULL,
series_2 DOUBLE PRECISION NULL,
series_bool BOOLEAN NULL
);
CREATE INDEX ON PUBLIC."testNs" (device_id, "timeCustom" DESC NULLS LAST) WHERE device_id IS NOT NULL;
SELECT * FROM add_hypertable('"public"."testNs"', 'timeCustom', 'device_id', hypertable_name=>'testNs', associated_schema_name=>'testNs' );
name | main_schema_name | main_table_name | associated_schema_name | associated_table_prefix | root_schema_name | root_table_name | distinct_schema_name | distinct_table_name | replication_factor | placement | time_field_name | time_field_type | created_on
--------+------------------+-----------------+------------------------+-------------------------+------------------+-----------------+----------------------+---------------------+--------------------+-----------+-----------------+-----------------------------+------------
testNs | public | testNs | testNs | _hyper_1 | testNs | _hyper_1_root | testNs | _hyper_1_distinct | 1 | STICKY | timeCustom | timestamp without time zone | Test1
(1 row)
SELECT set_is_distinct_flag('"public"."testNs"', 'device_id', TRUE);
set_is_distinct_flag
----------------------
(1 row)
\c Test1
INSERT INTO "testNs"("timeCustom", device_id, series_0, series_1) VALUES
('2009-11-12T01:00:00+00:00', 'dev1', 1.5, 1),
('2009-11-12T01:00:00+00:00', 'dev1', 1.5, 2),
('2009-11-10T23:00:02+00:00', 'dev1', 2.5, 3);
SELECT close_chunk_end(c.id)
FROM get_open_partition_for_key('testNs', 'dev1') part
INNER JOIN chunk c ON (c.partition_id = part.id);
close_chunk_end
-----------------
(1 row)
INSERT INTO "testNs"("timeCustom", device_id, series_0, series_1) VALUES
('2009-11-10T23:00:00+00:00', 'dev2', 1.5, 1),
('2009-11-10T23:00:00+00:00', 'dev2', 1.5, 2);
SELECT * FROM PUBLIC."testNs";
timeCustom | device_id | series_0 | series_1 | series_2 | series_bool
---------------------+-----------+----------+----------+----------+-------------
2009-11-12 01:00:00 | dev1 | 1.5 | 1 | |
2009-11-12 01:00:00 | dev1 | 1.5 | 2 | |
2009-11-10 23:00:02 | dev1 | 2.5 | 3 | |
2009-11-10 23:00:00 | dev2 | 1.5 | 1 | |
2009-11-10 23:00:00 | dev2 | 1.5 | 2 | |
(5 rows)
SELECT *
FROM ioql_exec_query(new_ioql_query(namespace_name => 'testNs'));
json
------------------------------------------------------------------------------------------------------------------------
{"timeCustom":"2009-11-12T01:00:00","device_id":"dev1","series_0":1.5,"series_1":1,"series_2":null,"series_bool":null}
{"timeCustom":"2009-11-12T01:00:00","device_id":"dev1","series_0":1.5,"series_1":2,"series_2":null,"series_bool":null}
{"timeCustom":"2009-11-10T23:00:02","device_id":"dev1","series_0":2.5,"series_1":3,"series_2":null,"series_bool":null}
{"timeCustom":"2009-11-10T23:00:00","device_id":"dev2","series_0":1.5,"series_1":1,"series_2":null,"series_bool":null}
{"timeCustom":"2009-11-10T23:00:00","device_id":"dev2","series_0":1.5,"series_1":2,"series_2":null,"series_bool":null}
(5 rows)
SELECT *
FROM ioql_exec_query(new_ioql_query(namespace_name => 'testNs',
select_items => ARRAY [new_select_item('series_0', 'SUM')],
aggregate => new_aggregate((100 * 60 * 60 * 1e6) :: BIGINT)
));
json
----------------------------------------------------
{"time":"2009-11-10T08:00:00","sum(series_0)":8.5}
(1 row)
SELECT *
FROM ioql_exec_query(new_ioql_query(namespace_name => 'testNs',
select_items => ARRAY [new_select_item('series_0', 'SUM')],
aggregate => new_aggregate((1 * 60 * 60 * 1e6) :: BIGINT)
));
json
----------------------------------------------------
{"time":"2009-11-10T23:00:00","sum(series_0)":5.5}
{"time":"2009-11-12T01:00:00","sum(series_0)":3}
(2 rows)
SELECT *
FROM ioql_exec_query(new_ioql_query(namespace_name => 'testNs',
time_condition=>new_time_condition(1257894000000000,1257987600000000) --microseconds
));
json
------------------------------------------------------------------------------------------------------------------------
{"timeCustom":"2009-11-10T23:00:02","device_id":"dev1","series_0":2.5,"series_1":3,"series_2":null,"series_bool":null}
{"timeCustom":"2009-11-10T23:00:00","device_id":"dev2","series_0":1.5,"series_1":1,"series_2":null,"series_bool":null}
{"timeCustom":"2009-11-10T23:00:00","device_id":"dev2","series_0":1.5,"series_1":2,"series_2":null,"series_bool":null}
(3 rows)
SELECT *
FROM ioql_exec_query(new_ioql_query(namespace_name => 'testNs',
select_items => ARRAY [new_select_item('series_0', 'SUM')],
aggregate => new_aggregate((1 * 60 * 60 * 1e6) :: BIGINT),
limit_time_periods => 2
));
json
--------------------------------------------------
{"time":"2009-11-12T01:00:00","sum(series_0)":3}
(1 row)

View File

@ -13,20 +13,20 @@ SELECT add_node('test2' :: NAME, 'localhost');
\c Test1
CREATE TABLE PUBLIC."testNs" (
time BIGINT NOT NULL,
"timeCustom" BIGINT NOT NULL,
device_id TEXT NOT NULL,
series_0 DOUBLE PRECISION NULL,
series_1 DOUBLE PRECISION NULL,
series_2 DOUBLE PRECISION NULL,
series_bool BOOLEAN NULL
);
CREATE INDEX ON PUBLIC."testNs" (device_id, time DESC NULLS LAST) WHERE device_id IS NOT NULL;
CREATE INDEX ON PUBLIC."testNs" (time DESC NULLS LAST, series_0) WHERE series_0 IS NOT NULL;
CREATE INDEX ON PUBLIC."testNs" (time DESC NULLS LAST, series_1) WHERE series_1 IS NOT NULL;
CREATE INDEX ON PUBLIC."testNs" (time DESC NULLS LAST, series_2) WHERE series_2 IS NOT NULL;
CREATE INDEX ON PUBLIC."testNs" (time DESC NULLS LAST, series_bool) WHERE series_bool IS NOT NULL;
CREATE INDEX ON PUBLIC."testNs" (device_id, "timeCustom" DESC NULLS LAST) WHERE device_id IS NOT NULL;
CREATE INDEX ON PUBLIC."testNs" ("timeCustom" DESC NULLS LAST, series_0) WHERE series_0 IS NOT NULL;
CREATE INDEX ON PUBLIC."testNs" ("timeCustom" DESC NULLS LAST, series_1) WHERE series_1 IS NOT NULL;
CREATE INDEX ON PUBLIC."testNs" ("timeCustom" DESC NULLS LAST, series_2) WHERE series_2 IS NOT NULL;
CREATE INDEX ON PUBLIC."testNs" ("timeCustom" DESC NULLS LAST, series_bool) WHERE series_bool IS NOT NULL;
SELECT * FROM add_hypertable('"public"."testNs"', 'time', 'device_id', hypertable_name=>'testNs', associated_schema_name=>'testNs' );
SELECT * FROM add_hypertable('"public"."testNs"', 'timeCustom', 'device_id', hypertable_name=>'testNs', associated_schema_name=>'testNs' );
SELECT set_is_distinct_flag('"public"."testNs"', 'device_id', TRUE);
@ -41,7 +41,7 @@ INNER JOIN chunk c ON (c.partition_id = part.id);
\c Test1
BEGIN;
INSERT INTO "testNs"(time, device_id, series_0, series_1) VALUES
INSERT INTO "testNs"("timeCustom", device_id, series_0, series_1) VALUES
(1257987600000000000, 'dev1', 1.5, 1),
(1257987600000000000, 'dev1', 1.5, 2),
(1257894002000000000, 'dev1', 2.5, 3);
@ -49,7 +49,7 @@ COMMIT;
\c test2
BEGIN;
INSERT INTO "testNs"(time, device_id, series_0, series_1) VALUES
INSERT INTO "testNs"("timeCustom", device_id, series_0, series_1) VALUES
(1257894000000000000, 'dev2', 1.5, 1),
(1257894000000000000, 'dev2', 1.5, 2);
COMMIT;

View File

@ -28,4 +28,5 @@ golden_test kafka.sql kafka.out
golden_test insert.sql insert.out
golden_test query.sql query.out
golden_test ddl.sql ddl.out
golden_test timestamp.sql timestamp.out
echo "Success"

View File

@ -0,0 +1,71 @@
\set ON_ERROR_STOP 1
\ir create_clustered_db.sql
\set ECHO ALL
\c meta
SELECT add_cluster_user('postgres', NULL);
SELECT set_meta('meta' :: NAME, 'localhost');
SELECT add_node('Test1' :: NAME, 'localhost');
SELECT add_node('test2' :: NAME, 'localhost');
\c Test1
CREATE TABLE PUBLIC."testNs" (
"timeCustom" TIMESTAMP NOT NULL,
device_id TEXT NOT NULL,
series_0 DOUBLE PRECISION NULL,
series_1 DOUBLE PRECISION NULL,
series_2 DOUBLE PRECISION NULL,
series_bool BOOLEAN NULL
);
CREATE INDEX ON PUBLIC."testNs" (device_id, "timeCustom" DESC NULLS LAST) WHERE device_id IS NOT NULL;
SELECT * FROM add_hypertable('"public"."testNs"', 'timeCustom', 'device_id', hypertable_name=>'testNs', associated_schema_name=>'testNs' );
SELECT set_is_distinct_flag('"public"."testNs"', 'device_id', TRUE);
\c Test1
INSERT INTO "testNs"("timeCustom", device_id, series_0, series_1) VALUES
('2009-11-12T01:00:00+00:00', 'dev1', 1.5, 1),
('2009-11-12T01:00:00+00:00', 'dev1', 1.5, 2),
('2009-11-10T23:00:02+00:00', 'dev1', 2.5, 3);
SELECT close_chunk_end(c.id)
FROM get_open_partition_for_key('testNs', 'dev1') part
INNER JOIN chunk c ON (c.partition_id = part.id);
INSERT INTO "testNs"("timeCustom", device_id, series_0, series_1) VALUES
('2009-11-10T23:00:00+00:00', 'dev2', 1.5, 1),
('2009-11-10T23:00:00+00:00', 'dev2', 1.5, 2);
SELECT * FROM PUBLIC."testNs";
SELECT *
FROM ioql_exec_query(new_ioql_query(namespace_name => 'testNs'));
SELECT *
FROM ioql_exec_query(new_ioql_query(namespace_name => 'testNs',
select_items => ARRAY [new_select_item('series_0', 'SUM')],
aggregate => new_aggregate((100 * 60 * 60 * 1e6) :: BIGINT)
));
SELECT *
FROM ioql_exec_query(new_ioql_query(namespace_name => 'testNs',
select_items => ARRAY [new_select_item('series_0', 'SUM')],
aggregate => new_aggregate((1 * 60 * 60 * 1e6) :: BIGINT)
));
SELECT *
FROM ioql_exec_query(new_ioql_query(namespace_name => 'testNs',
time_condition=>new_time_condition(1257894000000000,1257987600000000) --microseconds
));
SELECT *
FROM ioql_exec_query(new_ioql_query(namespace_name => 'testNs',
select_items => ARRAY [new_select_item('series_0', 'SUM')],
aggregate => new_aggregate((1 * 60 * 60 * 1e6) :: BIGINT),
limit_time_periods => 2
));