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

Copy Markdown View Source

Answers a query's format: option for InfluxElixir.Client.Local as Client.HTTP answers it from InfluxDB 3 (verified against Core):

  • :json / :jsonl (the default) — the rows as they are
  • :csv — the rows as the engine's CSV parses: every value a string, rendered as the engine renders it (1.5 → "1.5", 1.0e16 → "1e16", true → "true"), an empty value absent like a null one; timestamps stay DateTimes. The engine cannot write a nested value (array_agg, a selector_* struct) as CSV: it has sent 200 and closes the connection, so the answer is the same {:connection_error, %Mint.TransportError{reason: :closed}}
  • :parquet — refused by name: the double holds no Parquet writer
  • :pretty / :json_lines and their string forms — the engine accepts them but the client cannot parse them: {:unsupported_format, format}
  • anything else — the engine's 400 for an unknown variant, ending in the at line 1 column N of its JSON parser: N is the byte, in the request body Client.HTTP sends ({"db":"<database>","format":"<format>",...}, keys in that order), where the format's string ends. It depends on the database name, which answer/4 takes.

The engine reads the request's fields in that order, db, format, params, q, before it plans the query: an unknown format is its 400 whatever the query, as is the refusal of :parquet here, and after it a parameter that is a JSON object or array (answer/4, which names the byte where the engine's parser stops). The other formats are answered from the query's result.

Summary

Functions

Runs the query (run returns {:ok, rows} or an error) and answers in format, or with the error Client.HTTP returns for that format.

The engine's 400 for the request's parameters, or :ok. The engine reads a parameter as null, boolean, number or string, and its parser stops at the first object or array, at the end of that value, or one byte on when the value is the last parameter (the closing brace is read with it); at the end of a number it cannot read (number out of range). The position counts the bytes of the body Client.HTTP sends, which database and format (nil when the request carries none) shape.

A float as the planner prints a Float64 literal, and as the engine writes a field in line protocol: positional notation, the shortest digits that read back, no .0 for a whole number (1, 0.1, 100000000000000000000, 0.0000001; negative zero is -0).

A float as the engine's CSV writes it: positional notation, with .0 when there is no fraction, for 1.0e-5 <= |x| < 1.0e16; otherwise the shortest digits with an exponent and no .0 (1e16, 1.5e-7, 5e-324). Erlang's :short renders 1.0e15 and 1.0e-5 instead.

Functions

answer(format, run, database, params \\ %{})

@spec answer(
  term(),
  (-> {:ok, [map()]} | {:error, term()}),
  binary() | nil,
  InfluxElixir.Client.QueryParams.t()
) :: {:ok, [map()]} | {:error, term()}

Runs the query (run returns {:ok, rows} or an error) and answers in format, or with the error Client.HTTP returns for that format.

database is the one the request names, or nil when it names none (Client.HTTP then leaves db out of the body); the position in an unknown format's error counts the body's bytes. params are the query's parameters as InfluxElixir.Client.QueryParams.normalize/1 returns them.

check_params(params, format, database)

@spec check_params(InfluxElixir.Client.QueryParams.t(), term(), binary() | nil) ::
  :ok | {:error, map()}

The engine's 400 for the request's parameters, or :ok. The engine reads a parameter as null, boolean, number or string, and its parser stops at the first object or array, at the end of that value, or one byte on when the value is the last parameter (the closing brace is read with it); at the end of a number it cannot read (number out of range). The position counts the bytes of the body Client.HTTP sends, which database and format (nil when the request carries none) shape.

render_decimal(value)

@spec render_decimal(float()) :: binary()

A float as the planner prints a Float64 literal, and as the engine writes a field in line protocol: positional notation, the shortest digits that read back, no .0 for a whole number (1, 0.1, 100000000000000000000, 0.0000001; negative zero is -0).

render_float(value)

@spec render_float(float()) :: binary()

A float as the engine's CSV writes it: positional notation, with .0 when there is no fraction, for 1.0e-5 <= |x| < 1.0e16; otherwise the shortest digits with an exponent and no .0 (1e16, 1.5e-7, 5e-324). Erlang's :short renders 1.0e15 and 1.0e-5 instead.