Dsqlex (dsqlex v0.1.0)

Copy Markdown View Source

DSQLEX - A SQL-like DSL for evaluating calculations in Elixir.

Usage

# Define a calculation expression (SELECT is optional)
expression = "CASE WHEN category = 'A' THEN x ELSE (y / z) END"

# Create a context with your data
context = %{
  "x" => Decimal.new("100.00"),
  "y" => Decimal.new("500.00"),
  "category" => "B",
  "z" => Decimal.new("5.00")
}

# Evaluate!
{:ok, result} = Dsqlex.eval(expression, context)
# => {:ok, Decimal.new("100")}

Supported Features

  • Arithmetic: +, -, *, /
  • Comparison: =, !=, <, >, <=, >=
  • Logical: AND, OR (same-operator chaining allowed)
  • Control flow: CASE WHEN ... THEN ... ELSE ... END
  • Functions: ROUND(), COALESCE(), UPPER(), LOWER(), ABS(), CONCAT()
  • Literals: Numbers, strings, booleans, NULL

Parentheses Rule

To avoid ambiguity, expressions that mix operator groups require parentheses:

# Valid
"1 + 2"
"1 + 2 + 3"
"(1 + 2) * 3"
"a = 1 AND b = 2 AND c = 3"

# Invalid (ambiguous)
"1 + 2 * 3"
"a = 1 AND b = 2 OR c = 3"

Summary

Functions

Evaluates an expression against a context.

Parses an expression and returns the AST without evaluating.

Tokenizes an expression without parsing.

Functions

eval(expression, context, opts \\ [])

Evaluates an expression against a context.

The SELECT keyword is optional.

Parameters

  • expression - A string containing the expression
  • context - A map of field names (strings) to values

Returns

  • {:ok, result} - The computed result
  • {:error, reason} - If lexing, parsing, or evaluation fails

Examples

iex> Dsqlex.eval("1 + 2", %{})
{:ok, Decimal.new("3")}

iex> Dsqlex.eval("x * 2", %{"x" => Decimal.new("50")})
{:ok, Decimal.new("100")}

parse(expression)

Parses an expression and returns the AST without evaluating.

Useful for validating expressions before storing them. The SELECT keyword is optional.

Examples

iex> Dsqlex.parse("x / y")
{:ok, {:select, {:binary_op, :divide, {:identifier, "x"}, {:identifier, "y"}}}}

tokenize(expression)

Tokenizes an expression without parsing.

Useful for debugging or inspecting the lexer output.