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

Copy Markdown View Source

What a time comparand is, as InfluxDB 3 reads it (verified against Core):

  • a quoted string is read as Arrow reads a timestamp: YYYY-MM-DD, then optionally T, t or a space, HH:MM:SS (:60 is the next minute), a fraction (digits past the ninth are dropped) and a zone — Z, z, a fixed offset (+01:00, +0100, +01, after any blanks) or a name of the time zone database, which is case sensitive: the ones that are UTC (UTC, GMT, Zulu, UCT, Universal, Greenwich, GMT0, GMT+0, GMT-0 and the same under Etc/), Etc/GMT+1 to Etc/GMT+12 (the sign is inverted: UTC minus that many hours) and Etc/GMT-1 to Etc/GMT-14, and the fixed offsets EST, MST and HST. A string it cannot read is the optimizer's 500 naming why (timestamp must contain at least 10 characters, error parsing date, invalid timestamp separator, error parsing time, Invalid timezone "..."), and an instant outside the Int64 nanoseconds is its overflow error
  • now(), offset by +/- INTERVAL 'N unit' terms
  • a $name, bound by InfluxElixir.Client.Local.SQLBind: a string is read as above, a null is unknown, a number or boolean is the planner's type error
  • NULL, which compares as unknown
  • a bare number is the planner's type error, worded by the caller

The optimizer folds a constant after the planner has typed the whole query, so an unreadable string is kept in the parsed query as {:invalid_time, error} and raised by first_invalid/1 once the type checks have passed. What the double cannot model — a time zone whose offset changes with the date — is the same marker carrying a Client.Local: refusal.

Summary

Types

A time comparand: nanoseconds since the epoch, now() plus an offset, null, a $name still to bind, a bare number of the given type (an error once the clause is known) or an unreadable string.

What comparand/1 returns.

Functions

A time BETWEEN once its bounds are known: a bare number fails it, naming the first bound that has one.

A comparand as a bound: a bare number stays {:number, type} and an unreadable one becomes {:invalid_time, error}, for the clause to settle.

Reads the text of a time comparand. {:error, {:number, type}} is a bare number of that type, for the caller to word as its clause does.

The engine's type error for time compared with something that is not a timestamp.

The first unreadable string among the time comparands of a WHERE, in the order written, as the optimizer's error; :ok when there is none.

The first type error kept in a WHERE (a time compared with a number, see InfluxElixir.Client.Local.SQLWhere.deferred_clause/1), in the order written; :ok when there is none. A statement that is not planned against a schema raises it as soon as it is parsed.

A time IN list once its items are known: a bare number fails the whole list, which the engine words with every item's type, a string being Utf8.

An interval as nanoseconds: "N unit" with the unit one of second, minute, hour or day (plural or not).

What a bound parameter is as a time comparand.

Whether the bound is a $name still to bind.

Types

bound()

@type bound() ::
  integer()
  | {:now, integer()}
  | nil
  | {:param, binary()}
  | {:param, binary(), :left}
  | {:number, binary()}
  | {:invalid_time, InfluxElixir.Client.Local.SQLError.t()}

A time comparand: nanoseconds since the epoch, now() plus an offset, null, a $name still to bind, a bare number of the given type (an error once the clause is known) or an unreadable string.

comparand()

@type comparand() ::
  {:ok, bound()}
  | {:error, {:number, binary()} | InfluxElixir.Client.Local.SQLError.t()}

What comparand/1 returns.

Functions

between(op, low, high)

@spec between(:between | :not_between, bound(), bound()) ::
  {:ok, {atom(), binary(), {bound(), bound()}}}
  | {:error, InfluxElixir.Client.Local.SQLError.t()}

A time BETWEEN once its bounds are known: a bare number fails it, naming the first bound that has one.

bound(arg)

@spec bound(comparand()) :: bound()

A comparand as a bound: a bare number stays {:number, type} and an unreadable one becomes {:invalid_time, error}, for the clause to settle.

comparand(text)

@spec comparand(binary()) :: comparand()

Reads the text of a time comparand. {:error, {:number, type}} is a bare number of that type, for the caller to word as its clause does.

comparison_type_error(left, operator, right)

@spec comparison_type_error(binary(), binary(), binary()) ::
  InfluxElixir.Client.Local.SQLError.t()

The engine's type error for time compared with something that is not a timestamp.

first_invalid(nodes)

@spec first_invalid([term()]) ::
  :ok | {:error, InfluxElixir.Client.Local.SQLError.t()}

The first unreadable string among the time comparands of a WHERE, in the order written, as the optimizer's error; :ok when there is none.

first_type_error(nodes)

@spec first_type_error([term()]) ::
  :ok | {:error, InfluxElixir.Client.Local.SQLError.t()}

The first type error kept in a WHERE (a time compared with a number, see InfluxElixir.Client.Local.SQLWhere.deferred_clause/1), in the order written; :ok when there is none. A statement that is not planned against a schema raises it as soon as it is parsed.

in_list(bounds)

@spec in_list([bound()]) ::
  {:ok, [bound()]} | {:error, InfluxElixir.Client.Local.SQLError.t()}

A time IN list once its items are known: a bare number fails the whole list, which the engine words with every item's type, a string being Utf8.

interval(text)

@spec interval(binary()) ::
  {:ok, pos_integer()} | {:error, InfluxElixir.Client.Local.SQLError.t()}

An interval as nanoseconds: "N unit" with the unit one of second, minute, hour or day (plural or not).

param(value)

@spec param(term()) :: bound()

What a bound parameter is as a time comparand.

param_bound?(arg1)

@spec param_bound?(term()) :: boolean()

Whether the bound is a $name still to bind.