The engine's failure on a WHERE that leaves a numeric column no value
(verified against InfluxDB 3 Core).
When every top-level conjunct of the WHERE is one its interval analysis
can take, and the comparisons of a bare Int64, UInt64 or Float64
column with literals leave that column an empty interval, the query fails
with status 500 instead of answering []. The analysis reads:
<,<=,>,>=,=, either way round,BETWEEN, a one-elementIN, and aNOTof those, against a number or a$paramthat is one- an integer column's exclusive bound as the next integer (
v > 1 AND v < 2is empty), a float column's as the next double - a bound at the end of the type's range as that end (
v > 9223372036854775807alone is not empty), exceptu < 0on an unsigned column, which is
Any conjunct the analysis cannot take makes it give up, and the answer is
the rows: !=, NOT IN, NOT BETWEEN, a longer IN, IS [NOT] NULL
of a column, a null or text comparand, a string, tag or boolean column, a
comparison of time, an OR, a constant false, two different = of one
column, a negative literal against an unsigned column. An integer column
compared with a float literal is cast by the engine and does not take
part.
The same analysis evaluates the constants of the conjuncts it takes, and one
that overflows (the negation of the smallest integer of a type) fails the
query before any row is read: status 500, Arrow error: Arithmetic overflow: Overflow happened on: - -9223372036854775808. It does so only when the
analysis takes every conjunct; with one it cannot take (or in a select
list) the constant is read per row, and the connection is closed
(SQLNumber.negate/2).
The body names the first conjunct, in the order written (BETWEEN is
>= low then <= high): a lower bound or >= reads lhs:Null, rhs:<type>, an upper bound lhs:<type>, rhs:Null, an = is the
intersectable variant reading lhs:Null, rhs:<type>; the type is that
conjunct's column's.
What this does not pin down is refused by name: a column with two bounds one of which implies the other (the engine's choice of conjunct then changes with the set), an integer column bounded by both an integer and a float literal, a conjunct whose analysis is not known (an arithmetic expression, a comparison of two columns), and a filter over a CTE.
Summary
Types
What the engine's analysis reads a numeric column as; :other is any other column.
Looks up a column's type, or nil for a column that is not there.
Functions
Whether the engine fails the WHERE: :ok, or the engine's error, or the
refusal of a shape that is not pinned down. opts may carry cte: true
when the query filters a CTE, whose filter the engine may or may not push
to the table: the failure is refused rather than answered.
Types
@type column_type() :: :int64 | :uint64 | :float64 | :other
What the engine's analysis reads a numeric column as; :other is any other column.
@type type_of() :: (binary() -> column_type() | nil)
Looks up a column's type, or nil for a column that is not there.
Functions
@spec check([term()], type_of(), keyword()) :: :ok | {:error, InfluxElixir.Client.Local.SQLError.t()}
Whether the engine fails the WHERE: :ok, or the engine's error, or the
refusal of a shape that is not pinned down. opts may carry cte: true
when the query filters a CTE, whose filter the engine may or may not push
to the table: the failure is refused rather than answered.