mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-16 18:43:18 +08:00
Improve space constraint exclusion datatype handling
This patch adjusts the operator logic for valid space dimension constraints to no longer look for an exact match on both sides of the operator but instead allow mismatched datatypes. Previously a constraint like `col = value` would require `col` and `value` to have matching datatype with this change `col` and `value` can be different datatype as long as they have equality operator in btree family. Mismatching datatype can happen commonly when using int8 columns and comparing them with integer literals. Integer literals default to int4 so the datatypes would not match unless special care has been taken in writing the constraints and therefore the optimization would never apply in those cases.
This commit is contained in:
parent
f27e627341
commit
a26a5974dc
@ -12,6 +12,7 @@
|
||||
#include <optimizer/optimizer.h>
|
||||
#include <parser/parse_func.h>
|
||||
#include <utils/fmgroids.h>
|
||||
#include <utils/typcache.h>
|
||||
|
||||
#include "cache.h"
|
||||
#include "dimension.h"
|
||||
@ -42,6 +43,43 @@ get_space_dimension(Oid relid, Index varattno)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if this operator is compatible with the constraints on
|
||||
* the space dimension. This is the equality operator between
|
||||
* left and right in the btree operator family.
|
||||
*/
|
||||
static bool
|
||||
is_valid_space_operator(Oid opno, Oid left, Oid right)
|
||||
{
|
||||
TypeCacheEntry *tce;
|
||||
|
||||
if (left == right)
|
||||
{
|
||||
/*
|
||||
* When left and right match lookup_type_cache can
|
||||
* directly return the equality operator saving us
|
||||
* one roundtrip.
|
||||
*/
|
||||
tce = lookup_type_cache(left, TYPECACHE_EQ_OPR);
|
||||
|
||||
return tce && opno == tce->eq_opr;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* The left and right type might not match when comparing
|
||||
* different integer types eg comparing int2 or int8
|
||||
* columns with integer literals which default to int4.
|
||||
*/
|
||||
tce = lookup_type_cache(left, TYPECACHE_BTREE_OPFAMILY);
|
||||
if (!tce)
|
||||
return false;
|
||||
|
||||
Oid eqop = get_opfamily_member(tce->btree_opf, left, right, BTEqualStrategyNumber);
|
||||
return opno == eqop;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Valid constraints are: Var = Const
|
||||
* Var has to refer to a space partitioning column
|
||||
@ -54,9 +92,11 @@ is_valid_space_constraint(OpExpr *op, List *rtable)
|
||||
return false;
|
||||
|
||||
Var *var = linitial_node(Var, op->args);
|
||||
TypeCacheEntry *tce = lookup_type_cache(var->vartype, TYPECACHE_EQ_OPR);
|
||||
if (var->varlevelsup != 0)
|
||||
return false;
|
||||
|
||||
if (op->opno != tce->eq_opr || var->varlevelsup != 0)
|
||||
Const *value = lsecond_node(Const, op->args);
|
||||
if (!is_valid_space_operator(op->opno, var->vartype, value->consttype))
|
||||
return false;
|
||||
|
||||
/*
|
||||
@ -85,16 +125,12 @@ is_valid_scalar_space_constraint(ScalarArrayOpExpr *op, List *rtable)
|
||||
if (!IsA(linitial(op->args), Var) || !IsA(lsecond(op->args), ArrayExpr))
|
||||
return false;
|
||||
|
||||
ArrayExpr *arr = castNode(ArrayExpr, lsecond(op->args));
|
||||
if (arr->multidims || !op->useOr)
|
||||
return false;
|
||||
|
||||
Var *var = linitial_node(Var, op->args);
|
||||
TypeCacheEntry *tce = lookup_type_cache(var->vartype, TYPECACHE_EQ_OPR);
|
||||
if (var->vartype != arr->element_typeid || op->opno != tce->eq_opr)
|
||||
ArrayExpr *arr = castNode(ArrayExpr, lsecond(op->args));
|
||||
if (arr->multidims || !op->useOr || var->varlevelsup != 0)
|
||||
return false;
|
||||
|
||||
if (var->varlevelsup != 0)
|
||||
if (!is_valid_space_operator(op->opno, var->vartype, arr->element_typeid))
|
||||
return false;
|
||||
|
||||
/*
|
||||
@ -110,8 +146,23 @@ is_valid_scalar_space_constraint(ScalarArrayOpExpr *op, List *rtable)
|
||||
ListCell *lc;
|
||||
foreach (lc, arr->elements)
|
||||
{
|
||||
if (!IsA(lfirst(lc), Const) || lfirst_node(Const, lc)->consttype != var->vartype)
|
||||
return false;
|
||||
switch (nodeTag(lfirst(lc)))
|
||||
{
|
||||
case T_Const:
|
||||
break;
|
||||
case T_FuncExpr:
|
||||
{
|
||||
FuncExpr *element = lfirst_node(FuncExpr, lc);
|
||||
if (element->funcformat != COERCE_IMPLICIT_CAST ||
|
||||
!IsA(linitial(element->args), Const))
|
||||
return false;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -194,18 +245,21 @@ transform_scalar_space_constraint(PlannerInfo *root, List *rtable, ScalarArrayOp
|
||||
|
||||
foreach (lc, lsecond_node(ArrayExpr, op->args)->elements)
|
||||
{
|
||||
Const *value = lfirst_node(Const, lc);
|
||||
Assert(IsA(lfirst(lc), Const) ||
|
||||
(IsA(lfirst(lc), FuncExpr) &&
|
||||
lfirst_node(FuncExpr, lc)->funcformat == COERCE_IMPLICIT_CAST));
|
||||
|
||||
/*
|
||||
* We can skip NULL here as elements are ORed and partitioning dimensions
|
||||
* have NOT NULL constraint.
|
||||
*/
|
||||
if (!value->constisnull)
|
||||
{
|
||||
List *args = list_make1(value);
|
||||
partcall->args = args;
|
||||
part_values = lappend(part_values,
|
||||
castNode(Const, eval_const_expressions(root, (Node *) partcall)));
|
||||
}
|
||||
if (IsA(lfirst(lc), Const) && lfirst_node(Const, lc)->constisnull)
|
||||
continue;
|
||||
|
||||
List *args = list_make1(lfirst(lc));
|
||||
partcall->args = args;
|
||||
part_values =
|
||||
lappend(part_values, castNode(Const, eval_const_expressions(root, (Node *) partcall)));
|
||||
}
|
||||
/* build FuncExpr with column reference to use in constraint */
|
||||
partcall->args = list_make1(copyObject(var));
|
||||
|
@ -54,6 +54,91 @@ QUERY PLAN
|
||||
Filter: (device_id = ANY ('{1,3}'::integer[]))
|
||||
(16 rows)
|
||||
|
||||
-- check mismatching datatypes
|
||||
:PREFIX SELECT FROM metrics_space WHERE device_id = smallint '2' FOR UPDATE;
|
||||
QUERY PLAN
|
||||
LockRows
|
||||
-> Append
|
||||
-> Seq Scan on metrics_space
|
||||
Filter: (device_id = '2'::smallint)
|
||||
-> Index Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk
|
||||
Index Cond: (device_id = '2'::smallint)
|
||||
-> Index Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk
|
||||
Index Cond: (device_id = '2'::smallint)
|
||||
-> Index Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk
|
||||
Index Cond: (device_id = '2'::smallint)
|
||||
(10 rows)
|
||||
|
||||
:PREFIX SELECT FROM metrics_space WHERE device_id = int '2' FOR UPDATE;
|
||||
QUERY PLAN
|
||||
LockRows
|
||||
-> Append
|
||||
-> Seq Scan on metrics_space
|
||||
Filter: (device_id = 2)
|
||||
-> Index Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk
|
||||
Index Cond: (device_id = 2)
|
||||
-> Index Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk
|
||||
Index Cond: (device_id = 2)
|
||||
-> Index Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk
|
||||
Index Cond: (device_id = 2)
|
||||
(10 rows)
|
||||
|
||||
:PREFIX SELECT FROM metrics_space WHERE device_id = bigint '3' FOR UPDATE;
|
||||
QUERY PLAN
|
||||
LockRows
|
||||
-> Append
|
||||
-> Seq Scan on metrics_space
|
||||
Filter: (device_id = '3'::bigint)
|
||||
-> Seq Scan on _hyper_X_X_chunk
|
||||
Filter: (device_id = '3'::bigint)
|
||||
-> Seq Scan on _hyper_X_X_chunk
|
||||
Filter: (device_id = '3'::bigint)
|
||||
-> Seq Scan on _hyper_X_X_chunk
|
||||
Filter: (device_id = '3'::bigint)
|
||||
(10 rows)
|
||||
|
||||
:PREFIX SELECT FROM metrics_space WHERE device_id IN (smallint '1', smallint '1') FOR UPDATE;
|
||||
QUERY PLAN
|
||||
LockRows
|
||||
-> Append
|
||||
-> Seq Scan on metrics_space
|
||||
Filter: (device_id = ANY ('{1,1}'::integer[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk
|
||||
Filter: (device_id = ANY ('{1,1}'::integer[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk
|
||||
Filter: (device_id = ANY ('{1,1}'::integer[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk
|
||||
Filter: (device_id = ANY ('{1,1}'::integer[]))
|
||||
(10 rows)
|
||||
|
||||
:PREFIX SELECT FROM metrics_space WHERE device_id IN (int '1', int '1') FOR UPDATE;
|
||||
QUERY PLAN
|
||||
LockRows
|
||||
-> Append
|
||||
-> Seq Scan on metrics_space
|
||||
Filter: (device_id = ANY ('{1,1}'::integer[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk
|
||||
Filter: (device_id = ANY ('{1,1}'::integer[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk
|
||||
Filter: (device_id = ANY ('{1,1}'::integer[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk
|
||||
Filter: (device_id = ANY ('{1,1}'::integer[]))
|
||||
(10 rows)
|
||||
|
||||
:PREFIX SELECT FROM metrics_space WHERE device_id IN (bigint '1', bigint '1') FOR UPDATE;
|
||||
QUERY PLAN
|
||||
LockRows
|
||||
-> Append
|
||||
-> Seq Scan on metrics_space
|
||||
Filter: (device_id = ANY ('{1,1}'::bigint[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk
|
||||
Filter: (device_id = ANY ('{1,1}'::bigint[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk
|
||||
Filter: (device_id = ANY ('{1,1}'::bigint[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk
|
||||
Filter: (device_id = ANY ('{1,1}'::bigint[]))
|
||||
(10 rows)
|
||||
|
||||
-- test valid variants we are optimizing
|
||||
:PREFIX DELETE FROM metrics_space WHERE device_id = 1;
|
||||
QUERY PLAN
|
||||
|
@ -54,6 +54,91 @@ QUERY PLAN
|
||||
Filter: (device_id = ANY ('{1,3}'::integer[]))
|
||||
(16 rows)
|
||||
|
||||
-- check mismatching datatypes
|
||||
:PREFIX SELECT FROM metrics_space WHERE device_id = smallint '2' FOR UPDATE;
|
||||
QUERY PLAN
|
||||
LockRows
|
||||
-> Append
|
||||
-> Seq Scan on metrics_space metrics_space_1
|
||||
Filter: (device_id = '2'::smallint)
|
||||
-> Index Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk metrics_space_2
|
||||
Index Cond: (device_id = '2'::smallint)
|
||||
-> Index Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk metrics_space_3
|
||||
Index Cond: (device_id = '2'::smallint)
|
||||
-> Index Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk metrics_space_4
|
||||
Index Cond: (device_id = '2'::smallint)
|
||||
(10 rows)
|
||||
|
||||
:PREFIX SELECT FROM metrics_space WHERE device_id = int '2' FOR UPDATE;
|
||||
QUERY PLAN
|
||||
LockRows
|
||||
-> Append
|
||||
-> Seq Scan on metrics_space metrics_space_1
|
||||
Filter: (device_id = 2)
|
||||
-> Index Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk metrics_space_2
|
||||
Index Cond: (device_id = 2)
|
||||
-> Index Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk metrics_space_3
|
||||
Index Cond: (device_id = 2)
|
||||
-> Index Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk metrics_space_4
|
||||
Index Cond: (device_id = 2)
|
||||
(10 rows)
|
||||
|
||||
:PREFIX SELECT FROM metrics_space WHERE device_id = bigint '3' FOR UPDATE;
|
||||
QUERY PLAN
|
||||
LockRows
|
||||
-> Append
|
||||
-> Seq Scan on metrics_space metrics_space_1
|
||||
Filter: (device_id = '3'::bigint)
|
||||
-> Seq Scan on _hyper_X_X_chunk metrics_space_2
|
||||
Filter: (device_id = '3'::bigint)
|
||||
-> Seq Scan on _hyper_X_X_chunk metrics_space_3
|
||||
Filter: (device_id = '3'::bigint)
|
||||
-> Seq Scan on _hyper_X_X_chunk metrics_space_4
|
||||
Filter: (device_id = '3'::bigint)
|
||||
(10 rows)
|
||||
|
||||
:PREFIX SELECT FROM metrics_space WHERE device_id IN (smallint '1', smallint '1') FOR UPDATE;
|
||||
QUERY PLAN
|
||||
LockRows
|
||||
-> Append
|
||||
-> Seq Scan on metrics_space metrics_space_1
|
||||
Filter: (device_id = ANY ('{1,1}'::integer[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk metrics_space_2
|
||||
Filter: (device_id = ANY ('{1,1}'::integer[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk metrics_space_3
|
||||
Filter: (device_id = ANY ('{1,1}'::integer[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk metrics_space_4
|
||||
Filter: (device_id = ANY ('{1,1}'::integer[]))
|
||||
(10 rows)
|
||||
|
||||
:PREFIX SELECT FROM metrics_space WHERE device_id IN (int '1', int '1') FOR UPDATE;
|
||||
QUERY PLAN
|
||||
LockRows
|
||||
-> Append
|
||||
-> Seq Scan on metrics_space metrics_space_1
|
||||
Filter: (device_id = ANY ('{1,1}'::integer[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk metrics_space_2
|
||||
Filter: (device_id = ANY ('{1,1}'::integer[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk metrics_space_3
|
||||
Filter: (device_id = ANY ('{1,1}'::integer[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk metrics_space_4
|
||||
Filter: (device_id = ANY ('{1,1}'::integer[]))
|
||||
(10 rows)
|
||||
|
||||
:PREFIX SELECT FROM metrics_space WHERE device_id IN (bigint '1', bigint '1') FOR UPDATE;
|
||||
QUERY PLAN
|
||||
LockRows
|
||||
-> Append
|
||||
-> Seq Scan on metrics_space metrics_space_1
|
||||
Filter: (device_id = ANY ('{1,1}'::bigint[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk metrics_space_2
|
||||
Filter: (device_id = ANY ('{1,1}'::bigint[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk metrics_space_3
|
||||
Filter: (device_id = ANY ('{1,1}'::bigint[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk metrics_space_4
|
||||
Filter: (device_id = ANY ('{1,1}'::bigint[]))
|
||||
(10 rows)
|
||||
|
||||
-- test valid variants we are optimizing
|
||||
:PREFIX DELETE FROM metrics_space WHERE device_id = 1;
|
||||
QUERY PLAN
|
||||
|
@ -54,6 +54,91 @@ QUERY PLAN
|
||||
Filter: (device_id = ANY ('{1,3}'::integer[]))
|
||||
(16 rows)
|
||||
|
||||
-- check mismatching datatypes
|
||||
:PREFIX SELECT FROM metrics_space WHERE device_id = smallint '2' FOR UPDATE;
|
||||
QUERY PLAN
|
||||
LockRows
|
||||
-> Append
|
||||
-> Seq Scan on metrics_space metrics_space_1
|
||||
Filter: (device_id = '2'::smallint)
|
||||
-> Index Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk metrics_space_2
|
||||
Index Cond: (device_id = '2'::smallint)
|
||||
-> Index Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk metrics_space_3
|
||||
Index Cond: (device_id = '2'::smallint)
|
||||
-> Index Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk metrics_space_4
|
||||
Index Cond: (device_id = '2'::smallint)
|
||||
(10 rows)
|
||||
|
||||
:PREFIX SELECT FROM metrics_space WHERE device_id = int '2' FOR UPDATE;
|
||||
QUERY PLAN
|
||||
LockRows
|
||||
-> Append
|
||||
-> Seq Scan on metrics_space metrics_space_1
|
||||
Filter: (device_id = 2)
|
||||
-> Index Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk metrics_space_2
|
||||
Index Cond: (device_id = 2)
|
||||
-> Index Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk metrics_space_3
|
||||
Index Cond: (device_id = 2)
|
||||
-> Index Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk metrics_space_4
|
||||
Index Cond: (device_id = 2)
|
||||
(10 rows)
|
||||
|
||||
:PREFIX SELECT FROM metrics_space WHERE device_id = bigint '3' FOR UPDATE;
|
||||
QUERY PLAN
|
||||
LockRows
|
||||
-> Append
|
||||
-> Seq Scan on metrics_space metrics_space_1
|
||||
Filter: (device_id = '3'::bigint)
|
||||
-> Seq Scan on _hyper_X_X_chunk metrics_space_2
|
||||
Filter: (device_id = '3'::bigint)
|
||||
-> Seq Scan on _hyper_X_X_chunk metrics_space_3
|
||||
Filter: (device_id = '3'::bigint)
|
||||
-> Seq Scan on _hyper_X_X_chunk metrics_space_4
|
||||
Filter: (device_id = '3'::bigint)
|
||||
(10 rows)
|
||||
|
||||
:PREFIX SELECT FROM metrics_space WHERE device_id IN (smallint '1', smallint '1') FOR UPDATE;
|
||||
QUERY PLAN
|
||||
LockRows
|
||||
-> Append
|
||||
-> Seq Scan on metrics_space metrics_space_1
|
||||
Filter: (device_id = ANY ('{1,1}'::integer[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk metrics_space_2
|
||||
Filter: (device_id = ANY ('{1,1}'::integer[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk metrics_space_3
|
||||
Filter: (device_id = ANY ('{1,1}'::integer[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk metrics_space_4
|
||||
Filter: (device_id = ANY ('{1,1}'::integer[]))
|
||||
(10 rows)
|
||||
|
||||
:PREFIX SELECT FROM metrics_space WHERE device_id IN (int '1', int '1') FOR UPDATE;
|
||||
QUERY PLAN
|
||||
LockRows
|
||||
-> Append
|
||||
-> Seq Scan on metrics_space metrics_space_1
|
||||
Filter: (device_id = ANY ('{1,1}'::integer[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk metrics_space_2
|
||||
Filter: (device_id = ANY ('{1,1}'::integer[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk metrics_space_3
|
||||
Filter: (device_id = ANY ('{1,1}'::integer[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk metrics_space_4
|
||||
Filter: (device_id = ANY ('{1,1}'::integer[]))
|
||||
(10 rows)
|
||||
|
||||
:PREFIX SELECT FROM metrics_space WHERE device_id IN (bigint '1', bigint '1') FOR UPDATE;
|
||||
QUERY PLAN
|
||||
LockRows
|
||||
-> Append
|
||||
-> Seq Scan on metrics_space metrics_space_1
|
||||
Filter: (device_id = ANY ('{1,1}'::bigint[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk metrics_space_2
|
||||
Filter: (device_id = ANY ('{1,1}'::bigint[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk metrics_space_3
|
||||
Filter: (device_id = ANY ('{1,1}'::bigint[]))
|
||||
-> Seq Scan on _hyper_X_X_chunk metrics_space_4
|
||||
Filter: (device_id = ANY ('{1,1}'::bigint[]))
|
||||
(10 rows)
|
||||
|
||||
-- test valid variants we are optimizing
|
||||
:PREFIX DELETE FROM metrics_space WHERE device_id = 1;
|
||||
QUERY PLAN
|
||||
|
@ -14,6 +14,14 @@ SET timescaledb.current_timestamp_mock TO '1990-01-01';
|
||||
:PREFIX SELECT FROM metrics_space WHERE device_id IN (1) FOR UPDATE;
|
||||
:PREFIX SELECT FROM metrics_space WHERE device_id IN (1,3) FOR UPDATE;
|
||||
|
||||
-- check mismatching datatypes
|
||||
:PREFIX SELECT FROM metrics_space WHERE device_id = smallint '2' FOR UPDATE;
|
||||
:PREFIX SELECT FROM metrics_space WHERE device_id = int '2' FOR UPDATE;
|
||||
:PREFIX SELECT FROM metrics_space WHERE device_id = bigint '3' FOR UPDATE;
|
||||
:PREFIX SELECT FROM metrics_space WHERE device_id IN (smallint '1', smallint '1') FOR UPDATE;
|
||||
:PREFIX SELECT FROM metrics_space WHERE device_id IN (int '1', int '1') FOR UPDATE;
|
||||
:PREFIX SELECT FROM metrics_space WHERE device_id IN (bigint '1', bigint '1') FOR UPDATE;
|
||||
|
||||
-- test valid variants we are optimizing
|
||||
:PREFIX DELETE FROM metrics_space WHERE device_id = 1;
|
||||
:PREFIX DELETE FROM metrics_space WHERE device_id IN (1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user