InfluxElixir.Client.Local.SQLExpr (InfluxElixir v0.1.40)

Copy Markdown View Source

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.

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.

t()

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

cast_type()

@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.

casts()

@type casts() :: :drop | :refuse

How render/3 treats a CAST: written as the engine names it (gone), or refused.

column_ref()

@type column_ref() :: binary() | {:qualified, binary(), binary()}

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.

t()

@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

columns(arg)

@spec columns(t()) :: [column_ref()]

The columns an expression reads, in order.

parse(str)

@spec parse(binary()) :: {:ok, t()} | {:error, term()}

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}}.

ref_text(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.

render(arg, qualifier, casts)

@spec render(t(), binary() | nil, casts()) :: binary()

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.

symbol(op)

@spec symbol(:+ | :- | :* | :/ | :rem) :: binary()

The SQL symbol of an arithmetic operator.