The arithmetic expressions of a SQL text: a column, a literal, a $name
placeholder, an operation, a unary minus, a CAST or a call of one of
InfluxElixir.Client.Local.SQLFunctions. They stand in an aggregate's
argument, a projection, a WHERE operand and an ORDER BY term.
A $name is kept as {:param, name} and replaced by
InfluxElixir.Client.Local.SQLBind; a bound non-negative integer is
{:uint, n}, the engine's UInt64.
A number is typed as the engine types it (verified against InfluxDB 3
Core): an integer that fits Int64 is one, a larger one that fits UInt64
is a {:uint, n}, anything else is a Float64; a - written directly
before a number is part of it (-9223372036854775808 is an Int64, while
-(9223372036854775808) negates a UInt64, which the engine refuses). A
float too large for a double is {:lit, :inf} or {:lit, :neg_inf}, which the engine
answers as a JSON null and compares as infinity.
render/3 writes an expression as the engine names a column: the name
that stands for a select item without an alias.
Summary
Types
CAST(expr AS type) targets (and their synonyms): the integer types by
width (INTEGER is 32 bits), DOUBLE, and text.
A column an expression reads: its name, or a reference to a relation the
query does not have ("XQA".v, foo.v), kept as it was written so the
engine's error can print it.
An arithmetic expression: a column, a literal, a $name
placeholder ({:param, name}, replaced by InfluxElixir.Client.Local.SQLBind)
or a bound non-negative integer parameter ({:uint, n}, the engine's
UInt64), or an operation over expressions. The parser reads a column as
{:field, name}; InfluxElixir.Client.Local.SQLTyping reads one the store
holds as UInt64 as {:uint_col, name}.
Functions
The columns an expression reads, in order.
Parses an expression (recursive descent, standard precedence)
A column reference as the engine prints it in a message: a name bare when it is a lower case word, otherwise quoted; a reference to another relation as it was written.
An expression as the engine writes it in a column's name: columns
qualified by qualifier, literals with their type, operators infix and
unparenthesised, a call's arguments joined by a bare comma. A CAST is
written as the expression it casts when casts is :drop (the engine's
name for the column) and refused when it is :refuse (the planner's
printing, which keeps the cast under conditions the double does not model).
The SQL symbol of an arithmetic operator.
Types
@type cast_type() :: :int8 | :int16 | :int32 | :int64 | :float | :string
CAST(expr AS type) targets (and their synonyms): the integer types by
width (INTEGER is 32 bits), DOUBLE, and text.
@type casts() :: :drop | :refuse
How render/3 treats a CAST: written as the engine names it (gone), or refused.
A column an expression reads: its name, or a reference to a relation the
query does not have ("XQA".v, foo.v), kept as it was written so the
engine's error can print it.
@type t() :: {:field, column_ref()} | {:lit, number() | binary() | boolean() | nil | :inf | :neg_inf} | {:uint_col, binary()} | {:uint, non_neg_integer()} | {:param, binary()} | {:op, :+ | :- | :* | :/ | :rem, t(), t()} | {:neg, t()} | {:cast, t(), cast_type()} | {:call, InfluxElixir.Client.Local.SQLFunctions.name(), [t()]} | {:unreadable, binary()}
An arithmetic expression: a column, a literal, a $name
placeholder ({:param, name}, replaced by InfluxElixir.Client.Local.SQLBind)
or a bound non-negative integer parameter ({:uint, n}, the engine's
UInt64), or an operation over expressions. The parser reads a column as
{:field, name}; InfluxElixir.Client.Local.SQLTyping reads one the store
holds as UInt64 as {:uint_col, name}.
Functions
@spec columns(t()) :: [column_ref()]
The columns an expression reads, in order.
Parses an expression (recursive descent, standard precedence):
expr := term (('+' | '-') term)*
term := factor (('*' | '/' | '%') factor)*
factor := '-' factor | number | identifier | '(' expr ')'
| function '(' [expr (',' expr)*] ')'function is one of InfluxElixir.Client.Local.SQLFunctions; any number of
arguments parses, and the executor answers a wrong count or type as the
engine's planner does. A call of any other function is
{:error, {:unsupported_function, name}}.
@spec ref_text(column_ref()) :: binary()
A column reference as the engine prints it in a message: a name bare when it is a lower case word, otherwise quoted; a reference to another relation as it was written.
An expression as the engine writes it in a column's name: columns
qualified by qualifier, literals with their type, operators infix and
unparenthesised, a call's arguments joined by a bare comma. A CAST is
written as the expression it casts when casts is :drop (the engine's
name for the column) and refused when it is :refuse (the planner's
printing, which keeps the cast under conditions the double does not model).
Throws :unrenderable for what the double does not print: a column when
qualifier is nil (the side of a join that holds it is not known), a
refused cast.
@spec symbol(:+ | :- | :* | :/ | :rem) :: binary()
The SQL symbol of an arithmetic operator.