mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-16 02:23:49 +08:00
Avoid string conversion in hash partitioning
Hash partitioning previously relied on coercing (casting) values to strings before calculating a hash value, including creating CHECK constraints with casts. This approach is fairly suboptimal from a performance perspective and might have issues related to different character encodings depending on system. Hash partitioning now instead uses a partitioning function that takes an anyelement type that calls type-dependent hash functions internal to PostgreSQL. This should provide more efficient hashing both by avoiding unnecessary string conversions and by using more optimal type-specific hash functions. Support for the previous hash partitioning function is preserved for backwards compatibility. Hypertables created with the previous function will continue to use to old hashing strategy, while new tables will default to the updated hash partitioning. For safety, this change also blocks changing types on hash-partitioned columns, since it seems hard to guarantee the same hash result between different types.
This commit is contained in:
parent
2ba1a40a9f
commit
cf009cc584
@ -151,7 +151,7 @@ CREATE OR REPLACE FUNCTION _timescaledb_internal.add_dimension(
|
||||
RETURNS _timescaledb_catalog.dimension LANGUAGE PLPGSQL VOLATILE AS
|
||||
$BODY$
|
||||
DECLARE
|
||||
partitioning_func _timescaledb_catalog.dimension.partitioning_func%TYPE = 'get_partition_for_key';
|
||||
partitioning_func _timescaledb_catalog.dimension.partitioning_func%TYPE = 'get_partition_hash';
|
||||
partitioning_func_schema _timescaledb_catalog.dimension.partitioning_func_schema%TYPE = '_timescaledb_internal';
|
||||
aligned BOOL;
|
||||
column_type REGTYPE;
|
||||
|
@ -1,4 +1,8 @@
|
||||
-- our default partitioning function.
|
||||
-- returns a hash of val modulous the mod_factor
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_partition_for_key(val text) RETURNS int
|
||||
-- Deprecated partition hash function
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_partition_for_key(val text)
|
||||
RETURNS int
|
||||
AS '$libdir/timescaledb', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_partition_hash(val anyelement)
|
||||
RETURNS int
|
||||
AS '$libdir/timescaledb', 'get_partition_hash' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
@ -82,6 +82,8 @@ $BODY$
|
||||
DECLARE
|
||||
dimension_slice_row _timescaledb_catalog.dimension_slice;
|
||||
dimension_row _timescaledb_catalog.dimension;
|
||||
proargtype OID;
|
||||
typecast TEXT = '';
|
||||
BEGIN
|
||||
SELECT * INTO STRICT dimension_slice_row
|
||||
FROM _timescaledb_catalog.dimension_slice
|
||||
@ -92,12 +94,28 @@ BEGIN
|
||||
WHERE id = dimension_slice_row.dimension_id;
|
||||
|
||||
IF dimension_row.partitioning_func IS NOT NULL THEN
|
||||
SELECT proargtypes[0] INTO STRICT proargtype
|
||||
FROM pg_proc p, pg_namespace n
|
||||
WHERE n.nspname = dimension_row.partitioning_func_schema
|
||||
AND p.proname = dimension_row.partitioning_func
|
||||
AND n.oid = p.pronamespace;
|
||||
|
||||
-- Check if we are using a legacy partitioning function
|
||||
-- that only takes text input
|
||||
IF proargtype = 'text'::regtype THEN
|
||||
typecast := '::text';
|
||||
END IF;
|
||||
|
||||
return format(
|
||||
$$
|
||||
%1$I.%2$s(%3$I::text) >= %4$L AND %1$I.%2$s(%3$I::text) < %5$L
|
||||
%1$I.%2$s(%3$I%4$s) >= %5$L AND %1$I.%2$s(%3$I%4$s) < %6$L
|
||||
$$,
|
||||
dimension_row.partitioning_func_schema, dimension_row.partitioning_func,
|
||||
dimension_row.column_name, dimension_slice_row.range_start, dimension_slice_row.range_end);
|
||||
dimension_row.partitioning_func_schema,
|
||||
dimension_row.partitioning_func,
|
||||
dimension_row.column_name,
|
||||
typecast,
|
||||
dimension_slice_row.range_start,
|
||||
dimension_slice_row.range_end);
|
||||
ELSE
|
||||
--TODO: only works with time for now
|
||||
IF _timescaledb_internal.time_literal_sql(dimension_slice_row.range_start, dimension_row.column_type) =
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <postgres.h>
|
||||
#include <access/relscan.h>
|
||||
#include <utils/lsyscache.h>
|
||||
#include <utils/builtins.h>
|
||||
#include <funcapi.h>
|
||||
|
||||
#include "catalog.h"
|
||||
@ -37,6 +38,22 @@ hyperspace_get_dimension_by_id(Hyperspace *hs, int32 id)
|
||||
sizeof(Dimension), cmp_dimension_id);
|
||||
}
|
||||
|
||||
Dimension *
|
||||
hyperspace_get_dimension_by_name(Hyperspace *hs, DimensionType type, const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < hs->num_dimensions; i++)
|
||||
{
|
||||
Dimension *dim = &hs->dimensions[i];
|
||||
|
||||
if (dim->type == type && namestrcmp(&dim->fd.column_name, name) == 0)
|
||||
return dim;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Dimension *
|
||||
hyperspace_get_dimension(Hyperspace *hs, DimensionType type, Index n)
|
||||
{
|
||||
@ -95,8 +112,7 @@ dimension_fill_in_from_tuple(Dimension *d, TupleInfo *ti, Oid main_table_relid)
|
||||
DatumGetName(values[Anum_dimension_partitioning_func - 1]),
|
||||
NAMEDATALEN);
|
||||
|
||||
d->partitioning = partitioning_info_create(d->fd.num_slices,
|
||||
NameStr(d->fd.partitioning_func_schema),
|
||||
d->partitioning = partitioning_info_create(NameStr(d->fd.partitioning_func_schema),
|
||||
NameStr(d->fd.partitioning_func),
|
||||
NameStr(d->fd.column_name),
|
||||
main_table_relid);
|
||||
|
@ -67,6 +67,7 @@ extern DimensionSlice *dimension_calculate_default_slice(Dimension *dim, int64 v
|
||||
extern Point *hyperspace_calculate_point(Hyperspace *h, HeapTuple tuple, TupleDesc tupdesc);
|
||||
extern Dimension *hyperspace_get_dimension_by_id(Hyperspace *hs, int32 id);
|
||||
extern Dimension *hyperspace_get_dimension(Hyperspace *hs, DimensionType type, Index n);
|
||||
extern Dimension *hyperspace_get_dimension_by_name(Hyperspace *hs, DimensionType type, const char *name);
|
||||
|
||||
#define hyperspace_get_open_dimension(space, i) \
|
||||
hyperspace_get_dimension(space, DIMENSION_TYPE_OPEN, i)
|
||||
|
@ -1,83 +1,157 @@
|
||||
#include <postgres.h>
|
||||
#include <utils/builtins.h>
|
||||
#include <utils/lsyscache.h>
|
||||
#include <utils/numeric.h>
|
||||
#include <utils/timestamp.h>
|
||||
#include <utils/inet.h>
|
||||
#include <utils/cash.h>
|
||||
#include <utils/date.h>
|
||||
#include <utils/nabstime.h>
|
||||
#include <utils/jsonb.h>
|
||||
#include <utils/acl.h>
|
||||
#include <utils/rangetypes.h>
|
||||
#include <catalog/namespace.h>
|
||||
#include <catalog/pg_type.h>
|
||||
#include <access/hash.h>
|
||||
#include <access/htup_details.h>
|
||||
#include <parser/parse_coerce.h>
|
||||
#include <nodes/makefuncs.h>
|
||||
#include <nodes/pg_list.h>
|
||||
|
||||
#include "partitioning.h"
|
||||
#include "catalog.h"
|
||||
#include "utils.h"
|
||||
|
||||
/*
|
||||
* Resolve the partitioning function set for a hypertable.
|
||||
*/
|
||||
static void
|
||||
partitioning_func_set_func_fmgr(PartitioningFunc *pf)
|
||||
{
|
||||
FuncCandidateList funclist =
|
||||
FuncnameGetCandidates(list_make2(makeString(pf->schema), makeString(pf->name)),
|
||||
FuncnameGetCandidates(partitioning_func_qualified_name(pf),
|
||||
1, NULL, false, false, false);
|
||||
|
||||
if (funclist == NULL || funclist->next)
|
||||
elog(ERROR, "Could not resolve the partitioning function");
|
||||
|
||||
pf->paramtype = funclist->args[0];
|
||||
|
||||
if (!(funclist->nargs == 1 &&
|
||||
(pf->paramtype == TEXTOID || pf->paramtype == ANYELEMENTOID)))
|
||||
elog(ERROR, "Invalid partitioning function signature");
|
||||
|
||||
fmgr_info_cxt(funclist->oid, &pf->func_fmgr, CurrentMemoryContext);
|
||||
}
|
||||
|
||||
static void
|
||||
partitioning_info_set_textfunc_fmgr(PartitioningInfo *pi, Oid relid)
|
||||
List *
|
||||
partitioning_func_qualified_name(PartitioningFunc *pf)
|
||||
{
|
||||
Oid type_id,
|
||||
func_id;
|
||||
bool isVarlena;
|
||||
CoercionPathType cpt;
|
||||
return list_make2(makeString(pf->schema), makeString(pf->name));
|
||||
}
|
||||
|
||||
pi->column_attnum = get_attnum(relid, pi->column);
|
||||
type_id = get_atttype(relid, pi->column_attnum);
|
||||
static Oid
|
||||
find_text_coercion_func(Oid type)
|
||||
{
|
||||
Oid funcid;
|
||||
bool is_varlena;
|
||||
CoercionPathType cpt;
|
||||
|
||||
/*
|
||||
* First look for an explicit cast type. Needed since the output of for
|
||||
* example character(20) not the same as character(20)::text
|
||||
*/
|
||||
cpt = find_coercion_pathway(TEXTOID, type_id, COERCION_EXPLICIT, &func_id);
|
||||
cpt = find_coercion_pathway(TEXTOID, type, COERCION_EXPLICIT, &funcid);
|
||||
|
||||
if (cpt != COERCION_PATH_FUNC)
|
||||
{
|
||||
getTypeOutputInfo(type_id, &func_id, &isVarlena);
|
||||
}
|
||||
fmgr_info_cxt(func_id, &pi->partfunc.textfunc_fmgr, CurrentMemoryContext);
|
||||
getTypeOutputInfo(type, &funcid, &is_varlena);
|
||||
|
||||
return funcid;
|
||||
}
|
||||
|
||||
#define TYPECACHE_HASH_FLAGS (TYPECACHE_HASH_PROC | TYPECACHE_HASH_PROC_FINFO)
|
||||
|
||||
PartitioningInfo *
|
||||
partitioning_info_create(int num_partitions,
|
||||
const char *schema,
|
||||
partitioning_info_create(const char *schema,
|
||||
const char *partfunc,
|
||||
const char *partcol,
|
||||
Oid relid)
|
||||
{
|
||||
PartitioningInfo *pi;
|
||||
PartitioningInfo *pinfo;
|
||||
Oid columntype,
|
||||
varcollid,
|
||||
funccollid = InvalidOid;
|
||||
Var *var;
|
||||
FuncExpr *expr;
|
||||
|
||||
pi = palloc0(sizeof(PartitioningInfo));
|
||||
strncpy(pi->partfunc.name, partfunc, NAMEDATALEN);
|
||||
strncpy(pi->column, partcol, NAMEDATALEN);
|
||||
pinfo = palloc0(sizeof(PartitioningInfo));
|
||||
strncpy(pinfo->partfunc.name, partfunc, NAMEDATALEN);
|
||||
strncpy(pinfo->column, partcol, NAMEDATALEN);
|
||||
pinfo->column_attnum = get_attnum(relid, pinfo->column);
|
||||
|
||||
if (schema != NULL)
|
||||
strncpy(pi->partfunc.schema, schema, NAMEDATALEN);
|
||||
strncpy(pinfo->partfunc.schema, schema, NAMEDATALEN);
|
||||
|
||||
partitioning_func_set_func_fmgr(&pi->partfunc);
|
||||
partitioning_info_set_textfunc_fmgr(pi, relid);
|
||||
/* Lookup the type cache entry to access the hash function for the type */
|
||||
columntype = get_atttype(relid, pinfo->column_attnum);
|
||||
pinfo->typcache_entry = lookup_type_cache(columntype, TYPECACHE_HASH_FLAGS);
|
||||
|
||||
return pi;
|
||||
if (pinfo->typcache_entry->hash_proc == InvalidOid)
|
||||
elog(ERROR, "No hash function for type %u", columntype);
|
||||
|
||||
partitioning_func_set_func_fmgr(&pinfo->partfunc);
|
||||
|
||||
/*
|
||||
* Prepare a function expression for this function. The partition hash
|
||||
* function needs this to be able to resolve the type of the value to be
|
||||
* hashed.
|
||||
*/
|
||||
varcollid = get_typcollation(columntype);
|
||||
|
||||
var = makeVar(1,
|
||||
pinfo->column_attnum,
|
||||
columntype,
|
||||
-1,
|
||||
varcollid,
|
||||
0);
|
||||
|
||||
expr = makeFuncExpr(pinfo->partfunc.func_fmgr.fn_oid, INT4OID, list_make1(var),
|
||||
funccollid, varcollid, COERCE_EXPLICIT_CALL);
|
||||
|
||||
fmgr_info_set_expr((Node *) expr, &pinfo->partfunc.func_fmgr);
|
||||
|
||||
/*
|
||||
* Set the type cache entry in fn_extra to avoid an extry lookup in the
|
||||
* partition hash function
|
||||
*/
|
||||
pinfo->partfunc.func_fmgr.fn_extra = pinfo->typcache_entry;
|
||||
|
||||
return pinfo;
|
||||
}
|
||||
|
||||
/*
|
||||
* Apply the partitioning function of a hypertable to a value.
|
||||
*
|
||||
* We support both partitioning functions with the legacy signature int
|
||||
* func(text) and the new signature int func(anyelement).
|
||||
*/
|
||||
int32
|
||||
partitioning_func_apply(PartitioningInfo *pinfo, Datum value)
|
||||
{
|
||||
Datum text = FunctionCall1(&pinfo->partfunc.textfunc_fmgr, value);
|
||||
char *partition_val = DatumGetCString(text);
|
||||
Datum keyspace_datum = FunctionCall1(&pinfo->partfunc.func_fmgr,
|
||||
CStringGetTextDatum(partition_val));
|
||||
if (pinfo->partfunc.paramtype == TEXTOID)
|
||||
{
|
||||
/* Legacy function signature. We need to convert the datum to text. */
|
||||
Oid funcid = find_text_coercion_func(pinfo->typcache_entry->type_id);
|
||||
|
||||
return DatumGetInt32(keyspace_datum);
|
||||
if (!OidIsValid(funcid))
|
||||
elog(ERROR, "Could not coerce type %u to text",
|
||||
pinfo->typcache_entry->type_id);
|
||||
|
||||
value = OidFunctionCall1(funcid, value);
|
||||
value = CStringGetTextDatum(DatumGetCString(value));
|
||||
}
|
||||
|
||||
return DatumGetInt32(FunctionCall1(&pinfo->partfunc.func_fmgr, value));
|
||||
}
|
||||
|
||||
int32
|
||||
@ -99,15 +173,18 @@ PGDLLEXPORT Datum get_partition_for_key(PG_FUNCTION_ARGS);
|
||||
|
||||
PG_FUNCTION_INFO_V1(get_partition_for_key);
|
||||
|
||||
/*
|
||||
* Deprecated function to calculate partition hash values.
|
||||
*
|
||||
* This function assumes text input only.
|
||||
*/
|
||||
Datum
|
||||
get_partition_for_key(PG_FUNCTION_ARGS)
|
||||
{
|
||||
struct varlena *data;
|
||||
struct varlena *data = PG_GETARG_VARLENA_PP(0);
|
||||
uint32 hash_u;
|
||||
int32 res;
|
||||
|
||||
data = PG_GETARG_VARLENA_PP(0);
|
||||
|
||||
hash_u = DatumGetUInt32(hash_any((unsigned char *) VARDATA_ANY(data),
|
||||
VARSIZE_ANY_EXHDR(data)));
|
||||
|
||||
@ -116,3 +193,85 @@ get_partition_for_key(PG_FUNCTION_ARGS)
|
||||
PG_FREE_IF_COPY(data, 0);
|
||||
PG_RETURN_INT32(res);
|
||||
}
|
||||
|
||||
/*
|
||||
* Resolve the type of the argument passed to a function.
|
||||
*
|
||||
* The type is resolved from the function expression in the function call info.
|
||||
*/
|
||||
static Oid
|
||||
resolve_function_argtype(FunctionCallInfo fcinfo)
|
||||
{
|
||||
FuncExpr *fe;
|
||||
Node *node;
|
||||
Oid argtype;
|
||||
|
||||
/* Get the function expression from the call info */
|
||||
fe = (FuncExpr *) fcinfo->flinfo->fn_expr;
|
||||
|
||||
if (NULL == fe || !IsA(fe, FuncExpr))
|
||||
elog(ERROR, "No function expression set when invoking partitioning function");
|
||||
|
||||
if (list_length(fe->args) != 1)
|
||||
elog(ERROR, "Unexpected number of arguments in function expression");
|
||||
|
||||
node = linitial(fe->args);
|
||||
|
||||
switch (nodeTag(node))
|
||||
{
|
||||
case T_Var:
|
||||
argtype = ((Var *) node)->vartype;
|
||||
break;
|
||||
case T_Const:
|
||||
argtype = ((Const *) node)->consttype;
|
||||
break;
|
||||
case T_CoerceViaIO:
|
||||
argtype = ((CoerceViaIO *) node)->resulttype;
|
||||
break;
|
||||
default:
|
||||
elog(ERROR, "Unsupported expression argument node type %u", nodeTag(node));
|
||||
}
|
||||
|
||||
return argtype;
|
||||
}
|
||||
|
||||
PGDLLEXPORT Datum get_partition_hash(PG_FUNCTION_ARGS);
|
||||
|
||||
PG_FUNCTION_INFO_V1(get_partition_hash);
|
||||
|
||||
/*
|
||||
* Compute a partition hash value for any input type.
|
||||
*
|
||||
* get_partition_hash() takes a single argument of anyelement type. We compute
|
||||
* the hash based on the argument type information that we expect to find in the
|
||||
* function expression in the function call context. If no such expression
|
||||
* exists, or the type cannot be resolved from the expression, the function
|
||||
* throws an error.
|
||||
*/
|
||||
Datum
|
||||
get_partition_hash(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Datum arg = PG_GETARG_DATUM(0);
|
||||
TypeCacheEntry *tce = fcinfo->flinfo->fn_extra;
|
||||
Oid argtype;
|
||||
Datum hash;
|
||||
int32 res;
|
||||
|
||||
if (PG_NARGS() != 1)
|
||||
elog(ERROR, "Unexpected number of arguments to partitioning function");
|
||||
|
||||
argtype = resolve_function_argtype(fcinfo);
|
||||
|
||||
if (tce == NULL)
|
||||
tce = lookup_type_cache(argtype, TYPECACHE_HASH_FLAGS);
|
||||
|
||||
if (tce->hash_proc == InvalidOid)
|
||||
elog(ERROR, "No hash function for type %u", argtype);
|
||||
|
||||
hash = FunctionCall1(&tce->hash_proc_finfo, arg);
|
||||
|
||||
/* Only positive numbers */
|
||||
res = (int32) (DatumGetUInt32(hash) & 0x7fffffff);
|
||||
|
||||
PG_RETURN_INT32(res);
|
||||
}
|
||||
|
@ -5,7 +5,8 @@
|
||||
|
||||
#include <postgres.h>
|
||||
#include <access/attnum.h>
|
||||
#include <access/htup.h>
|
||||
#include <access/htup_details.h>
|
||||
#include <utils/typcache.h>
|
||||
#include <fmgr.h>
|
||||
|
||||
#define OPEN_START_TIME -1
|
||||
@ -16,17 +17,17 @@ typedef struct PartitioningFunc
|
||||
char schema[NAMEDATALEN];
|
||||
char name[NAMEDATALEN];
|
||||
|
||||
/*
|
||||
* Function manager info to call the function to convert a row's
|
||||
* partitioning column value to a text string
|
||||
*/
|
||||
FmgrInfo textfunc_fmgr;
|
||||
|
||||
/*
|
||||
* Function manager info to call the partitioning function on the
|
||||
* partitioning column's text representation
|
||||
* partitioning column's text representation.
|
||||
*/
|
||||
FmgrInfo func_fmgr;
|
||||
|
||||
/*
|
||||
* The type of the parameter that the partitioning function accepts. This
|
||||
* can be either TEXTOID or ANYELEMENTOID.
|
||||
*/
|
||||
Oid paramtype;
|
||||
} PartitioningFunc;
|
||||
|
||||
|
||||
@ -34,16 +35,17 @@ typedef struct PartitioningInfo
|
||||
{
|
||||
char column[NAMEDATALEN];
|
||||
AttrNumber column_attnum;
|
||||
TypeCacheEntry *typcache_entry;
|
||||
PartitioningFunc partfunc;
|
||||
} PartitioningInfo;
|
||||
|
||||
|
||||
extern PartitioningInfo *partitioning_info_create(int num_partitions,
|
||||
const char *schema,
|
||||
extern PartitioningInfo *partitioning_info_create(const char *schema,
|
||||
const char *partfunc,
|
||||
const char *partcol,
|
||||
Oid relid);
|
||||
|
||||
extern List *partitioning_func_qualified_name(PartitioningFunc *pf);
|
||||
extern int32 partitioning_func_apply(PartitioningInfo *pinfo, Datum value);
|
||||
extern int32 partitioning_func_apply_tuple(PartitioningInfo *pinfo, HeapTuple tuple, TupleDesc desc);
|
||||
|
||||
|
@ -110,36 +110,37 @@ hypertable_query_walker(Node *node, void *context)
|
||||
|
||||
/* Returns the partitioning info for a var if the var is a partitioning
|
||||
* column. If the var is not a partitioning column return NULL */
|
||||
static PartitioningInfo *
|
||||
static inline PartitioningInfo *
|
||||
get_partitioning_info_for_partition_column_var(Var *var_expr, AddPartFuncQualCtx *context)
|
||||
{
|
||||
Hypertable *ht = context->hentry;
|
||||
RangeTblEntry *rte = rt_fetch(var_expr->varno, context->parse->rtable);
|
||||
char *varname = get_rte_attribute_name(rte, var_expr->varattno);
|
||||
char *varname;
|
||||
Dimension *dim;
|
||||
|
||||
if (rte->relid == context->hentry->main_table_relid)
|
||||
{
|
||||
Dimension *closed_dim = hyperspace_get_closed_dimension(context->hentry->space, 0);
|
||||
if (rte->relid != ht->main_table_relid)
|
||||
return NULL;
|
||||
|
||||
varname = get_rte_attribute_name(rte, var_expr->varattno);
|
||||
|
||||
dim = hyperspace_get_dimension_by_name(ht->space, DIMENSION_TYPE_CLOSED, varname);
|
||||
|
||||
if (dim != NULL)
|
||||
return dim->partitioning;
|
||||
|
||||
if (closed_dim != NULL &&
|
||||
strncmp(closed_dim->fd.column_name.data, varname, NAMEDATALEN) == 0)
|
||||
return closed_dim->partitioning;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Creates an expression for partioning_func(var_expr, partitioning_mod) =
|
||||
* partioning_func(const_expr, partitioning_mod). This function makes a copy of
|
||||
* partitioning_func(const_expr, partitioning_mod). This function makes a copy of
|
||||
* all nodes given in input. */
|
||||
static Expr *
|
||||
create_partition_func_equals_const(Var *var_expr, Const *const_expr, char *partitioning_func_schema,
|
||||
char *partitioning_func)
|
||||
create_partition_func_equals_const(PartitioningInfo *pi, Var *var_expr, Const *const_expr)
|
||||
{
|
||||
Expr *op_expr;
|
||||
List *func_name = list_make2(makeString(partitioning_func_schema), makeString(partitioning_func));
|
||||
Var *var_for_fn_call;
|
||||
Node *var_node_for_fn_call;
|
||||
Const *const_for_fn_call;
|
||||
Node *const_node_for_fn_call;
|
||||
List *func_name = partitioning_func_qualified_name(&pi->partfunc);
|
||||
Node *var_node;
|
||||
Node *const_node;
|
||||
List *args_func_var;
|
||||
List *args_func_const;
|
||||
FuncCall *fc_var;
|
||||
@ -147,33 +148,35 @@ create_partition_func_equals_const(Var *var_expr, Const *const_expr, char *parti
|
||||
Node *f_var;
|
||||
Node *f_const;
|
||||
|
||||
const_for_fn_call = (Const *) palloc(sizeof(Const));
|
||||
memcpy(const_for_fn_call, const_expr, sizeof(Const));
|
||||
|
||||
var_for_fn_call = (Var *) palloc(sizeof(Var));
|
||||
memcpy(var_for_fn_call, var_expr, sizeof(Var));
|
||||
|
||||
if (var_for_fn_call->vartype == TEXTOID)
|
||||
if (pi->partfunc.paramtype == TEXTOID)
|
||||
{
|
||||
var_node_for_fn_call = (Node *) var_for_fn_call;
|
||||
const_node_for_fn_call = (Node *) const_for_fn_call;
|
||||
/* Path for deprecated partitioning function taking text input */
|
||||
if (var_expr->vartype == TEXTOID)
|
||||
{
|
||||
var_node = copyObject(var_expr);
|
||||
const_node = copyObject(const_expr);
|
||||
}
|
||||
else
|
||||
{
|
||||
var_node_for_fn_call =
|
||||
coerce_to_target_type(NULL, (Node *) var_for_fn_call,
|
||||
var_for_fn_call->vartype,
|
||||
var_node = coerce_to_target_type(NULL, (Node *) var_expr,
|
||||
var_expr->vartype,
|
||||
TEXTOID, -1, COERCION_EXPLICIT,
|
||||
COERCE_EXPLICIT_CAST, -1);
|
||||
const_node_for_fn_call =
|
||||
coerce_to_target_type(NULL, (Node *) const_for_fn_call,
|
||||
const_for_fn_call->consttype,
|
||||
const_node = coerce_to_target_type(NULL, (Node *) const_expr,
|
||||
const_expr->consttype,
|
||||
TEXTOID, -1, COERCION_EXPLICIT,
|
||||
COERCE_EXPLICIT_CAST, -1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Path for partitioning func taking anyelement */
|
||||
var_node = copyObject(var_expr);
|
||||
const_node = copyObject(const_expr);
|
||||
}
|
||||
|
||||
args_func_var = list_make1(var_node_for_fn_call);
|
||||
args_func_const = list_make1(const_node_for_fn_call);
|
||||
args_func_var = list_make1(var_node);
|
||||
args_func_const = list_make1(const_node);
|
||||
|
||||
fc_var = makeFuncCall(func_name, args_func_var, -1);
|
||||
fc_const = makeFuncCall(func_name, args_func_const, -1);
|
||||
@ -248,8 +251,8 @@ add_partitioning_func_qual_mutator(Node *node, AddPartFuncQualCtx *context)
|
||||
if (pi != NULL)
|
||||
{
|
||||
/* The var is a partitioning column */
|
||||
Expr *partitioning_clause = create_partition_func_equals_const(var_expr, const_expr,
|
||||
pi->partfunc.schema, pi->partfunc.name);
|
||||
Expr *partitioning_clause =
|
||||
create_partition_func_equals_const(pi, var_expr, const_expr);
|
||||
|
||||
return (Node *) make_andclause(list_make2(node, partitioning_clause));
|
||||
|
||||
|
@ -1005,7 +1005,24 @@ typename_get_unqual_name(TypeName *tn)
|
||||
}
|
||||
|
||||
static void
|
||||
process_alter_column_type(Hypertable *ht, AlterTableCmd *cmd)
|
||||
process_alter_column_type_start(Hypertable *ht, AlterTableCmd *cmd)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ht->space->num_dimensions; i++)
|
||||
{
|
||||
Dimension *dim = &ht->space->dimensions[i];
|
||||
|
||||
if (IS_CLOSED_DIMENSION(dim) &&
|
||||
strncmp(NameStr(dim->fd.column_name), cmd->name, NAMEDATALEN) == 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_IO_OPERATION_NOT_SUPPORTED),
|
||||
errmsg("Cannot change the type of a hash-partitioned column")));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
process_alter_column_type_end(Hypertable *ht, AlterTableCmd *cmd)
|
||||
{
|
||||
ColumnDef *coldef = (ColumnDef *) cmd->def;
|
||||
Oid new_type = TypenameGetTypid(typename_get_unqual_name(coldef->typeName));
|
||||
@ -1102,6 +1119,11 @@ process_altertable_start(Node *parsetree)
|
||||
verify_constraint_plaintable(stmt->relation, (Constraint *) cmd->def);
|
||||
else
|
||||
verify_constraint_hypertable(ht, cmd->def);
|
||||
break;
|
||||
case AT_AlterColumnType:
|
||||
Assert(IsA(cmd->def, ColumnDef));
|
||||
process_alter_column_type_start(ht, cmd);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1163,7 +1185,7 @@ process_altertable_end_subcmd(Hypertable *ht, Node *parsetree, ObjectAddress *ob
|
||||
break;
|
||||
case AT_AlterColumnType:
|
||||
Assert(IsA(cmd->def, ColumnDef));
|
||||
process_alter_column_type(ht, cmd);
|
||||
process_alter_column_type_end(ht, cmd);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -29,7 +29,7 @@ SELECT create_hypertable('chunk_test', 'time', 'tag', 2, chunk_time_interval =>
|
||||
|
||||
(1 row)
|
||||
|
||||
INSERT INTO chunk_test VALUES (4, 24.3, 3, 1);
|
||||
INSERT INTO chunk_test VALUES (4, 24.3, 1, 1);
|
||||
SELECT * FROM _timescaledb_catalog.dimension_slice;
|
||||
id | dimension_id | range_start | range_end
|
||||
----+--------------+-------------+------------
|
||||
@ -37,8 +37,8 @@ SELECT * FROM _timescaledb_catalog.dimension_slice;
|
||||
2 | 2 | 0 | 1073741823
|
||||
(2 rows)
|
||||
|
||||
INSERT INTO chunk_test VALUES (4, 24.3, 1, 1);
|
||||
INSERT INTO chunk_test VALUES (10, 24.3, 1, 1);
|
||||
INSERT INTO chunk_test VALUES (4, 24.3, 2, 1);
|
||||
INSERT INTO chunk_test VALUES (10, 24.3, 2, 1);
|
||||
SELECT c.table_name AS chunk_name, d.id AS dimension_id, ds.id AS slice_id, range_start, range_end FROM _timescaledb_catalog.chunk c
|
||||
LEFT JOIN _timescaledb_catalog.chunk_constraint cc ON (c.id = cc.chunk_id)
|
||||
LEFT JOIN _timescaledb_catalog.dimension_slice ds ON (ds.id = cc.dimension_slice_id)
|
||||
@ -65,7 +65,7 @@ SELECT set_chunk_time_interval('chunk_test', 1::bigint);
|
||||
|
||||
(1 row)
|
||||
|
||||
INSERT INTO chunk_test VALUES (8, 24.3, 79669, 1);
|
||||
INSERT INTO chunk_test VALUES (8, 24.3, 11233, 1);
|
||||
SELECT set_chunk_time_interval('chunk_test', 5::bigint);
|
||||
set_chunk_time_interval
|
||||
-------------------------
|
||||
@ -74,15 +74,15 @@ SELECT set_chunk_time_interval('chunk_test', 5::bigint);
|
||||
|
||||
SELECT * FROM _timescaledb_catalog.dimension;
|
||||
id | hypertable_id | column_name | column_type | aligned | num_slices | partitioning_func_schema | partitioning_func | interval_length
|
||||
----+---------------+-------------+-------------+---------+------------+--------------------------+-----------------------+-----------------
|
||||
2 | 1 | tag | integer | f | 3 | _timescaledb_internal | get_partition_for_key |
|
||||
----+---------------+-------------+-------------+---------+------------+--------------------------+--------------------+-----------------
|
||||
2 | 1 | tag | integer | f | 3 | _timescaledb_internal | get_partition_hash |
|
||||
1 | 1 | time | integer | t | | | | 5
|
||||
(2 rows)
|
||||
|
||||
INSERT INTO chunk_test VALUES (7, 24.3, 11233, 1);
|
||||
INSERT INTO chunk_test VALUES (8, 24.3, 11233, 1);
|
||||
INSERT INTO chunk_test VALUES (10, 24.3, 79669, 1);
|
||||
INSERT INTO chunk_test VALUES (16, 24.3, 79669, 1);
|
||||
INSERT INTO chunk_test VALUES (7, 24.3, 79669, 1);
|
||||
INSERT INTO chunk_test VALUES (8, 24.3, 79669, 1);
|
||||
INSERT INTO chunk_test VALUES (10, 24.3, 11233, 1);
|
||||
INSERT INTO chunk_test VALUES (16, 24.3, 11233, 1);
|
||||
SELECT c.table_name AS chunk_name, d.id AS dimension_id, ds.id AS slice_id, range_start, range_end FROM _timescaledb_catalog.chunk c
|
||||
LEFT JOIN _timescaledb_catalog.chunk_constraint cc ON (c.id = cc.chunk_id)
|
||||
LEFT JOIN _timescaledb_catalog.dimension_slice ds ON (ds.id = cc.dimension_slice_id)
|
||||
|
@ -41,10 +41,10 @@ select * from _timescaledb_catalog.hypertable where table_name = 'test_table';
|
||||
|
||||
select * from _timescaledb_catalog.dimension;
|
||||
id | hypertable_id | column_name | column_type | aligned | num_slices | partitioning_func_schema | partitioning_func | interval_length
|
||||
----+---------------+-------------+-------------+---------+------------+--------------------------+-----------------------+-----------------
|
||||
----+---------------+-------------+-------------+---------+------------+--------------------------+--------------------+-----------------
|
||||
1 | 1 | time | bigint | t | | | | 2592000000000
|
||||
2 | 1 | device_id | text | f | 2 | _timescaledb_internal | get_partition_for_key |
|
||||
3 | 1 | location | text | f | 2 | _timescaledb_internal | get_partition_for_key |
|
||||
2 | 1 | device_id | text | f | 2 | _timescaledb_internal | get_partition_hash |
|
||||
3 | 1 | location | text | f | 2 | _timescaledb_internal | get_partition_hash |
|
||||
(3 rows)
|
||||
|
||||
\set ON_ERROR_STOP 0
|
||||
@ -67,10 +67,10 @@ select * from _timescaledb_catalog.hypertable where table_name = 'test_table';
|
||||
|
||||
select * from _timescaledb_catalog.dimension;
|
||||
id | hypertable_id | column_name | column_type | aligned | num_slices | partitioning_func_schema | partitioning_func | interval_length
|
||||
----+---------------+-------------+-------------+---------+------------+--------------------------+-----------------------+-----------------
|
||||
----+---------------+-------------+-------------+---------+------------+--------------------------+--------------------+-----------------
|
||||
1 | 1 | time | bigint | t | | | | 2592000000000
|
||||
2 | 1 | device_id | text | f | 2 | _timescaledb_internal | get_partition_for_key |
|
||||
3 | 1 | location | text | f | 2 | _timescaledb_internal | get_partition_for_key |
|
||||
2 | 1 | device_id | text | f | 2 | _timescaledb_internal | get_partition_hash |
|
||||
3 | 1 | location | text | f | 2 | _timescaledb_internal | get_partition_hash |
|
||||
4 | 1 | id | integer | t | | | | 1000
|
||||
(4 rows)
|
||||
|
||||
|
@ -351,7 +351,7 @@ Indexes:
|
||||
"_hyper_1_1_chunk_ind_sensor_1" btree ("time", sensor_1)
|
||||
Check constraints:
|
||||
"constraint_1" CHECK ("time" >= '1257892416000000000'::bigint AND "time" < '1257895008000000000'::bigint)
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_for_key("Device_id") >= 0 AND _timescaledb_internal.get_partition_for_key("Device_id") < 2147483647)
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_hash("Device_id") >= 0 AND _timescaledb_internal.get_partition_hash("Device_id") < 2147483647)
|
||||
Inherits: "Hypertable_1"
|
||||
|
||||
\ir include/ddl_ops_2.sql
|
||||
|
@ -36,7 +36,7 @@ Indexes:
|
||||
"_hyper_1_1_chunk_alter_test_time_idx" btree ("time" DESC)
|
||||
Check constraints:
|
||||
"constraint_1" CHECK ("time" >= 'Thu Jan 19 02:00:00 2017 PST'::timestamp with time zone AND "time" < 'Sat Feb 18 12:00:00 2017 PST'::timestamp with time zone)
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_for_key(color::text) >= 0 AND _timescaledb_internal.get_partition_for_key(color::text) < 1073741823)
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_hash(color) >= 0 AND _timescaledb_internal.get_partition_hash(color) < 1073741823)
|
||||
Inherits: alter_test
|
||||
|
||||
Index "_timescaledb_internal._hyper_1_1_chunk_alter_test_color_time_idx"
|
||||
@ -63,7 +63,7 @@ Indexes:
|
||||
"_hyper_1_2_chunk_alter_test_time_idx" btree ("time" DESC)
|
||||
Check constraints:
|
||||
"constraint_3" CHECK ("time" >= 'Thu Apr 20 09:00:00 2017 PDT'::timestamp with time zone AND "time" < 'Sat May 20 19:00:00 2017 PDT'::timestamp with time zone)
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_for_key(color::text) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(color::text) < 2147483647)
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_hash(color) >= 1073741823 AND _timescaledb_internal.get_partition_hash(color) < 2147483647)
|
||||
Inherits: alter_test
|
||||
|
||||
Index "_timescaledb_internal._hyper_1_2_chunk_alter_test_color_time_idx"
|
||||
@ -89,7 +89,7 @@ Indexes:
|
||||
"_hyper_1_3_chunk_alter_test_color_time_idx" btree (color, "time" DESC)
|
||||
"_hyper_1_3_chunk_alter_test_time_idx" btree ("time" DESC)
|
||||
Check constraints:
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_for_key(color::text) >= 0 AND _timescaledb_internal.get_partition_for_key(color::text) < 1073741823)
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_hash(color) >= 0 AND _timescaledb_internal.get_partition_hash(color) < 1073741823)
|
||||
"constraint_3" CHECK ("time" >= 'Thu Apr 20 09:00:00 2017 PDT'::timestamp with time zone AND "time" < 'Sat May 20 19:00:00 2017 PDT'::timestamp with time zone)
|
||||
Inherits: alter_test
|
||||
|
||||
@ -110,9 +110,9 @@ btree, for table "_timescaledb_internal._hyper_1_3_chunk"
|
||||
-- metadata table
|
||||
SELECT * FROM _timescaledb_catalog.dimension;
|
||||
id | hypertable_id | column_name | column_type | aligned | num_slices | partitioning_func_schema | partitioning_func | interval_length
|
||||
----+---------------+-------------+--------------------------+---------+------------+--------------------------+-----------------------+-----------------
|
||||
----+---------------+-------------+--------------------------+---------+------------+--------------------------+--------------------+-----------------
|
||||
1 | 1 | time | timestamp with time zone | t | | | | 2628000000000
|
||||
2 | 1 | color | character varying | f | 2 | _timescaledb_internal | get_partition_for_key |
|
||||
2 | 1 | color | character varying | f | 2 | _timescaledb_internal | get_partition_hash |
|
||||
(2 rows)
|
||||
|
||||
EXPLAIN (costs off)
|
||||
@ -136,14 +136,19 @@ SELECT * FROM alter_test WHERE time > '2017-05-20T10:00:01';
|
||||
ALTER TABLE alter_test RENAME COLUMN time TO time_us;
|
||||
ALTER TABLE alter_test ALTER COLUMN time_us TYPE timestamp;
|
||||
ALTER TABLE alter_test RENAME COLUMN color TO colorname;
|
||||
\set ON_ERROR_STOP 0
|
||||
-- Changing types on hash-partitioned columns is not safe for some
|
||||
-- types and is therefore blocked.
|
||||
ALTER TABLE alter_test ALTER COLUMN colorname TYPE text;
|
||||
ERROR: Cannot change the type of a hash-partitioned column
|
||||
\set ON_ERROR_STOP 1
|
||||
\d+ alter_test
|
||||
Table "public.alter_test"
|
||||
Column | Type | Modifiers | Storage | Stats target | Description
|
||||
-----------+-----------------------------+-----------+----------+--------------+-------------
|
||||
time_us | timestamp without time zone | | plain | |
|
||||
temp | double precision | | plain | |
|
||||
colorname | text | | extended | |
|
||||
colorname | character varying(10) | | extended | |
|
||||
Indexes:
|
||||
"alter_test_color_time_idx" btree (colorname, time_us DESC)
|
||||
"alter_test_time_idx" btree (time_us DESC)
|
||||
@ -157,19 +162,19 @@ Child tables: _timescaledb_internal._hyper_1_1_chunk,
|
||||
-----------+-----------------------------+-----------+----------+--------------+-------------
|
||||
time_us | timestamp without time zone | | plain | |
|
||||
temp | double precision | | plain | |
|
||||
colorname | text | | extended | |
|
||||
colorname | character varying(10) | | extended | |
|
||||
Indexes:
|
||||
"_hyper_1_1_chunk_alter_test_color_time_idx" btree (colorname, time_us DESC)
|
||||
"_hyper_1_1_chunk_alter_test_time_idx" btree (time_us DESC)
|
||||
Check constraints:
|
||||
"constraint_1" CHECK (time_us >= 'Thu Jan 19 02:00:00 2017'::timestamp without time zone AND time_us < 'Sat Feb 18 12:00:00 2017'::timestamp without time zone)
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_for_key(colorname) >= 0 AND _timescaledb_internal.get_partition_for_key(colorname) < 1073741823)
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_hash(colorname) >= 0 AND _timescaledb_internal.get_partition_hash(colorname) < 1073741823)
|
||||
Inherits: alter_test
|
||||
|
||||
Index "_timescaledb_internal._hyper_1_1_chunk_alter_test_color_time_idx"
|
||||
Column | Type | Definition | Storage
|
||||
-----------+-----------------------------+------------+----------
|
||||
colorname | text | colorname | extended
|
||||
---------+-----------------------------+------------+----------
|
||||
color | character varying(10) | colorname | extended
|
||||
time_us | timestamp without time zone | time_us | plain
|
||||
btree, for table "_timescaledb_internal._hyper_1_1_chunk"
|
||||
|
||||
@ -184,19 +189,19 @@ btree, for table "_timescaledb_internal._hyper_1_1_chunk"
|
||||
-----------+-----------------------------+-----------+----------+--------------+-------------
|
||||
time_us | timestamp without time zone | | plain | |
|
||||
temp | double precision | | plain | |
|
||||
colorname | text | | extended | |
|
||||
colorname | character varying(10) | | extended | |
|
||||
Indexes:
|
||||
"_hyper_1_2_chunk_alter_test_color_time_idx" btree (colorname, time_us DESC)
|
||||
"_hyper_1_2_chunk_alter_test_time_idx" btree (time_us DESC)
|
||||
Check constraints:
|
||||
"constraint_3" CHECK (time_us >= 'Thu Apr 20 09:00:00 2017'::timestamp without time zone AND time_us < 'Sat May 20 19:00:00 2017'::timestamp without time zone)
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_for_key(colorname) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(colorname) < 2147483647)
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_hash(colorname) >= 1073741823 AND _timescaledb_internal.get_partition_hash(colorname) < 2147483647)
|
||||
Inherits: alter_test
|
||||
|
||||
Index "_timescaledb_internal._hyper_1_2_chunk_alter_test_color_time_idx"
|
||||
Column | Type | Definition | Storage
|
||||
-----------+-----------------------------+------------+----------
|
||||
colorname | text | colorname | extended
|
||||
---------+-----------------------------+------------+----------
|
||||
color | character varying(10) | colorname | extended
|
||||
time_us | timestamp without time zone | time_us | plain
|
||||
btree, for table "_timescaledb_internal._hyper_1_2_chunk"
|
||||
|
||||
@ -211,19 +216,19 @@ btree, for table "_timescaledb_internal._hyper_1_2_chunk"
|
||||
-----------+-----------------------------+-----------+----------+--------------+-------------
|
||||
time_us | timestamp without time zone | | plain | |
|
||||
temp | double precision | | plain | |
|
||||
colorname | text | | extended | |
|
||||
colorname | character varying(10) | | extended | |
|
||||
Indexes:
|
||||
"_hyper_1_3_chunk_alter_test_color_time_idx" btree (colorname, time_us DESC)
|
||||
"_hyper_1_3_chunk_alter_test_time_idx" btree (time_us DESC)
|
||||
Check constraints:
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_for_key(colorname) >= 0 AND _timescaledb_internal.get_partition_for_key(colorname) < 1073741823)
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_hash(colorname) >= 0 AND _timescaledb_internal.get_partition_hash(colorname) < 1073741823)
|
||||
"constraint_3" CHECK (time_us >= 'Thu Apr 20 09:00:00 2017'::timestamp without time zone AND time_us < 'Sat May 20 19:00:00 2017'::timestamp without time zone)
|
||||
Inherits: alter_test
|
||||
|
||||
Index "_timescaledb_internal._hyper_1_3_chunk_alter_test_color_time_idx"
|
||||
Column | Type | Definition | Storage
|
||||
-----------+-----------------------------+------------+----------
|
||||
colorname | text | colorname | extended
|
||||
---------+-----------------------------+------------+----------
|
||||
color | character varying(10) | colorname | extended
|
||||
time_us | timestamp without time zone | time_us | plain
|
||||
btree, for table "_timescaledb_internal._hyper_1_3_chunk"
|
||||
|
||||
@ -236,9 +241,9 @@ btree, for table "_timescaledb_internal._hyper_1_3_chunk"
|
||||
-- show that the metadata has been updated
|
||||
SELECT * FROM _timescaledb_catalog.dimension;
|
||||
id | hypertable_id | column_name | column_type | aligned | num_slices | partitioning_func_schema | partitioning_func | interval_length
|
||||
----+---------------+-------------+-----------------------------+---------+------------+--------------------------+-----------------------+-----------------
|
||||
----+---------------+-------------+-----------------------------+---------+------------+--------------------------+--------------------+-----------------
|
||||
1 | 1 | time_us | timestamp without time zone | t | | | | 2628000000000
|
||||
2 | 1 | colorname | text | f | 2 | _timescaledb_internal | get_partition_for_key |
|
||||
2 | 1 | colorname | character varying | f | 2 | _timescaledb_internal | get_partition_hash |
|
||||
(2 rows)
|
||||
|
||||
-- constraint exclusion should still work with updated column
|
||||
@ -258,7 +263,7 @@ SELECT * FROM alter_test WHERE time_us > '2017-05-20T10:00:01';
|
||||
\set ON_ERROR_STOP 0
|
||||
-- verify that we cannot change the column type to something incompatible
|
||||
ALTER TABLE alter_test ALTER COLUMN colorname TYPE varchar(3);
|
||||
ERROR: value too long for type character varying(3)
|
||||
ERROR: Cannot change the type of a hash-partitioned column
|
||||
-- conversion that messes up partitioning fails
|
||||
ALTER TABLE alter_test ALTER COLUMN time_us TYPE timestamptz USING time_us::timestamptz+INTERVAL '1 year';
|
||||
ERROR: check constraint "constraint_1" is violated by some row
|
||||
|
@ -381,7 +381,7 @@ Indexes:
|
||||
"_hyper_1_1_chunk_ind_humdity2" btree ("time", humidity)
|
||||
Check constraints:
|
||||
"constraint_1" CHECK ("time" >= '1257892416000000000'::bigint AND "time" < '1257895008000000000'::bigint)
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_for_key("Device_id") >= 0 AND _timescaledb_internal.get_partition_for_key("Device_id") < 2147483647)
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_hash("Device_id") >= 0 AND _timescaledb_internal.get_partition_hash("Device_id") < 2147483647)
|
||||
Inherits: "Hypertable_1"
|
||||
|
||||
SELECT * FROM PUBLIC."Hypertable_1";
|
||||
|
@ -49,7 +49,7 @@ Indexes:
|
||||
"_hyper_1_1_chunk_two_Partitions_timeCustom_series_bool_idx" btree ("timeCustom" DESC NULLS LAST, series_bool) WHERE series_bool IS NOT NULL
|
||||
Check constraints:
|
||||
"constraint_1" CHECK ("timeCustom" >= '1257892416000000000'::bigint AND "timeCustom" < '1257895008000000000'::bigint)
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_for_key(device_id) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(device_id) < 2147483647)
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_hash(device_id) >= 1073741823 AND _timescaledb_internal.get_partition_hash(device_id) < 2147483647)
|
||||
Inherits: "two_Partitions"
|
||||
|
||||
Index "_timescaledb_internal._hyper_1_1_chunk_two_Partitions_device_id_timeCustom_idx"
|
||||
@ -118,7 +118,7 @@ Indexes:
|
||||
"_hyper_1_2_chunk_two_Partitions_timeCustom_series_2_idx" btree ("timeCustom" DESC NULLS LAST, series_2) WHERE series_2 IS NOT NULL
|
||||
"_hyper_1_2_chunk_two_Partitions_timeCustom_series_bool_idx" btree ("timeCustom" DESC NULLS LAST, series_bool) WHERE series_bool IS NOT NULL
|
||||
Check constraints:
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_for_key(device_id) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(device_id) < 2147483647)
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_hash(device_id) >= 1073741823 AND _timescaledb_internal.get_partition_hash(device_id) < 2147483647)
|
||||
"constraint_3" CHECK ("timeCustom" >= '1257897600000000000'::bigint AND "timeCustom" < '1257900192000000000'::bigint)
|
||||
Inherits: "two_Partitions"
|
||||
|
||||
@ -188,7 +188,7 @@ Indexes:
|
||||
"_hyper_1_3_chunk_two_Partitions_timeCustom_series_2_idx" btree ("timeCustom" DESC NULLS LAST, series_2) WHERE series_2 IS NOT NULL
|
||||
"_hyper_1_3_chunk_two_Partitions_timeCustom_series_bool_idx" btree ("timeCustom" DESC NULLS LAST, series_bool) WHERE series_bool IS NOT NULL
|
||||
Check constraints:
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_for_key(device_id) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(device_id) < 2147483647)
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_hash(device_id) >= 1073741823 AND _timescaledb_internal.get_partition_hash(device_id) < 2147483647)
|
||||
"constraint_4" CHECK ("timeCustom" >= '1257985728000000000'::bigint AND "timeCustom" < '1257988320000000000'::bigint)
|
||||
Inherits: "two_Partitions"
|
||||
|
||||
@ -259,7 +259,7 @@ Indexes:
|
||||
"_hyper_1_4_chunk_two_Partitions_timeCustom_series_bool_idx" btree ("timeCustom" DESC NULLS LAST, series_bool) WHERE series_bool IS NOT NULL
|
||||
Check constraints:
|
||||
"constraint_1" CHECK ("timeCustom" >= '1257892416000000000'::bigint AND "timeCustom" < '1257895008000000000'::bigint)
|
||||
"constraint_5" CHECK (_timescaledb_internal.get_partition_for_key(device_id) >= 0 AND _timescaledb_internal.get_partition_for_key(device_id) < 1073741823)
|
||||
"constraint_5" CHECK (_timescaledb_internal.get_partition_hash(device_id) >= 0 AND _timescaledb_internal.get_partition_hash(device_id) < 1073741823)
|
||||
Inherits: "two_Partitions"
|
||||
|
||||
Index "_timescaledb_internal._hyper_1_4_chunk_two_Partitions_device_id_timeCustom_idx"
|
||||
@ -331,7 +331,7 @@ Indexes:
|
||||
"_hyper_1_1_chunk_two_Partitions_timeCustom_series_bool_idx" btree ("timeCustom" DESC NULLS LAST, series_bool) WHERE series_bool IS NOT NULL
|
||||
Check constraints:
|
||||
"constraint_1" CHECK ("timeCustom" >= '1257892416000000000'::bigint AND "timeCustom" < '1257895008000000000'::bigint)
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_for_key(device_id) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(device_id) < 2147483647)
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_hash(device_id) >= 1073741823 AND _timescaledb_internal.get_partition_hash(device_id) < 2147483647)
|
||||
Inherits: "two_Partitions"
|
||||
|
||||
ALTER TABLE "two_Partitions" RENAME TO "newname";
|
||||
|
@ -177,11 +177,11 @@ SELECT *,
|
||||
) sub1
|
||||
) sub2;
|
||||
chunk_id | chunk_table | partitioning_columns | partitioning_column_types | partitioning_hash_functions | ranges | table_bytes | index_bytes | toast_bytes | total_bytes
|
||||
----------+--------------------------------------------+------------------------+---------------------------+----------------------------------------------------+-----------------------------------------------------------------------------+-------------+-------------+-------------+-------------
|
||||
1 | "_timescaledb_internal"."_hyper_1_1_chunk" | {timeCustom,device_id} | {bigint,text} | {NULL,_timescaledb_internal.get_partition_for_key} | {"['1257892416000000000','1257895008000000000')","[1073741823,2147483647)"} | 8192 | 114688 | 8192 | 131072
|
||||
2 | "_timescaledb_internal"."_hyper_1_2_chunk" | {timeCustom,device_id} | {bigint,text} | {NULL,_timescaledb_internal.get_partition_for_key} | {"['1257897600000000000','1257900192000000000')","[1073741823,2147483647)"} | 8192 | 106496 | 8192 | 122880
|
||||
3 | "_timescaledb_internal"."_hyper_1_3_chunk" | {timeCustom,device_id} | {bigint,text} | {NULL,_timescaledb_internal.get_partition_for_key} | {"['1257985728000000000','1257988320000000000')","[1073741823,2147483647)"} | 8192 | 98304 | 8192 | 114688
|
||||
4 | "_timescaledb_internal"."_hyper_1_4_chunk" | {timeCustom,device_id} | {bigint,text} | {NULL,_timescaledb_internal.get_partition_for_key} | {"['1257892416000000000','1257895008000000000')","[0,1073741823)"} | 8192 | 98304 | 8192 | 114688
|
||||
----------+--------------------------------------------+------------------------+---------------------------+-------------------------------------------------+-----------------------------------------------------------------------------+-------------+-------------+-------------+-------------
|
||||
1 | "_timescaledb_internal"."_hyper_1_1_chunk" | {timeCustom,device_id} | {bigint,text} | {NULL,_timescaledb_internal.get_partition_hash} | {"['1257892416000000000','1257895008000000000')","[1073741823,2147483647)"} | 8192 | 114688 | 8192 | 131072
|
||||
2 | "_timescaledb_internal"."_hyper_1_2_chunk" | {timeCustom,device_id} | {bigint,text} | {NULL,_timescaledb_internal.get_partition_hash} | {"['1257897600000000000','1257900192000000000')","[1073741823,2147483647)"} | 8192 | 106496 | 8192 | 122880
|
||||
3 | "_timescaledb_internal"."_hyper_1_3_chunk" | {timeCustom,device_id} | {bigint,text} | {NULL,_timescaledb_internal.get_partition_hash} | {"['1257985728000000000','1257988320000000000')","[1073741823,2147483647)"} | 8192 | 98304 | 8192 | 114688
|
||||
4 | "_timescaledb_internal"."_hyper_1_4_chunk" | {timeCustom,device_id} | {bigint,text} | {NULL,_timescaledb_internal.get_partition_hash} | {"['1257892416000000000','1257895008000000000')","[0,1073741823)"} | 8192 | 98304 | 8192 | 114688
|
||||
(4 rows)
|
||||
|
||||
\echo 'Hypertable index sizes'
|
||||
|
252
test/expected/hash.out
Normal file
252
test/expected/hash.out
Normal file
@ -0,0 +1,252 @@
|
||||
-- Test hashing Const values. We should expect the same hash value for
|
||||
-- all integer types when values are compatible
|
||||
SELECT _timescaledb_internal.get_partition_hash(1::int);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
242423622
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash(1::bigint);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
242423622
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash(1::smallint);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
242423622
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash(true);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
242423622
|
||||
(1 row)
|
||||
|
||||
-- Floating point types should also hash the same for compatible values
|
||||
SELECT _timescaledb_internal.get_partition_hash(1.0::real);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
376496956
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash(1.0::double precision);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
376496956
|
||||
(1 row)
|
||||
|
||||
-- Float aliases
|
||||
SELECT _timescaledb_internal.get_partition_hash(1.0::float);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
376496956
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash(1.0::float4);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
376496956
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash(1.0::float8);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
376496956
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash(1.0::numeric);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
1324868424
|
||||
(1 row)
|
||||
|
||||
-- 'name' and '"char"' are internal PostgreSQL types, which are not
|
||||
-- intended for use by the general user. They are included here only
|
||||
-- for completeness
|
||||
-- https://www.postgresql.org/docs/10/static/datatype-character.html#datatype-character-special-table
|
||||
SELECT _timescaledb_internal.get_partition_hash('c'::name);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
1903644986
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash('c'::"char");
|
||||
get_partition_hash
|
||||
--------------------
|
||||
203891234
|
||||
(1 row)
|
||||
|
||||
-- String and character hashes should also have the same output for
|
||||
-- compatible values
|
||||
SELECT _timescaledb_internal.get_partition_hash('c'::char);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
1903644986
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash('c'::varchar(2));
|
||||
get_partition_hash
|
||||
--------------------
|
||||
1903644986
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash('c'::text);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
1903644986
|
||||
(1 row)
|
||||
|
||||
-- 'c' is 0x63 in ASCII
|
||||
SELECT _timescaledb_internal.get_partition_hash(E'\\x63'::bytea);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
1903644986
|
||||
(1 row)
|
||||
|
||||
-- Time and date types
|
||||
SELECT _timescaledb_internal.get_partition_hash(interval '1 day');
|
||||
get_partition_hash
|
||||
--------------------
|
||||
93502988
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash('2017-03-22T09:18:23'::timestamp);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
307315039
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash('2017-03-22T09:18:23'::timestamptz);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
1195163597
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash('2017-03-22'::date);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
693590295
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash('10:00:00'::time);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
1380652790
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash('10:00:00-1'::timetz);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
769387140
|
||||
(1 row)
|
||||
|
||||
-- Other types
|
||||
SELECT _timescaledb_internal.get_partition_hash(ARRAY[1,2,3]);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
1822090118
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash('08002b:010203'::macaddr);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
294987870
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash('192.168.100.128/25'::cidr);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
1612896565
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash('192.168.100.128'::inet);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
1952516432
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash('2001:4f8:3:ba:2e0:81ff:fe22:d1f1'::inet);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
933321588
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash('2001:4f8:3:ba:2e0:81ff:fe22:d1f1/128'::cidr);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
933321588
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash('{ "foo": "bar" }'::jsonb);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
208840587
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash('4b6a5eec-b344-11e7-abc4-cec278b6b50a'::uuid);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
504202548
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash(1::regclass);
|
||||
get_partition_hash
|
||||
--------------------
|
||||
242423622
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash(int4range(10, 20));
|
||||
get_partition_hash
|
||||
--------------------
|
||||
1202375768
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash(int8range(10, 20));
|
||||
get_partition_hash
|
||||
--------------------
|
||||
1202375768
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash(numrange(10, 20));
|
||||
get_partition_hash
|
||||
--------------------
|
||||
1083987536
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash(tsrange('2017-03-22T09:18:23', '2017-03-23T09:18:23'));
|
||||
get_partition_hash
|
||||
--------------------
|
||||
2079608838
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash(tstzrange('2017-03-22T09:18:23+01', '2017-03-23T09:18:23+00'));
|
||||
get_partition_hash
|
||||
--------------------
|
||||
1255083771
|
||||
(1 row)
|
||||
|
||||
-- Test hashing Var values
|
||||
CREATE TABLE hash_test(id int, value text);
|
||||
INSERT INTO hash_test VALUES (1, 'test');
|
||||
-- Test Vars
|
||||
SELECT _timescaledb_internal.get_partition_hash(id) FROM hash_test;
|
||||
get_partition_hash
|
||||
--------------------
|
||||
242423622
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.get_partition_hash(value) FROM hash_test;
|
||||
get_partition_hash
|
||||
--------------------
|
||||
1771415073
|
||||
(1 row)
|
||||
|
||||
-- Test coerced value
|
||||
SELECT _timescaledb_internal.get_partition_hash(id::text) FROM hash_test;
|
||||
get_partition_hash
|
||||
--------------------
|
||||
1516350201
|
||||
(1 row)
|
||||
|
@ -200,7 +200,7 @@ Indexes:
|
||||
"_hyper_4_3_chunk_time_temp_idx" btree ("time", temp)
|
||||
Check constraints:
|
||||
"constraint_3" CHECK ("time" >= 'Sat Dec 24 16:00:00 2016 PST'::timestamp with time zone AND "time" < 'Mon Jan 23 16:00:00 2017 PST'::timestamp with time zone)
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_for_key(device::text) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(device::text) < 2147483647)
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_hash(device) >= 0 AND _timescaledb_internal.get_partition_hash(device) < 1073741823)
|
||||
Inherits: index_test
|
||||
|
||||
Table "_timescaledb_internal._hyper_4_4_chunk"
|
||||
@ -215,7 +215,7 @@ Indexes:
|
||||
"_hyper_4_4_chunk_index_test_time_idx" btree ("time" DESC)
|
||||
"_hyper_4_4_chunk_index_test_time_temp_idx" btree ("time", temp)
|
||||
Check constraints:
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_for_key(device::text) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(device::text) < 2147483647)
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_hash(device) >= 0 AND _timescaledb_internal.get_partition_hash(device) < 1073741823)
|
||||
"constraint_5" CHECK ("time" >= 'Fri Mar 24 17:00:00 2017 PDT'::timestamp with time zone AND "time" < 'Sun Apr 23 17:00:00 2017 PDT'::timestamp with time zone)
|
||||
Inherits: index_test
|
||||
|
||||
@ -263,7 +263,7 @@ Indexes:
|
||||
"_hyper_4_3_chunk_time_temp_idx" btree ("time", temp)
|
||||
Check constraints:
|
||||
"constraint_3" CHECK ("time" >= 'Sat Dec 24 16:00:00 2016 PST'::timestamp with time zone AND "time" < 'Mon Jan 23 16:00:00 2017 PST'::timestamp with time zone)
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_for_key(device::text) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(device::text) < 2147483647)
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_hash(device) >= 0 AND _timescaledb_internal.get_partition_hash(device) < 1073741823)
|
||||
Inherits: index_test
|
||||
|
||||
Table "_timescaledb_internal._hyper_4_4_chunk"
|
||||
@ -278,7 +278,7 @@ Indexes:
|
||||
"_hyper_4_4_chunk_index_test_time_idx2" btree ("time" DESC)
|
||||
"_hyper_4_4_chunk_index_test_time_temp_idx" btree ("time", temp)
|
||||
Check constraints:
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_for_key(device::text) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(device::text) < 2147483647)
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_hash(device) >= 0 AND _timescaledb_internal.get_partition_hash(device) < 1073741823)
|
||||
"constraint_5" CHECK ("time" >= 'Fri Mar 24 17:00:00 2017 PDT'::timestamp with time zone AND "time" < 'Sun Apr 23 17:00:00 2017 PDT'::timestamp with time zone)
|
||||
Inherits: index_test
|
||||
|
||||
@ -323,7 +323,7 @@ Indexes:
|
||||
"_hyper_4_3_chunk_time_temp_idx" btree ("time", temp)
|
||||
Check constraints:
|
||||
"constraint_3" CHECK ("time" >= 'Sat Dec 24 16:00:00 2016 PST'::timestamp with time zone AND "time" < 'Mon Jan 23 16:00:00 2017 PST'::timestamp with time zone)
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_for_key(device::text) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(device::text) < 2147483647)
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_hash(device) >= 0 AND _timescaledb_internal.get_partition_hash(device) < 1073741823)
|
||||
Inherits: index_test
|
||||
|
||||
Table "_timescaledb_internal._hyper_4_4_chunk"
|
||||
@ -336,7 +336,7 @@ Indexes:
|
||||
"_hyper_4_4_chunk_index_test_device_time_idx" btree (device, "time" DESC)
|
||||
"_hyper_4_4_chunk_index_test_time_temp_idx" btree ("time", temp)
|
||||
Check constraints:
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_for_key(device::text) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(device::text) < 2147483647)
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_hash(device) >= 0 AND _timescaledb_internal.get_partition_hash(device) < 1073741823)
|
||||
"constraint_5" CHECK ("time" >= 'Fri Mar 24 17:00:00 2017 PDT'::timestamp with time zone AND "time" < 'Sun Apr 23 17:00:00 2017 PDT'::timestamp with time zone)
|
||||
Inherits: index_test
|
||||
|
||||
@ -381,7 +381,7 @@ Indexes:
|
||||
"_hyper_4_3_chunk_time_temp_idx" btree ("time", temp)
|
||||
Check constraints:
|
||||
"constraint_3" CHECK ("time" >= 'Sat Dec 24 16:00:00 2016 PST'::timestamp with time zone AND "time" < 'Mon Jan 23 16:00:00 2017 PST'::timestamp with time zone)
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_for_key(device::text) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(device::text) < 2147483647)
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_hash(device) >= 0 AND _timescaledb_internal.get_partition_hash(device) < 1073741823)
|
||||
Inherits: index_test
|
||||
|
||||
Table "_timescaledb_internal._hyper_4_4_chunk"
|
||||
@ -396,7 +396,7 @@ Indexes:
|
||||
"_hyper_4_4_chunk_index_test_device_time_idx" btree (device, "time" DESC)
|
||||
"_hyper_4_4_chunk_index_test_time_temp_idx" btree ("time", temp)
|
||||
Check constraints:
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_for_key(device::text) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(device::text) < 2147483647)
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_hash(device) >= 0 AND _timescaledb_internal.get_partition_hash(device) < 1073741823)
|
||||
"constraint_5" CHECK ("time" >= 'Fri Mar 24 17:00:00 2017 PDT'::timestamp with time zone AND "time" < 'Sun Apr 23 17:00:00 2017 PDT'::timestamp with time zone)
|
||||
Inherits: index_test
|
||||
|
||||
@ -444,7 +444,7 @@ Indexes:
|
||||
"_hyper_4_3_chunk_time_temp_idx" btree ("time", temp)
|
||||
Check constraints:
|
||||
"constraint_3" CHECK ("time" >= 'Sat Dec 24 16:00:00 2016 PST'::timestamp with time zone AND "time" < 'Mon Jan 23 16:00:00 2017 PST'::timestamp with time zone)
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_for_key(device::text) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(device::text) < 2147483647)
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_hash(device) >= 0 AND _timescaledb_internal.get_partition_hash(device) < 1073741823)
|
||||
Inherits: index_test
|
||||
|
||||
Index "_timescaledb_internal._hyper_4_3_chunk_index_test_device_time_idx"
|
||||
@ -479,7 +479,7 @@ Indexes:
|
||||
"_hyper_4_4_chunk_index_test_time_idx" btree ("time"), tablespace "tablespace1"
|
||||
"_hyper_4_4_chunk_index_test_time_temp_idx" btree ("time", temp)
|
||||
Check constraints:
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_for_key(device::text) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(device::text) < 2147483647)
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_hash(device) >= 0 AND _timescaledb_internal.get_partition_hash(device) < 1073741823)
|
||||
"constraint_5" CHECK ("time" >= 'Fri Mar 24 17:00:00 2017 PDT'::timestamp with time zone AND "time" < 'Sun Apr 23 17:00:00 2017 PDT'::timestamp with time zone)
|
||||
Inherits: index_test
|
||||
|
||||
@ -535,7 +535,7 @@ Indexes:
|
||||
"_hyper_4_3_chunk_time_temp_idx" btree ("time", temp)
|
||||
Check constraints:
|
||||
"constraint_3" CHECK ("time" >= 'Sat Dec 24 16:00:00 2016 PST'::timestamp with time zone AND "time" < 'Mon Jan 23 16:00:00 2017 PST'::timestamp with time zone)
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_for_key(device::text) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(device::text) < 2147483647)
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_hash(device) >= 0 AND _timescaledb_internal.get_partition_hash(device) < 1073741823)
|
||||
Inherits: index_test
|
||||
|
||||
Table "_timescaledb_internal._hyper_4_4_chunk"
|
||||
@ -549,7 +549,7 @@ Indexes:
|
||||
"_hyper_4_4_chunk_index_test_time_idx" btree ("time"), tablespace "tablespace2"
|
||||
"_hyper_4_4_chunk_index_test_time_temp_idx" btree ("time", temp)
|
||||
Check constraints:
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_for_key(device::text) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(device::text) < 2147483647)
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_hash(device) >= 0 AND _timescaledb_internal.get_partition_hash(device) < 1073741823)
|
||||
"constraint_5" CHECK ("time" >= 'Fri Mar 24 17:00:00 2017 PDT'::timestamp with time zone AND "time" < 'Sun Apr 23 17:00:00 2017 PDT'::timestamp with time zone)
|
||||
Inherits: index_test
|
||||
|
||||
@ -584,7 +584,7 @@ Indexes:
|
||||
"_hyper_4_3_chunk_time_temp_idx" btree ("time", temp)
|
||||
Check constraints:
|
||||
"constraint_3" CHECK ("time" >= 'Sat Dec 24 16:00:00 2016 PST'::timestamp with time zone AND "time" < 'Mon Jan 23 16:00:00 2017 PST'::timestamp with time zone)
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_for_key(device::text) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(device::text) < 2147483647)
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_hash(device) >= 0 AND _timescaledb_internal.get_partition_hash(device) < 1073741823)
|
||||
Inherits: index_test
|
||||
|
||||
Table "_timescaledb_internal._hyper_4_4_chunk"
|
||||
@ -599,7 +599,7 @@ Indexes:
|
||||
"_hyper_4_4_chunk_index_test_time_idx" btree ("time"), tablespace "tablespace2"
|
||||
"_hyper_4_4_chunk_index_test_time_temp_idx" btree ("time", temp)
|
||||
Check constraints:
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_for_key(device::text) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(device::text) < 2147483647)
|
||||
"constraint_4" CHECK (_timescaledb_internal.get_partition_hash(device) >= 0 AND _timescaledb_internal.get_partition_hash(device) < 1073741823)
|
||||
"constraint_5" CHECK ("time" >= 'Fri Mar 24 17:00:00 2017 PDT'::timestamp with time zone AND "time" < 'Sun Apr 23 17:00:00 2017 PDT'::timestamp with time zone)
|
||||
Inherits: index_test
|
||||
|
||||
|
@ -57,7 +57,7 @@ Indexes:
|
||||
"_hyper_1_1_chunk_two_Partitions_timeCustom_series_bool_idx" btree ("timeCustom" DESC NULLS LAST, series_bool) WHERE series_bool IS NOT NULL
|
||||
Check constraints:
|
||||
"constraint_1" CHECK ("timeCustom" >= '1257892416000000000'::bigint AND "timeCustom" < '1257895008000000000'::bigint)
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_for_key(device_id) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(device_id) < 2147483647)
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_hash(device_id) >= 1073741823 AND _timescaledb_internal.get_partition_hash(device_id) < 2147483647)
|
||||
Inherits: "two_Partitions"
|
||||
|
||||
Index "_timescaledb_internal._hyper_1_1_chunk_two_Partitions_device_id_timeCustom_idx"
|
||||
@ -126,7 +126,7 @@ Indexes:
|
||||
"_hyper_1_2_chunk_two_Partitions_timeCustom_series_2_idx" btree ("timeCustom" DESC NULLS LAST, series_2) WHERE series_2 IS NOT NULL
|
||||
"_hyper_1_2_chunk_two_Partitions_timeCustom_series_bool_idx" btree ("timeCustom" DESC NULLS LAST, series_bool) WHERE series_bool IS NOT NULL
|
||||
Check constraints:
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_for_key(device_id) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(device_id) < 2147483647)
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_hash(device_id) >= 1073741823 AND _timescaledb_internal.get_partition_hash(device_id) < 2147483647)
|
||||
"constraint_3" CHECK ("timeCustom" >= '1257897600000000000'::bigint AND "timeCustom" < '1257900192000000000'::bigint)
|
||||
Inherits: "two_Partitions"
|
||||
|
||||
@ -196,7 +196,7 @@ Indexes:
|
||||
"_hyper_1_3_chunk_two_Partitions_timeCustom_series_2_idx" btree ("timeCustom" DESC NULLS LAST, series_2) WHERE series_2 IS NOT NULL
|
||||
"_hyper_1_3_chunk_two_Partitions_timeCustom_series_bool_idx" btree ("timeCustom" DESC NULLS LAST, series_bool) WHERE series_bool IS NOT NULL
|
||||
Check constraints:
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_for_key(device_id) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(device_id) < 2147483647)
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_hash(device_id) >= 1073741823 AND _timescaledb_internal.get_partition_hash(device_id) < 2147483647)
|
||||
"constraint_4" CHECK ("timeCustom" >= '1257985728000000000'::bigint AND "timeCustom" < '1257988320000000000'::bigint)
|
||||
Inherits: "two_Partitions"
|
||||
|
||||
@ -267,7 +267,7 @@ Indexes:
|
||||
"_hyper_1_4_chunk_two_Partitions_timeCustom_series_bool_idx" btree ("timeCustom" DESC NULLS LAST, series_bool) WHERE series_bool IS NOT NULL
|
||||
Check constraints:
|
||||
"constraint_1" CHECK ("timeCustom" >= '1257892416000000000'::bigint AND "timeCustom" < '1257895008000000000'::bigint)
|
||||
"constraint_5" CHECK (_timescaledb_internal.get_partition_for_key(device_id) >= 0 AND _timescaledb_internal.get_partition_for_key(device_id) < 1073741823)
|
||||
"constraint_5" CHECK (_timescaledb_internal.get_partition_hash(device_id) >= 0 AND _timescaledb_internal.get_partition_hash(device_id) < 1073741823)
|
||||
Inherits: "two_Partitions"
|
||||
|
||||
Index "_timescaledb_internal._hyper_1_4_chunk_two_Partitions_device_id_timeCustom_idx"
|
||||
|
@ -426,8 +426,8 @@ Indexes:
|
||||
"_hyper_7_15_chunk_3dim_time_idx" btree ("time" DESC)
|
||||
Check constraints:
|
||||
"constraint_15" CHECK ("time" >= 'Sat Dec 24 16:00:00 2016'::timestamp without time zone AND "time" < 'Mon Jan 23 16:00:00 2017'::timestamp without time zone)
|
||||
"constraint_16" CHECK (_timescaledb_internal.get_partition_for_key(device) >= 0 AND _timescaledb_internal.get_partition_for_key(device) < 1073741823)
|
||||
"constraint_17" CHECK (_timescaledb_internal.get_partition_for_key(location) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(location) < 2147483647)
|
||||
"constraint_16" CHECK (_timescaledb_internal.get_partition_hash(device) >= 0 AND _timescaledb_internal.get_partition_hash(device) < 1073741823)
|
||||
"constraint_17" CHECK (_timescaledb_internal.get_partition_hash(location) >= 1073741823 AND _timescaledb_internal.get_partition_hash(location) < 2147483647)
|
||||
Inherits: "3dim"
|
||||
|
||||
--queries should work in three dimensions
|
||||
|
166
test/expected/partitioning.out
Normal file
166
test/expected/partitioning.out
Normal file
@ -0,0 +1,166 @@
|
||||
CREATE TABLE part_legacy(time timestamptz, temp float, device int);
|
||||
SELECT create_hypertable('part_legacy', 'time', 'device', 2);
|
||||
create_hypertable
|
||||
-------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM _timescaledb_catalog.dimension;
|
||||
id | hypertable_id | column_name | column_type | aligned | num_slices | partitioning_func_schema | partitioning_func | interval_length
|
||||
----+---------------+-------------+--------------------------+---------+------------+--------------------------+--------------------+-----------------
|
||||
1 | 1 | time | timestamp with time zone | t | | | | 2592000000000
|
||||
2 | 1 | device | integer | f | 2 | _timescaledb_internal | get_partition_hash |
|
||||
(2 rows)
|
||||
|
||||
\c single :ROLE_SUPERUSER
|
||||
UPDATE _timescaledb_catalog.dimension SET partitioning_func = 'get_partition_for_key'
|
||||
WHERE partitioning_func IS NOT NULL;
|
||||
\c single :ROLE_DEFAULT_PERM_USER
|
||||
-- Show updated partitioning function
|
||||
SELECT * FROM _timescaledb_catalog.dimension;
|
||||
id | hypertable_id | column_name | column_type | aligned | num_slices | partitioning_func_schema | partitioning_func | interval_length
|
||||
----+---------------+-------------+--------------------------+---------+------------+--------------------------+-----------------------+-----------------
|
||||
1 | 1 | time | timestamp with time zone | t | | | | 2592000000000
|
||||
2 | 1 | device | integer | f | 2 | _timescaledb_internal | get_partition_for_key |
|
||||
(2 rows)
|
||||
|
||||
INSERT INTO part_legacy VALUES ('2017-03-22T09:18:23', 23.4, 1);
|
||||
INSERT INTO part_legacy VALUES ('2017-03-22T09:18:23', 23.4, 76);
|
||||
VACUUM part_legacy;
|
||||
-- Show two chunks and CHECK constraint with cast
|
||||
\d+ _timescaledb_internal._hyper_1_*_chunk
|
||||
Table "_timescaledb_internal._hyper_1_1_chunk"
|
||||
Column | Type | Modifiers | Storage | Stats target | Description
|
||||
--------+--------------------------+-----------+---------+--------------+-------------
|
||||
time | timestamp with time zone | | plain | |
|
||||
temp | double precision | | plain | |
|
||||
device | integer | | plain | |
|
||||
Indexes:
|
||||
"_hyper_1_1_chunk_part_legacy_device_time_idx" btree (device, "time" DESC)
|
||||
"_hyper_1_1_chunk_part_legacy_time_idx" btree ("time" DESC)
|
||||
Check constraints:
|
||||
"constraint_1" CHECK ("time" >= 'Wed Feb 22 16:00:00 2017 PST'::timestamp with time zone AND "time" < 'Fri Mar 24 17:00:00 2017 PDT'::timestamp with time zone)
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_for_key(device::text) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(device::text) < 2147483647)
|
||||
Inherits: part_legacy
|
||||
|
||||
Table "_timescaledb_internal._hyper_1_2_chunk"
|
||||
Column | Type | Modifiers | Storage | Stats target | Description
|
||||
--------+--------------------------+-----------+---------+--------------+-------------
|
||||
time | timestamp with time zone | | plain | |
|
||||
temp | double precision | | plain | |
|
||||
device | integer | | plain | |
|
||||
Indexes:
|
||||
"_hyper_1_2_chunk_part_legacy_device_time_idx" btree (device, "time" DESC)
|
||||
"_hyper_1_2_chunk_part_legacy_time_idx" btree ("time" DESC)
|
||||
Check constraints:
|
||||
"constraint_1" CHECK ("time" >= 'Wed Feb 22 16:00:00 2017 PST'::timestamp with time zone AND "time" < 'Fri Mar 24 17:00:00 2017 PDT'::timestamp with time zone)
|
||||
"constraint_3" CHECK (_timescaledb_internal.get_partition_for_key(device::text) >= 0 AND _timescaledb_internal.get_partition_for_key(device::text) < 1073741823)
|
||||
Inherits: part_legacy
|
||||
|
||||
-- Make sure constraint exclusion works on device column
|
||||
EXPLAIN (verbose, costs off)
|
||||
SELECT * FROM part_legacy WHERE device = 1;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Append
|
||||
-> Seq Scan on public.part_legacy
|
||||
Output: part_legacy."time", part_legacy.temp, part_legacy.device
|
||||
Filter: ((part_legacy.device = 1) AND (_timescaledb_internal.get_partition_for_key((part_legacy.device)::text) = 1516350201))
|
||||
-> Seq Scan on _timescaledb_internal._hyper_1_1_chunk
|
||||
Output: _hyper_1_1_chunk."time", _hyper_1_1_chunk.temp, _hyper_1_1_chunk.device
|
||||
Filter: ((_hyper_1_1_chunk.device = 1) AND (_timescaledb_internal.get_partition_for_key((_hyper_1_1_chunk.device)::text) = 1516350201))
|
||||
(7 rows)
|
||||
|
||||
CREATE TABLE part_new(time timestamptz, temp float, device int);
|
||||
SELECT create_hypertable('part_new', 'time', 'device', 2);
|
||||
create_hypertable
|
||||
-------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM _timescaledb_catalog.dimension;
|
||||
id | hypertable_id | column_name | column_type | aligned | num_slices | partitioning_func_schema | partitioning_func | interval_length
|
||||
----+---------------+-------------+--------------------------+---------+------------+--------------------------+-----------------------+-----------------
|
||||
1 | 1 | time | timestamp with time zone | t | | | | 2592000000000
|
||||
2 | 1 | device | integer | f | 2 | _timescaledb_internal | get_partition_for_key |
|
||||
3 | 2 | time | timestamp with time zone | t | | | | 2592000000000
|
||||
4 | 2 | device | integer | f | 2 | _timescaledb_internal | get_partition_hash |
|
||||
(4 rows)
|
||||
|
||||
INSERT INTO part_new VALUES ('2017-03-22T09:18:23', 23.4, 1);
|
||||
INSERT INTO part_new VALUES ('2017-03-22T09:18:23', 23.4, 2);
|
||||
VACUUM part_new;
|
||||
-- Show two chunks and CHECK constraint without cast
|
||||
\d+ _timescaledb_internal._hyper_2_*_chunk
|
||||
Table "_timescaledb_internal._hyper_2_3_chunk"
|
||||
Column | Type | Modifiers | Storage | Stats target | Description
|
||||
--------+--------------------------+-----------+---------+--------------+-------------
|
||||
time | timestamp with time zone | | plain | |
|
||||
temp | double precision | | plain | |
|
||||
device | integer | | plain | |
|
||||
Indexes:
|
||||
"_hyper_2_3_chunk_part_new_device_time_idx" btree (device, "time" DESC)
|
||||
"_hyper_2_3_chunk_part_new_time_idx" btree ("time" DESC)
|
||||
Check constraints:
|
||||
"constraint_4" CHECK ("time" >= 'Wed Feb 22 16:00:00 2017 PST'::timestamp with time zone AND "time" < 'Fri Mar 24 17:00:00 2017 PDT'::timestamp with time zone)
|
||||
"constraint_5" CHECK (_timescaledb_internal.get_partition_hash(device) >= 0 AND _timescaledb_internal.get_partition_hash(device) < 1073741823)
|
||||
Inherits: part_new
|
||||
|
||||
Table "_timescaledb_internal._hyper_2_4_chunk"
|
||||
Column | Type | Modifiers | Storage | Stats target | Description
|
||||
--------+--------------------------+-----------+---------+--------------+-------------
|
||||
time | timestamp with time zone | | plain | |
|
||||
temp | double precision | | plain | |
|
||||
device | integer | | plain | |
|
||||
Indexes:
|
||||
"_hyper_2_4_chunk_part_new_device_time_idx" btree (device, "time" DESC)
|
||||
"_hyper_2_4_chunk_part_new_time_idx" btree ("time" DESC)
|
||||
Check constraints:
|
||||
"constraint_4" CHECK ("time" >= 'Wed Feb 22 16:00:00 2017 PST'::timestamp with time zone AND "time" < 'Fri Mar 24 17:00:00 2017 PDT'::timestamp with time zone)
|
||||
"constraint_6" CHECK (_timescaledb_internal.get_partition_hash(device) >= 1073741823 AND _timescaledb_internal.get_partition_hash(device) < 2147483647)
|
||||
Inherits: part_new
|
||||
|
||||
-- Make sure constraint exclusion works on device column
|
||||
EXPLAIN (verbose, costs off)
|
||||
SELECT * FROM part_new WHERE device = 1;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------------------------------------------------------------------------------------------
|
||||
Append
|
||||
-> Seq Scan on public.part_new
|
||||
Output: part_new."time", part_new.temp, part_new.device
|
||||
Filter: ((part_new.device = 1) AND (_timescaledb_internal.get_partition_hash(part_new.device) = 242423622))
|
||||
-> Seq Scan on _timescaledb_internal._hyper_2_3_chunk
|
||||
Output: _hyper_2_3_chunk."time", _hyper_2_3_chunk.temp, _hyper_2_3_chunk.device
|
||||
Filter: ((_hyper_2_3_chunk.device = 1) AND (_timescaledb_internal.get_partition_hash(_hyper_2_3_chunk.device) = 242423622))
|
||||
(7 rows)
|
||||
|
||||
CREATE TABLE part_new_convert1(time timestamptz, temp float8, device int);
|
||||
SELECT create_hypertable('part_new_convert1', 'time', 'temp', 2);
|
||||
create_hypertable
|
||||
-------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
INSERT INTO part_new_convert1 VALUES ('2017-03-22T09:18:23', 1.0, 2);
|
||||
\set ON_ERROR_STOP 0
|
||||
-- Changing the type of a hash-partitioned column should be unsupported
|
||||
ALTER TABLE part_new_convert1 ALTER COLUMN temp TYPE numeric;
|
||||
ERROR: Cannot change the type of a hash-partitioned column
|
||||
\set ON_ERROR_STOP 1
|
||||
-- Should be able to change if not hash partitioned though
|
||||
ALTER TABLE part_new_convert1 ALTER COLUMN time TYPE timestamp;
|
||||
\d+ _timescaledb_internal._hyper_3_*_chunk
|
||||
Table "_timescaledb_internal._hyper_3_5_chunk"
|
||||
Column | Type | Modifiers | Storage | Stats target | Description
|
||||
--------+-----------------------------+-----------+---------+--------------+-------------
|
||||
time | timestamp without time zone | | plain | |
|
||||
temp | double precision | | plain | |
|
||||
device | integer | | plain | |
|
||||
Indexes:
|
||||
"_hyper_3_5_chunk_part_new_convert1_temp_time_idx" btree (temp, "time" DESC)
|
||||
"_hyper_3_5_chunk_part_new_convert1_time_idx" btree ("time" DESC)
|
||||
Check constraints:
|
||||
"constraint_7" CHECK ("time" >= 'Wed Feb 22 16:00:00 2017'::timestamp without time zone AND "time" < 'Fri Mar 24 17:00:00 2017'::timestamp without time zone)
|
||||
"constraint_8" CHECK (_timescaledb_internal.get_partition_hash(temp) >= 0 AND _timescaledb_internal.get_partition_hash(temp) < 1073741823)
|
||||
Inherits: part_new_convert1
|
||||
|
@ -49,7 +49,7 @@ SELECT count(*)
|
||||
AND refobjid = (SELECT oid FROM pg_extension WHERE extname = 'timescaledb');
|
||||
count
|
||||
-------
|
||||
110
|
||||
111
|
||||
(1 row)
|
||||
|
||||
\d+ public."two_Partitions"
|
||||
@ -99,7 +99,7 @@ Indexes:
|
||||
"_hyper_1_1_chunk_two_Partitions_timeCustom_series_bool_idx" btree ("timeCustom" DESC NULLS LAST, series_bool) WHERE series_bool IS NOT NULL
|
||||
Check constraints:
|
||||
"constraint_1" CHECK ("timeCustom" >= '1257892416000000000'::bigint AND "timeCustom" < '1257895008000000000'::bigint)
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_for_key(device_id) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(device_id) < 2147483647)
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_hash(device_id) >= 1073741823 AND _timescaledb_internal.get_partition_hash(device_id) < 2147483647)
|
||||
Triggers:
|
||||
restore_trigger BEFORE INSERT ON _timescaledb_internal._hyper_1_1_chunk FOR EACH ROW EXECUTE PROCEDURE test_trigger()
|
||||
Inherits: "two_Partitions"
|
||||
@ -213,7 +213,7 @@ SELECT count(*)
|
||||
AND refobjid = (SELECT oid FROM pg_extension WHERE extname = 'timescaledb');
|
||||
count
|
||||
-------
|
||||
110
|
||||
111
|
||||
(1 row)
|
||||
|
||||
--main table and chunk schemas should be the same
|
||||
@ -264,7 +264,7 @@ Indexes:
|
||||
"_hyper_1_1_chunk_two_Partitions_timeCustom_series_bool_idx" btree ("timeCustom" DESC NULLS LAST, series_bool) WHERE series_bool IS NOT NULL
|
||||
Check constraints:
|
||||
"constraint_1" CHECK ("timeCustom" >= '1257892416000000000'::bigint AND "timeCustom" < '1257895008000000000'::bigint)
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_for_key(device_id) >= 1073741823 AND _timescaledb_internal.get_partition_for_key(device_id) < 2147483647)
|
||||
"constraint_2" CHECK (_timescaledb_internal.get_partition_hash(device_id) >= 1073741823 AND _timescaledb_internal.get_partition_hash(device_id) < 2147483647)
|
||||
Triggers:
|
||||
restore_trigger BEFORE INSERT ON _timescaledb_internal._hyper_1_1_chunk FOR EACH ROW EXECUTE PROCEDURE test_trigger()
|
||||
Inherits: "two_Partitions"
|
||||
|
@ -51,20 +51,20 @@ SELECT * FROM hypertable_relation_size_pretty('"public"."two_Partitions"');
|
||||
|
||||
SELECT * FROM chunk_relation_size('"public"."two_Partitions"');
|
||||
chunk_id | chunk_table | partitioning_columns | partitioning_column_types | partitioning_hash_functions | ranges | table_bytes | index_bytes | toast_bytes | total_bytes
|
||||
----------+--------------------------------------------+------------------------+---------------------------+----------------------------------------------------+-------------------------------------------------------------------------+-------------+-------------+-------------+-------------
|
||||
1 | "_timescaledb_internal"."_hyper_1_1_chunk" | {timeCustom,device_id} | {bigint,text} | {NULL,_timescaledb_internal.get_partition_for_key} | {"[1257892416000000000,1257895008000000000)","[1073741823,2147483647)"} | 8192 | 114688 | 8192 | 131072
|
||||
2 | "_timescaledb_internal"."_hyper_1_2_chunk" | {timeCustom,device_id} | {bigint,text} | {NULL,_timescaledb_internal.get_partition_for_key} | {"[1257897600000000000,1257900192000000000)","[1073741823,2147483647)"} | 8192 | 106496 | 8192 | 122880
|
||||
3 | "_timescaledb_internal"."_hyper_1_3_chunk" | {timeCustom,device_id} | {bigint,text} | {NULL,_timescaledb_internal.get_partition_for_key} | {"[1257985728000000000,1257988320000000000)","[1073741823,2147483647)"} | 8192 | 98304 | 8192 | 114688
|
||||
4 | "_timescaledb_internal"."_hyper_1_4_chunk" | {timeCustom,device_id} | {bigint,text} | {NULL,_timescaledb_internal.get_partition_for_key} | {"[1257892416000000000,1257895008000000000)","[0,1073741823)"} | 8192 | 98304 | 8192 | 114688
|
||||
----------+--------------------------------------------+------------------------+---------------------------+-------------------------------------------------+-------------------------------------------------------------------------+-------------+-------------+-------------+-------------
|
||||
1 | "_timescaledb_internal"."_hyper_1_1_chunk" | {timeCustom,device_id} | {bigint,text} | {NULL,_timescaledb_internal.get_partition_hash} | {"[1257892416000000000,1257895008000000000)","[1073741823,2147483647)"} | 8192 | 114688 | 8192 | 131072
|
||||
2 | "_timescaledb_internal"."_hyper_1_2_chunk" | {timeCustom,device_id} | {bigint,text} | {NULL,_timescaledb_internal.get_partition_hash} | {"[1257897600000000000,1257900192000000000)","[1073741823,2147483647)"} | 8192 | 106496 | 8192 | 122880
|
||||
3 | "_timescaledb_internal"."_hyper_1_3_chunk" | {timeCustom,device_id} | {bigint,text} | {NULL,_timescaledb_internal.get_partition_hash} | {"[1257985728000000000,1257988320000000000)","[1073741823,2147483647)"} | 8192 | 98304 | 8192 | 114688
|
||||
4 | "_timescaledb_internal"."_hyper_1_4_chunk" | {timeCustom,device_id} | {bigint,text} | {NULL,_timescaledb_internal.get_partition_hash} | {"[1257892416000000000,1257895008000000000)","[0,1073741823)"} | 8192 | 98304 | 8192 | 114688
|
||||
(4 rows)
|
||||
|
||||
SELECT * FROM chunk_relation_size_pretty('"public"."two_Partitions"');
|
||||
chunk_id | chunk_table | partitioning_columns | partitioning_column_types | partitioning_hash_functions | ranges | table_size | index_size | toast_size | total_size
|
||||
----------+--------------------------------------------+------------------------+---------------------------+----------------------------------------------------+-----------------------------------------------------------------------------+------------+------------+------------+------------
|
||||
1 | "_timescaledb_internal"."_hyper_1_1_chunk" | {timeCustom,device_id} | {bigint,text} | {NULL,_timescaledb_internal.get_partition_for_key} | {"['1257892416000000000','1257895008000000000')","[1073741823,2147483647)"} | 8192 bytes | 112 kB | 8192 bytes | 128 kB
|
||||
2 | "_timescaledb_internal"."_hyper_1_2_chunk" | {timeCustom,device_id} | {bigint,text} | {NULL,_timescaledb_internal.get_partition_for_key} | {"['1257897600000000000','1257900192000000000')","[1073741823,2147483647)"} | 8192 bytes | 104 kB | 8192 bytes | 120 kB
|
||||
3 | "_timescaledb_internal"."_hyper_1_3_chunk" | {timeCustom,device_id} | {bigint,text} | {NULL,_timescaledb_internal.get_partition_for_key} | {"['1257985728000000000','1257988320000000000')","[1073741823,2147483647)"} | 8192 bytes | 96 kB | 8192 bytes | 112 kB
|
||||
4 | "_timescaledb_internal"."_hyper_1_4_chunk" | {timeCustom,device_id} | {bigint,text} | {NULL,_timescaledb_internal.get_partition_for_key} | {"['1257892416000000000','1257895008000000000')","[0,1073741823)"} | 8192 bytes | 96 kB | 8192 bytes | 112 kB
|
||||
----------+--------------------------------------------+------------------------+---------------------------+-------------------------------------------------+-----------------------------------------------------------------------------+------------+------------+------------+------------
|
||||
1 | "_timescaledb_internal"."_hyper_1_1_chunk" | {timeCustom,device_id} | {bigint,text} | {NULL,_timescaledb_internal.get_partition_hash} | {"['1257892416000000000','1257895008000000000')","[1073741823,2147483647)"} | 8192 bytes | 112 kB | 8192 bytes | 128 kB
|
||||
2 | "_timescaledb_internal"."_hyper_1_2_chunk" | {timeCustom,device_id} | {bigint,text} | {NULL,_timescaledb_internal.get_partition_hash} | {"['1257897600000000000','1257900192000000000')","[1073741823,2147483647)"} | 8192 bytes | 104 kB | 8192 bytes | 120 kB
|
||||
3 | "_timescaledb_internal"."_hyper_1_3_chunk" | {timeCustom,device_id} | {bigint,text} | {NULL,_timescaledb_internal.get_partition_hash} | {"['1257985728000000000','1257988320000000000')","[1073741823,2147483647)"} | 8192 bytes | 96 kB | 8192 bytes | 112 kB
|
||||
4 | "_timescaledb_internal"."_hyper_1_4_chunk" | {timeCustom,device_id} | {bigint,text} | {NULL,_timescaledb_internal.get_partition_hash} | {"['1257892416000000000','1257895008000000000')","[0,1073741823)"} | 8192 bytes | 96 kB | 8192 bytes | 112 kB
|
||||
(4 rows)
|
||||
|
||||
SELECT * FROM indexes_relation_size('"public"."two_Partitions"');
|
||||
@ -102,16 +102,16 @@ INSERT INTO timestamp_partitioned VALUES('2004-10-19 10:23:54', '10');
|
||||
INSERT INTO timestamp_partitioned VALUES('2004-12-19 10:23:54', '30');
|
||||
SELECT * FROM chunk_relation_size('timestamp_partitioned');
|
||||
chunk_id | chunk_table | partitioning_columns | partitioning_column_types | partitioning_hash_functions | ranges | table_bytes | index_bytes | toast_bytes | total_bytes
|
||||
----------+--------------------------------------------+----------------------+--------------------------------------+----------------------------------------------------+-------------------------------------------------------------------+-------------+-------------+-------------+-------------
|
||||
5 | "_timescaledb_internal"."_hyper_2_5_chunk" | {time,value} | {"timestamp without time zone",text} | {NULL,_timescaledb_internal.get_partition_for_key} | {"[1096416000000000,1099008000000000)","[1073741823,2147483647)"} | 8192 | 32768 | 8192 | 49152
|
||||
6 | "_timescaledb_internal"."_hyper_2_6_chunk" | {time,value} | {"timestamp without time zone",text} | {NULL,_timescaledb_internal.get_partition_for_key} | {"[1101600000000000,1104192000000000)","[1073741823,2147483647)"} | 8192 | 32768 | 8192 | 49152
|
||||
----------+--------------------------------------------+----------------------+--------------------------------------+-------------------------------------------------+-------------------------------------------------------------------+-------------+-------------+-------------+-------------
|
||||
5 | "_timescaledb_internal"."_hyper_2_5_chunk" | {time,value} | {"timestamp without time zone",text} | {NULL,_timescaledb_internal.get_partition_hash} | {"[1096416000000000,1099008000000000)","[1073741823,2147483647)"} | 8192 | 32768 | 8192 | 49152
|
||||
6 | "_timescaledb_internal"."_hyper_2_6_chunk" | {time,value} | {"timestamp without time zone",text} | {NULL,_timescaledb_internal.get_partition_hash} | {"[1101600000000000,1104192000000000)","[1073741823,2147483647)"} | 8192 | 32768 | 8192 | 49152
|
||||
(2 rows)
|
||||
|
||||
SELECT * FROM chunk_relation_size_pretty('timestamp_partitioned');
|
||||
chunk_id | chunk_table | partitioning_columns | partitioning_column_types | partitioning_hash_functions | ranges | table_size | index_size | toast_size | total_size
|
||||
----------+--------------------------------------------+----------------------+--------------------------------------+----------------------------------------------------+-----------------------------------------------------------------------------------------------+------------+------------+------------+------------
|
||||
5 | "_timescaledb_internal"."_hyper_2_5_chunk" | {time,value} | {"timestamp without time zone",text} | {NULL,_timescaledb_internal.get_partition_for_key} | {"['Tue Sep 28 17:00:00 2004 PDT','Thu Oct 28 17:00:00 2004 PDT')","[1073741823,2147483647)"} | 8192 bytes | 32 kB | 8192 bytes | 48 kB
|
||||
6 | "_timescaledb_internal"."_hyper_2_6_chunk" | {time,value} | {"timestamp without time zone",text} | {NULL,_timescaledb_internal.get_partition_for_key} | {"['Sat Nov 27 16:00:00 2004 PST','Mon Dec 27 16:00:00 2004 PST')","[1073741823,2147483647)"} | 8192 bytes | 32 kB | 8192 bytes | 48 kB
|
||||
----------+--------------------------------------------+----------------------+--------------------------------------+-------------------------------------------------+-----------------------------------------------------------------------------------------------+------------+------------+------------+------------
|
||||
5 | "_timescaledb_internal"."_hyper_2_5_chunk" | {time,value} | {"timestamp without time zone",text} | {NULL,_timescaledb_internal.get_partition_hash} | {"['Tue Sep 28 17:00:00 2004 PDT','Thu Oct 28 17:00:00 2004 PDT')","[1073741823,2147483647)"} | 8192 bytes | 32 kB | 8192 bytes | 48 kB
|
||||
6 | "_timescaledb_internal"."_hyper_2_6_chunk" | {time,value} | {"timestamp without time zone",text} | {NULL,_timescaledb_internal.get_partition_hash} | {"['Sat Nov 27 16:00:00 2004 PST','Mon Dec 27 16:00:00 2004 PST')","[1073741823,2147483647)"} | 8192 bytes | 32 kB | 8192 bytes | 48 kB
|
||||
(2 rows)
|
||||
|
||||
CREATE TABLE timestamp_partitioned_2(time TIMESTAMP, value CHAR(9));
|
||||
@ -125,15 +125,15 @@ INSERT INTO timestamp_partitioned_2 VALUES('2004-10-19 10:23:54', '10');
|
||||
INSERT INTO timestamp_partitioned_2 VALUES('2004-12-19 10:23:54', '30');
|
||||
SELECT * FROM chunk_relation_size('timestamp_partitioned_2');
|
||||
chunk_id | chunk_table | partitioning_columns | partitioning_column_types | partitioning_hash_functions | ranges | table_bytes | index_bytes | toast_bytes | total_bytes
|
||||
----------+--------------------------------------------+----------------------+-------------------------------------------+----------------------------------------------------+-------------------------------------------------------------------+-------------+-------------+-------------+-------------
|
||||
7 | "_timescaledb_internal"."_hyper_3_7_chunk" | {time,value} | {"timestamp without time zone",character} | {NULL,_timescaledb_internal.get_partition_for_key} | {"[1096416000000000,1099008000000000)","[1073741823,2147483647)"} | 8192 | 32768 | | 40960
|
||||
8 | "_timescaledb_internal"."_hyper_3_8_chunk" | {time,value} | {"timestamp without time zone",character} | {NULL,_timescaledb_internal.get_partition_for_key} | {"[1101600000000000,1104192000000000)","[1073741823,2147483647)"} | 8192 | 32768 | | 40960
|
||||
----------+--------------------------------------------+----------------------+-------------------------------------------+-------------------------------------------------+-------------------------------------------------------------------+-------------+-------------+-------------+-------------
|
||||
7 | "_timescaledb_internal"."_hyper_3_7_chunk" | {time,value} | {"timestamp without time zone",character} | {NULL,_timescaledb_internal.get_partition_hash} | {"[1096416000000000,1099008000000000)","[1073741823,2147483647)"} | 8192 | 32768 | | 40960
|
||||
8 | "_timescaledb_internal"."_hyper_3_8_chunk" | {time,value} | {"timestamp without time zone",character} | {NULL,_timescaledb_internal.get_partition_hash} | {"[1101600000000000,1104192000000000)","[1073741823,2147483647)"} | 8192 | 32768 | | 40960
|
||||
(2 rows)
|
||||
|
||||
SELECT * FROM chunk_relation_size_pretty('timestamp_partitioned_2');
|
||||
chunk_id | chunk_table | partitioning_columns | partitioning_column_types | partitioning_hash_functions | ranges | table_size | index_size | toast_size | total_size
|
||||
----------+--------------------------------------------+----------------------+-------------------------------------------+----------------------------------------------------+-----------------------------------------------------------------------------------------------+------------+------------+------------+------------
|
||||
7 | "_timescaledb_internal"."_hyper_3_7_chunk" | {time,value} | {"timestamp without time zone",character} | {NULL,_timescaledb_internal.get_partition_for_key} | {"['Tue Sep 28 17:00:00 2004 PDT','Thu Oct 28 17:00:00 2004 PDT')","[1073741823,2147483647)"} | 8192 bytes | 32 kB | | 40 kB
|
||||
8 | "_timescaledb_internal"."_hyper_3_8_chunk" | {time,value} | {"timestamp without time zone",character} | {NULL,_timescaledb_internal.get_partition_for_key} | {"['Sat Nov 27 16:00:00 2004 PST','Mon Dec 27 16:00:00 2004 PST')","[1073741823,2147483647)"} | 8192 bytes | 32 kB | | 40 kB
|
||||
----------+--------------------------------------------+----------------------+-------------------------------------------+-------------------------------------------------+-----------------------------------------------------------------------------------------------+------------+------------+------------+------------
|
||||
7 | "_timescaledb_internal"."_hyper_3_7_chunk" | {time,value} | {"timestamp without time zone",character} | {NULL,_timescaledb_internal.get_partition_hash} | {"['Tue Sep 28 17:00:00 2004 PDT','Thu Oct 28 17:00:00 2004 PDT')","[1073741823,2147483647)"} | 8192 bytes | 32 kB | | 40 kB
|
||||
8 | "_timescaledb_internal"."_hyper_3_8_chunk" | {time,value} | {"timestamp without time zone",character} | {NULL,_timescaledb_internal.get_partition_hash} | {"['Sat Nov 27 16:00:00 2004 PST','Mon Dec 27 16:00:00 2004 PST')","[1073741823,2147483647)"} | 8192 bytes | 32 kB | | 40 kB
|
||||
(2 rows)
|
||||
|
||||
|
@ -62,19 +62,19 @@ EXPLAIN (verbose ON, costs off) SELECT * FROM PUBLIC."two_Partitions";
|
||||
Output: _hyper_1_4_chunk."timeCustom", _hyper_1_4_chunk.device_id, _hyper_1_4_chunk.series_0, _hyper_1_4_chunk.series_1, _hyper_1_4_chunk.series_2, _hyper_1_4_chunk.series_bool
|
||||
(11 rows)
|
||||
|
||||
\echo "The following queries should NOT scan two_Partitions._hyper_1_1_0_partition"
|
||||
"The following queries should NOT scan two_Partitions._hyper_1_1_0_partition"
|
||||
\echo "The following queries should NOT scan two_Partitions._hyper_1_1_chunk"
|
||||
"The following queries should NOT scan two_Partitions._hyper_1_1_chunk"
|
||||
EXPLAIN (verbose ON, costs off) SELECT * FROM PUBLIC."two_Partitions" WHERE device_id = 'dev2';
|
||||
QUERY PLAN
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Append
|
||||
-> Seq Scan on public."two_Partitions"
|
||||
Output: "two_Partitions"."timeCustom", "two_Partitions".device_id, "two_Partitions".series_0, "two_Partitions".series_1, "two_Partitions".series_2, "two_Partitions".series_bool
|
||||
Filter: (("two_Partitions".device_id = 'dev2'::text) AND (_timescaledb_internal.get_partition_for_key("two_Partitions".device_id) = 405750566))
|
||||
Filter: (("two_Partitions".device_id = 'dev2'::text) AND (_timescaledb_internal.get_partition_hash("two_Partitions".device_id) = 405750566))
|
||||
-> Bitmap Heap Scan on _timescaledb_internal._hyper_1_4_chunk
|
||||
Output: _hyper_1_4_chunk."timeCustom", _hyper_1_4_chunk.device_id, _hyper_1_4_chunk.series_0, _hyper_1_4_chunk.series_1, _hyper_1_4_chunk.series_2, _hyper_1_4_chunk.series_bool
|
||||
Recheck Cond: (_hyper_1_4_chunk.device_id = 'dev2'::text)
|
||||
Filter: (_timescaledb_internal.get_partition_for_key(_hyper_1_4_chunk.device_id) = 405750566)
|
||||
Filter: (_timescaledb_internal.get_partition_hash(_hyper_1_4_chunk.device_id) = 405750566)
|
||||
-> Bitmap Index Scan on "_hyper_1_4_chunk_two_Partitions_device_id_timeCustom_idx"
|
||||
Index Cond: (_hyper_1_4_chunk.device_id = 'dev2'::text)
|
||||
(10 rows)
|
||||
@ -85,11 +85,11 @@ EXPLAIN (verbose ON, costs off) SELECT * FROM PUBLIC."two_Partitions" WHERE devi
|
||||
Append
|
||||
-> Seq Scan on public."two_Partitions"
|
||||
Output: "two_Partitions"."timeCustom", "two_Partitions".device_id, "two_Partitions".series_0, "two_Partitions".series_1, "two_Partitions".series_2, "two_Partitions".series_bool
|
||||
Filter: (("two_Partitions".device_id = 'dev2'::text) AND (_timescaledb_internal.get_partition_for_key("two_Partitions".device_id) = 405750566))
|
||||
Filter: (("two_Partitions".device_id = 'dev2'::text) AND (_timescaledb_internal.get_partition_hash("two_Partitions".device_id) = 405750566))
|
||||
-> Bitmap Heap Scan on _timescaledb_internal._hyper_1_4_chunk
|
||||
Output: _hyper_1_4_chunk."timeCustom", _hyper_1_4_chunk.device_id, _hyper_1_4_chunk.series_0, _hyper_1_4_chunk.series_1, _hyper_1_4_chunk.series_2, _hyper_1_4_chunk.series_bool
|
||||
Recheck Cond: (_hyper_1_4_chunk.device_id = 'dev2'::text)
|
||||
Filter: (_timescaledb_internal.get_partition_for_key(_hyper_1_4_chunk.device_id) = 405750566)
|
||||
Filter: (_timescaledb_internal.get_partition_hash(_hyper_1_4_chunk.device_id) = 405750566)
|
||||
-> Bitmap Index Scan on "_hyper_1_4_chunk_two_Partitions_device_id_timeCustom_idx"
|
||||
Index Cond: (_hyper_1_4_chunk.device_id = 'dev2'::text)
|
||||
(10 rows)
|
||||
@ -100,11 +100,11 @@ EXPLAIN (verbose ON, costs off) SELECT * FROM PUBLIC."two_Partitions" WHERE 'dev
|
||||
Append
|
||||
-> Seq Scan on public."two_Partitions"
|
||||
Output: "two_Partitions"."timeCustom", "two_Partitions".device_id, "two_Partitions".series_0, "two_Partitions".series_1, "two_Partitions".series_2, "two_Partitions".series_bool
|
||||
Filter: (('dev2'::text = "two_Partitions".device_id) AND (_timescaledb_internal.get_partition_for_key("two_Partitions".device_id) = 405750566))
|
||||
Filter: (('dev2'::text = "two_Partitions".device_id) AND (_timescaledb_internal.get_partition_hash("two_Partitions".device_id) = 405750566))
|
||||
-> Bitmap Heap Scan on _timescaledb_internal._hyper_1_4_chunk
|
||||
Output: _hyper_1_4_chunk."timeCustom", _hyper_1_4_chunk.device_id, _hyper_1_4_chunk.series_0, _hyper_1_4_chunk.series_1, _hyper_1_4_chunk.series_2, _hyper_1_4_chunk.series_bool
|
||||
Recheck Cond: ('dev2'::text = _hyper_1_4_chunk.device_id)
|
||||
Filter: (_timescaledb_internal.get_partition_for_key(_hyper_1_4_chunk.device_id) = 405750566)
|
||||
Filter: (_timescaledb_internal.get_partition_hash(_hyper_1_4_chunk.device_id) = 405750566)
|
||||
-> Bitmap Index Scan on "_hyper_1_4_chunk_two_Partitions_device_id_timeCustom_idx"
|
||||
Index Cond: ('dev2'::text = _hyper_1_4_chunk.device_id)
|
||||
(10 rows)
|
||||
@ -118,6 +118,37 @@ SELECT create_hypertable('"int_part"', 'time', 'object_id', 2);
|
||||
(1 row)
|
||||
|
||||
INSERT INTO "int_part" VALUES('2017-01-20T09:00:01', 1, 22.5);
|
||||
INSERT INTO "int_part" VALUES('2017-01-20T09:00:01', 2, 22.5);
|
||||
--check that there are two chunks
|
||||
\d _timescaledb_internal._hyper_2_*_chunk
|
||||
Table "_timescaledb_internal._hyper_2_5_chunk"
|
||||
Column | Type | Modifiers
|
||||
-----------+-----------------------------+-----------
|
||||
time | timestamp without time zone |
|
||||
object_id | integer |
|
||||
temp | double precision |
|
||||
Indexes:
|
||||
"_hyper_2_5_chunk_int_part_object_id_time_idx" btree (object_id, "time" DESC)
|
||||
"_hyper_2_5_chunk_int_part_time_idx" btree ("time" DESC)
|
||||
Check constraints:
|
||||
"constraint_6" CHECK ("time" >= 'Sat Dec 24 16:00:00 2016'::timestamp without time zone AND "time" < 'Mon Jan 23 16:00:00 2017'::timestamp without time zone)
|
||||
"constraint_7" CHECK (_timescaledb_internal.get_partition_hash(object_id) >= 0 AND _timescaledb_internal.get_partition_hash(object_id) < 1073741823)
|
||||
Inherits: int_part
|
||||
|
||||
Table "_timescaledb_internal._hyper_2_6_chunk"
|
||||
Column | Type | Modifiers
|
||||
-----------+-----------------------------+-----------
|
||||
time | timestamp without time zone |
|
||||
object_id | integer |
|
||||
temp | double precision |
|
||||
Indexes:
|
||||
"_hyper_2_6_chunk_int_part_object_id_time_idx" btree (object_id, "time" DESC)
|
||||
"_hyper_2_6_chunk_int_part_time_idx" btree ("time" DESC)
|
||||
Check constraints:
|
||||
"constraint_6" CHECK ("time" >= 'Sat Dec 24 16:00:00 2016'::timestamp without time zone AND "time" < 'Mon Jan 23 16:00:00 2017'::timestamp without time zone)
|
||||
"constraint_8" CHECK (_timescaledb_internal.get_partition_hash(object_id) >= 1073741823 AND _timescaledb_internal.get_partition_hash(object_id) < 2147483647)
|
||||
Inherits: int_part
|
||||
|
||||
SELECT * FROM "int_part" WHERE object_id = 1;
|
||||
time | object_id | temp
|
||||
--------------------------+-----------+------
|
||||
@ -127,15 +158,15 @@ SELECT * FROM "int_part" WHERE object_id = 1;
|
||||
--make sure this touches only one partititon
|
||||
EXPLAIN (verbose ON, costs off) SELECT * FROM "int_part" WHERE object_id = 1;
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------------------------------------------------------------------------
|
||||
---------------------------------------------------------------------------------------------------------------------------
|
||||
Append
|
||||
-> Seq Scan on public.int_part
|
||||
Output: int_part."time", int_part.object_id, int_part.temp
|
||||
Filter: ((int_part.object_id = 1) AND (_timescaledb_internal.get_partition_for_key((int_part.object_id)::text) = 1516350201))
|
||||
Filter: ((int_part.object_id = 1) AND (_timescaledb_internal.get_partition_hash(int_part.object_id) = 242423622))
|
||||
-> Bitmap Heap Scan on _timescaledb_internal._hyper_2_5_chunk
|
||||
Output: _hyper_2_5_chunk."time", _hyper_2_5_chunk.object_id, _hyper_2_5_chunk.temp
|
||||
Recheck Cond: (_hyper_2_5_chunk.object_id = 1)
|
||||
Filter: (_timescaledb_internal.get_partition_for_key((_hyper_2_5_chunk.object_id)::text) = 1516350201)
|
||||
Filter: (_timescaledb_internal.get_partition_hash(_hyper_2_5_chunk.object_id) = 242423622)
|
||||
-> Bitmap Index Scan on _hyper_2_5_chunk_int_part_object_id_time_idx
|
||||
Index Cond: (_hyper_2_5_chunk.object_id = 1)
|
||||
(10 rows)
|
||||
|
@ -27,12 +27,12 @@ CREATE TABLE chunk_test(time integer, temp float8, tag integer, color integer);
|
||||
|
||||
SELECT create_hypertable('chunk_test', 'time', 'tag', 2, chunk_time_interval => 3);
|
||||
|
||||
INSERT INTO chunk_test VALUES (4, 24.3, 3, 1);
|
||||
INSERT INTO chunk_test VALUES (4, 24.3, 1, 1);
|
||||
|
||||
SELECT * FROM _timescaledb_catalog.dimension_slice;
|
||||
|
||||
INSERT INTO chunk_test VALUES (4, 24.3, 1, 1);
|
||||
INSERT INTO chunk_test VALUES (10, 24.3, 1, 1);
|
||||
INSERT INTO chunk_test VALUES (4, 24.3, 2, 1);
|
||||
INSERT INTO chunk_test VALUES (10, 24.3, 2, 1);
|
||||
|
||||
SELECT c.table_name AS chunk_name, d.id AS dimension_id, ds.id AS slice_id, range_start, range_end FROM _timescaledb_catalog.chunk c
|
||||
LEFT JOIN _timescaledb_catalog.chunk_constraint cc ON (c.id = cc.chunk_id)
|
||||
@ -47,15 +47,15 @@ UPDATE _timescaledb_catalog.dimension SET num_slices = 3 WHERE id = 2;
|
||||
\c single :ROLE_DEFAULT_PERM_USER
|
||||
SELECT set_chunk_time_interval('chunk_test', 1::bigint);
|
||||
|
||||
INSERT INTO chunk_test VALUES (8, 24.3, 79669, 1);
|
||||
INSERT INTO chunk_test VALUES (8, 24.3, 11233, 1);
|
||||
|
||||
SELECT set_chunk_time_interval('chunk_test', 5::bigint);
|
||||
|
||||
SELECT * FROM _timescaledb_catalog.dimension;
|
||||
INSERT INTO chunk_test VALUES (7, 24.3, 11233, 1);
|
||||
INSERT INTO chunk_test VALUES (8, 24.3, 11233, 1);
|
||||
INSERT INTO chunk_test VALUES (10, 24.3, 79669, 1);
|
||||
INSERT INTO chunk_test VALUES (16, 24.3, 79669, 1);
|
||||
INSERT INTO chunk_test VALUES (7, 24.3, 79669, 1);
|
||||
INSERT INTO chunk_test VALUES (8, 24.3, 79669, 1);
|
||||
INSERT INTO chunk_test VALUES (10, 24.3, 11233, 1);
|
||||
INSERT INTO chunk_test VALUES (16, 24.3, 11233, 1);
|
||||
|
||||
SELECT c.table_name AS chunk_name, d.id AS dimension_id, ds.id AS slice_id, range_start, range_end FROM _timescaledb_catalog.chunk c
|
||||
LEFT JOIN _timescaledb_catalog.chunk_constraint cc ON (c.id = cc.chunk_id)
|
||||
|
@ -20,7 +20,11 @@ SELECT * FROM alter_test WHERE time > '2017-05-20T10:00:01';
|
||||
ALTER TABLE alter_test RENAME COLUMN time TO time_us;
|
||||
ALTER TABLE alter_test ALTER COLUMN time_us TYPE timestamp;
|
||||
ALTER TABLE alter_test RENAME COLUMN color TO colorname;
|
||||
\set ON_ERROR_STOP 0
|
||||
-- Changing types on hash-partitioned columns is not safe for some
|
||||
-- types and is therefore blocked.
|
||||
ALTER TABLE alter_test ALTER COLUMN colorname TYPE text;
|
||||
\set ON_ERROR_STOP 1
|
||||
|
||||
\d+ alter_test
|
||||
\d+ _timescaledb_internal.*
|
||||
|
64
test/sql/hash.sql
Normal file
64
test/sql/hash.sql
Normal file
@ -0,0 +1,64 @@
|
||||
-- Test hashing Const values. We should expect the same hash value for
|
||||
-- all integer types when values are compatible
|
||||
SELECT _timescaledb_internal.get_partition_hash(1::int);
|
||||
SELECT _timescaledb_internal.get_partition_hash(1::bigint);
|
||||
SELECT _timescaledb_internal.get_partition_hash(1::smallint);
|
||||
SELECT _timescaledb_internal.get_partition_hash(true);
|
||||
|
||||
-- Floating point types should also hash the same for compatible values
|
||||
SELECT _timescaledb_internal.get_partition_hash(1.0::real);
|
||||
SELECT _timescaledb_internal.get_partition_hash(1.0::double precision);
|
||||
-- Float aliases
|
||||
SELECT _timescaledb_internal.get_partition_hash(1.0::float);
|
||||
SELECT _timescaledb_internal.get_partition_hash(1.0::float4);
|
||||
SELECT _timescaledb_internal.get_partition_hash(1.0::float8);
|
||||
SELECT _timescaledb_internal.get_partition_hash(1.0::numeric);
|
||||
|
||||
-- 'name' and '"char"' are internal PostgreSQL types, which are not
|
||||
-- intended for use by the general user. They are included here only
|
||||
-- for completeness
|
||||
-- https://www.postgresql.org/docs/10/static/datatype-character.html#datatype-character-special-table
|
||||
SELECT _timescaledb_internal.get_partition_hash('c'::name);
|
||||
SELECT _timescaledb_internal.get_partition_hash('c'::"char");
|
||||
|
||||
-- String and character hashes should also have the same output for
|
||||
-- compatible values
|
||||
SELECT _timescaledb_internal.get_partition_hash('c'::char);
|
||||
SELECT _timescaledb_internal.get_partition_hash('c'::varchar(2));
|
||||
SELECT _timescaledb_internal.get_partition_hash('c'::text);
|
||||
-- 'c' is 0x63 in ASCII
|
||||
SELECT _timescaledb_internal.get_partition_hash(E'\\x63'::bytea);
|
||||
|
||||
-- Time and date types
|
||||
SELECT _timescaledb_internal.get_partition_hash(interval '1 day');
|
||||
SELECT _timescaledb_internal.get_partition_hash('2017-03-22T09:18:23'::timestamp);
|
||||
SELECT _timescaledb_internal.get_partition_hash('2017-03-22T09:18:23'::timestamptz);
|
||||
SELECT _timescaledb_internal.get_partition_hash('2017-03-22'::date);
|
||||
SELECT _timescaledb_internal.get_partition_hash('10:00:00'::time);
|
||||
SELECT _timescaledb_internal.get_partition_hash('10:00:00-1'::timetz);
|
||||
|
||||
-- Other types
|
||||
SELECT _timescaledb_internal.get_partition_hash(ARRAY[1,2,3]);
|
||||
SELECT _timescaledb_internal.get_partition_hash('08002b:010203'::macaddr);
|
||||
SELECT _timescaledb_internal.get_partition_hash('192.168.100.128/25'::cidr);
|
||||
SELECT _timescaledb_internal.get_partition_hash('192.168.100.128'::inet);
|
||||
SELECT _timescaledb_internal.get_partition_hash('2001:4f8:3:ba:2e0:81ff:fe22:d1f1'::inet);
|
||||
SELECT _timescaledb_internal.get_partition_hash('2001:4f8:3:ba:2e0:81ff:fe22:d1f1/128'::cidr);
|
||||
SELECT _timescaledb_internal.get_partition_hash('{ "foo": "bar" }'::jsonb);
|
||||
SELECT _timescaledb_internal.get_partition_hash('4b6a5eec-b344-11e7-abc4-cec278b6b50a'::uuid);
|
||||
SELECT _timescaledb_internal.get_partition_hash(1::regclass);
|
||||
SELECT _timescaledb_internal.get_partition_hash(int4range(10, 20));
|
||||
SELECT _timescaledb_internal.get_partition_hash(int8range(10, 20));
|
||||
SELECT _timescaledb_internal.get_partition_hash(numrange(10, 20));
|
||||
SELECT _timescaledb_internal.get_partition_hash(tsrange('2017-03-22T09:18:23', '2017-03-23T09:18:23'));
|
||||
SELECT _timescaledb_internal.get_partition_hash(tstzrange('2017-03-22T09:18:23+01', '2017-03-23T09:18:23+00'));
|
||||
|
||||
-- Test hashing Var values
|
||||
CREATE TABLE hash_test(id int, value text);
|
||||
INSERT INTO hash_test VALUES (1, 'test');
|
||||
|
||||
-- Test Vars
|
||||
SELECT _timescaledb_internal.get_partition_hash(id) FROM hash_test;
|
||||
SELECT _timescaledb_internal.get_partition_hash(value) FROM hash_test;
|
||||
-- Test coerced value
|
||||
SELECT _timescaledb_internal.get_partition_hash(id::text) FROM hash_test;
|
55
test/sql/partitioning.sql
Normal file
55
test/sql/partitioning.sql
Normal file
@ -0,0 +1,55 @@
|
||||
CREATE TABLE part_legacy(time timestamptz, temp float, device int);
|
||||
SELECT create_hypertable('part_legacy', 'time', 'device', 2);
|
||||
|
||||
SELECT * FROM _timescaledb_catalog.dimension;
|
||||
|
||||
\c single :ROLE_SUPERUSER
|
||||
UPDATE _timescaledb_catalog.dimension SET partitioning_func = 'get_partition_for_key'
|
||||
WHERE partitioning_func IS NOT NULL;
|
||||
\c single :ROLE_DEFAULT_PERM_USER
|
||||
|
||||
-- Show updated partitioning function
|
||||
SELECT * FROM _timescaledb_catalog.dimension;
|
||||
|
||||
INSERT INTO part_legacy VALUES ('2017-03-22T09:18:23', 23.4, 1);
|
||||
INSERT INTO part_legacy VALUES ('2017-03-22T09:18:23', 23.4, 76);
|
||||
|
||||
VACUUM part_legacy;
|
||||
|
||||
-- Show two chunks and CHECK constraint with cast
|
||||
\d+ _timescaledb_internal._hyper_1_*_chunk
|
||||
|
||||
-- Make sure constraint exclusion works on device column
|
||||
EXPLAIN (verbose, costs off)
|
||||
SELECT * FROM part_legacy WHERE device = 1;
|
||||
|
||||
CREATE TABLE part_new(time timestamptz, temp float, device int);
|
||||
SELECT create_hypertable('part_new', 'time', 'device', 2);
|
||||
|
||||
SELECT * FROM _timescaledb_catalog.dimension;
|
||||
|
||||
INSERT INTO part_new VALUES ('2017-03-22T09:18:23', 23.4, 1);
|
||||
INSERT INTO part_new VALUES ('2017-03-22T09:18:23', 23.4, 2);
|
||||
|
||||
VACUUM part_new;
|
||||
|
||||
-- Show two chunks and CHECK constraint without cast
|
||||
\d+ _timescaledb_internal._hyper_2_*_chunk
|
||||
|
||||
-- Make sure constraint exclusion works on device column
|
||||
EXPLAIN (verbose, costs off)
|
||||
SELECT * FROM part_new WHERE device = 1;
|
||||
|
||||
CREATE TABLE part_new_convert1(time timestamptz, temp float8, device int);
|
||||
SELECT create_hypertable('part_new_convert1', 'time', 'temp', 2);
|
||||
|
||||
INSERT INTO part_new_convert1 VALUES ('2017-03-22T09:18:23', 1.0, 2);
|
||||
\set ON_ERROR_STOP 0
|
||||
-- Changing the type of a hash-partitioned column should be unsupported
|
||||
ALTER TABLE part_new_convert1 ALTER COLUMN temp TYPE numeric;
|
||||
\set ON_ERROR_STOP 1
|
||||
|
||||
-- Should be able to change if not hash partitioned though
|
||||
ALTER TABLE part_new_convert1 ALTER COLUMN time TYPE timestamp;
|
||||
|
||||
\d+ _timescaledb_internal._hyper_3_*_chunk
|
@ -6,16 +6,20 @@ SELECT * FROM PUBLIC."two_Partitions";
|
||||
|
||||
EXPLAIN (verbose ON, costs off) SELECT * FROM PUBLIC."two_Partitions";
|
||||
|
||||
\echo "The following queries should NOT scan two_Partitions._hyper_1_1_0_partition"
|
||||
\echo "The following queries should NOT scan two_Partitions._hyper_1_1_chunk"
|
||||
EXPLAIN (verbose ON, costs off) SELECT * FROM PUBLIC."two_Partitions" WHERE device_id = 'dev2';
|
||||
EXPLAIN (verbose ON, costs off) SELECT * FROM PUBLIC."two_Partitions" WHERE device_id = 'dev'||'2';
|
||||
EXPLAIN (verbose ON, costs off) SELECT * FROM PUBLIC."two_Partitions" WHERE 'dev'||'2' = device_id;
|
||||
|
||||
|
||||
--test integer partition key
|
||||
CREATE TABLE "int_part"(time timestamp, object_id int, temp float);
|
||||
SELECT create_hypertable('"int_part"', 'time', 'object_id', 2);
|
||||
INSERT INTO "int_part" VALUES('2017-01-20T09:00:01', 1, 22.5);
|
||||
INSERT INTO "int_part" VALUES('2017-01-20T09:00:01', 2, 22.5);
|
||||
|
||||
--check that there are two chunks
|
||||
\d _timescaledb_internal._hyper_2_*_chunk
|
||||
|
||||
SELECT * FROM "int_part" WHERE object_id = 1;
|
||||
--make sure this touches only one partititon
|
||||
EXPLAIN (verbose ON, costs off) SELECT * FROM "int_part" WHERE object_id = 1;
|
||||
@ -37,6 +41,3 @@ EXPLAIN (verbose ON, costs off)SELECT "timeCustom" t, min(series_0) FROM PUBLIC.
|
||||
--TODO: time transform doesn't work
|
||||
EXPLAIN (verbose ON, costs off)SELECT "timeCustom"/10 t, min(series_0) FROM PUBLIC."two_Partitions" GROUP BY t ORDER BY t DESC NULLS LAST limit 2;
|
||||
EXPLAIN (verbose ON, costs off)SELECT "timeCustom"%10 t, min(series_0) FROM PUBLIC."two_Partitions" GROUP BY t ORDER BY t DESC NULLS LAST limit 2;
|
||||
|
||||
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
--keep same order of tables as tables.sql
|
||||
SELECT * FROM _timescaledb_catalog.hypertable ORDER BY id;
|
||||
SELECT * FROM _timescaledb_catalog.tablespace ORDER BY id;
|
||||
SELECT * FROM _timescaledb_catalog.dimension ORDER BY id;
|
||||
--partitioning function changed, so don't output
|
||||
SELECT id, hypertable_id, column_name, column_type, aligned, num_slices, interval_length FROM _timescaledb_catalog.dimension ORDER BY id;
|
||||
SELECT * FROM _timescaledb_catalog.dimension_slice ORDER BY id;
|
||||
SELECT * FROM _timescaledb_catalog.chunk ORDER BY id;
|
||||
SELECT * FROM _timescaledb_catalog.chunk_constraint ORDER BY chunk_id, dimension_slice_id, constraint_name;
|
||||
|
Loading…
x
Reference in New Issue
Block a user