mtparser/ast

AST nodes and their supporting types — every type lives here; the functions that construct and manipulate them live in helper.

Types

Comparison operators.

pub type ComparisonOp {
  Eq
  Neq
  Lt
  Le
  Gt
  Ge
}

Constructors

  • Eq
  • Neq
  • Lt
  • Le
  • Gt
  • Ge

Right-hand side of a comparison.

pub type ComparisonRhs {
  RhsInteger(value: Int, span: Span)
  RhsString(value: String, span: Span)
  RhsVariable(variable: VariableRef)
  RhsQuery(query: QueryExpr)
}

Constructors

Position-based connection parameters for connect (…) — empty segments are None.

pub type ConnectParams {
  ConnectParams(
    host: option.Option(List(TextPart)),
    user: option.Option(List(TextPart)),
    password: option.Option(List(TextPart)),
    database: option.Option(List(TextPart)),
    port: option.Option(List(TextPart)),
    socket: option.Option(List(TextPart)),
    default_charset: option.Option(List(TextPart)),
  )
}

Constructors

A condition expression, shared by assert/if/while.

pub type Expr {
  Var(variable: VariableRef)
  Negated(span: Span, expr: Expr)
  Integer(span: Span, value: Int)
  Query(query: QueryExpr)
  Comparison(
    left: VariableRef,
    operator: ComparisonOp,
    operator_span: Span,
    right: ComparisonRhs,
  )
  Closure(span: Span, expression: String)
  Logical(span: Span, left: Expr, op: LogicalOp, right: Expr)
}

Constructors

  • Var(variable: VariableRef)

    $var truthiness reference.

  • Negated(span: Span, expr: Expr)

    !expr — single negation.

  • Integer(span: Span, value: Int)
  • Query(query: QueryExpr)
  • Comparison(
      left: VariableRef,
      operator: ComparisonOp,
      operator_span: Span,
      right: ComparisonRhs,
    )

    $var [op rhs]; no overall span (sub-nodes carry their own).

  • Closure(span: Span, expression: String)

    $(expr) closure, e.g. $(1 + 2) — the inner arithmetic expression is kept raw (the calculator grammar is a runtime concern).

  • Logical(span: Span, left: Expr, op: LogicalOp, right: Expr)

    Top-level && / || expression, e.g. 0 && $have_debug. || splits before && (precedence), each side is a full expression — variables inside carry their own spans.

Text that may contain $variable_name references: an ordered list of parts. An empty list is empty text.

pub type InterpolatedText =
  List(TextPart)

The right-hand side of a let assignment.

pub type LetValue {
  Text(value: List(TextPart))
  QueryValue(query: QueryExpr)
  QueryGetValue(span: Span, args: List(List(TextPart)))
  Escape(
    span: Span,
    characters: List(TextPart),
    string: List(TextPart),
  )
  ConvertError(span: Span, argument: List(TextPart))
}

Constructors

  • Text(value: List(TextPart))

    Plain value (variable references substituted).

  • QueryValue(query: QueryExpr)

    `query` — the query’s result assigned to the variable.

  • QueryGetValue(span: Span, args: List(List(TextPart)))

    query_get_value(query, col, row [, resultset]) — 3 required args.

  • Escape(
      span: Span,
      characters: List(TextPart),
      string: List(TextPart),
    )

    escape(characters, string) — string kept verbatim (whitespace is significant).

  • ConvertError(span: Span, argument: List(TextPart))

    convert_error(error) — number ↔ name.

One source line: raw text without its line ending, UTF-16 offset of the line’s first code unit, 1-based line number.

pub type Line {
  Line(text: String, offset: Int, number: Int)
}

Constructors

  • Line(text: String, offset: Int, number: Int)

Top-level && / || operators.

pub type LogicalOp {
  And
  Or
}

Constructors

  • And
  • Or

A block terminator marker occurrence. A block declares its marker on the command line (open, zero-length span when implicit) and closes with the same marker alone on a line (close).

pub type Marker {
  Marker(name: String, span: Span)
}

Constructors

  • Marker(name: String, span: Span)

Backtick-enclosed query: `SELECT ...`. The content passes through do_eval before being sent (mysqltest.cc var_query_set: “Eval the query, thus replacing all environment variables” — identical in 5.7/26.7 and MariaDB), so $var references are parsed out and the rest is the SQL; SQL quotes do NOT protect a $.

pub type QueryExpr {
  QueryExpr(span: Span, query: List(TextPart))
}

Constructors

One /pattern/replacement/[i] rule of replace_regex.

pub type RegexRule {
  RegexRule(
    pattern: String,
    replacement: String,
    insensitive: Bool,
  )
}

Constructors

  • RegexRule(
      pattern: String,
      replacement: String,
      insensitive: Bool,
    )

Source location: 1-based line/column, offset into the source and length, both in UTF-16 code units — the unit VS Code/LSP positions and JS string indexing use, so consumers compare against document.offsetAt directly.

pub type Span {
  Span(line: Int, column: Int, offset: Int, len: Int)
}

Constructors

  • Span(line: Int, column: Int, offset: Int, len: Int)

The root AST node: one mysqltest statement, command, or line.

Unlike the Rust version (enum variants wrapping per-command structs), labelled variant fields hold the payload directly — no wrapper structs.

pub type Statement {
  Comment(span: Span, text: String)
  DashCommand(span: Span, dash: Span, statement: Statement)
  AppendFile(
    span: Span,
    filename: List(TextPart),
    open: Marker,
    close: Marker,
    content: String,
  )
  Assert(span: Span, expression: Expr)
  CatFile(span: Span, file: List(TextPart))
  ChangeUser(
    span: Span,
    user: option.Option(List(TextPart)),
    password: option.Option(List(TextPart)),
    database: option.Option(List(TextPart)),
  )
  CharacterSet(span: Span, charset: String)
  Chmod(span: Span, mode: String, file: List(TextPart))
  Connect(
    span: Span,
    name: option.Option(List(TextPart)),
    params: ConnectParams,
  )
  Connection(span: Span, name: List(TextPart))
  CopyFile(
    span: Span,
    source: List(TextPart),
    dest: List(TextPart),
    retry: option.Option(String),
  )
  CopyFilesWildcard(
    span: Span,
    source_dir: List(TextPart),
    dest_dir: List(TextPart),
    pattern: List(TextPart),
    retry: option.Option(String),
  )
  Dec(span: Span, variable: String, variable_span: Span)
  Toggle(span: Span, kind: ToggleKind, enable: Bool)
  ForceCpdir(
    span: Span,
    source_dir: List(TextPart),
    dest_dir: List(TextPart),
  )
  ForceRmdir(span: Span, dir: List(TextPart))
  HorizontalResults(span: Span)
  Let(
    span: Span,
    variable: String,
    variable_span: Span,
    value: LetValue,
  )
  ListFiles(
    span: Span,
    dir: option.Option(List(TextPart)),
    pattern: option.Option(List(TextPart)),
  )
  ListFilesAppendFile(
    span: Span,
    file: List(TextPart),
    dir: List(TextPart),
    pattern: option.Option(List(TextPart)),
  )
  ListFilesWriteFile(
    span: Span,
    file: List(TextPart),
    dir: List(TextPart),
    pattern: option.Option(List(TextPart)),
  )
  LowercaseResults(span: Span)
  Mkdir(span: Span, dir: List(TextPart))
  MoveFile(
    span: Span,
    source: List(TextPart),
    dest: List(TextPart),
    retry: option.Option(String),
  )
  Output(span: Span, file: List(TextPart))
  OptimizerTrace(span: Span)
  PsPrepare(span: Span, sql: List(TextPart))
  PsBind(span: Span, params: List(List(TextPart)))
  PsExecute(span: Span)
  PsClose(span: Span)
  SkipIfHypergraph(span: Span)
  WriteLine(
    span: Span,
    line: List(TextPart),
    file: List(TextPart),
  )
  Evalp(span: Span, statement: List(TextPart))
  Perl(span: Span, open: Marker, close: Marker, content: String)
  Ping(span: Span)
  QueryCommand(span: Span, sql: List(TextPart))
  QueryHorizontal(span: Span, sql: List(TextPart))
  QueryVertical(span: Span, sql: List(TextPart))
  Reap(span: Span)
  RealSleep(span: Span, seconds: List(TextPart))
  Require(span: Span, file: List(TextPart))
  QueryAttributes(
    span: Span,
    attributes: List(#(List(TextPart), List(TextPart))),
  )
  System(span: Span, command: List(TextPart))
  RemoveFile(
    span: Span,
    file: List(TextPart),
    retry: option.Option(String),
  )
  RemoveFilesWildcard(
    span: Span,
    dir: List(TextPart),
    pattern: List(TextPart),
    retry: option.Option(String),
  )
  ReplaceColumn(span: Span, pairs: List(#(Int, List(TextPart))))
  ReplaceNumericRound(span: Span, precision: Int)
  ReplaceRegex(span: Span, rules: List(RegexRule))
  ReplaceRegexVariable(span: Span, variable: List(TextPart))
  ReplaceResult(
    span: Span,
    pairs: List(#(List(TextPart), List(TextPart))),
  )
  ResetConnection(span: Span)
  ResultFormat(span: Span, version: Int)
  If(
    span: Span,
    condition: Expr,
    body: List(Statement),
    open_brace: Span,
    close_brace: Span,
  )
  While(
    span: Span,
    condition: Expr,
    body: List(Statement),
    open_brace: Span,
    close_brace: Span,
  )
  WriteFile(
    span: Span,
    filename: List(TextPart),
    open: Marker,
    close: Marker,
    content: String,
  )
  PartiallySortedResult(span: Span, start_column: Int)
  Rmdir(span: Span, dir: List(TextPart))
  SaveMasterPos(span: Span)
  Send(span: Span, sql: option.Option(String))
  SendEval(span: Span, sql: option.Option(List(TextPart)))
  SendQuit(span: Span, connection: List(TextPart))
  SendShutdown(span: Span)
  ShutdownServer(
    span: Span,
    timeout: option.Option(List(TextPart)),
  )
  Skip(span: Span, message: option.Option(String))
  Sleep(span: Span, seconds: List(TextPart))
  SortedResult(span: Span)
  Source(span: Span, file: List(TextPart))
  StartTimer(span: Span)
  SyncSlaveWithMaster(
    span: Span,
    connection: option.Option(List(TextPart)),
  )
  SyncWithMaster(
    span: Span,
    offset: option.Option(List(TextPart)),
  )
  VerticalResults(span: Span)
  WaitForSlaveToStop(span: Span)
  Inc(span: Span, variable: String, variable_span: Span)
  Delimiter(span: Span, new_delimiter: String)
  Die(span: Span, message: option.Option(String))
  DiffFiles(
    span: Span,
    file1: List(TextPart),
    file2: List(TextPart),
  )
  DirtyClose(span: Span, name: List(TextPart))
  Disconnect(span: Span, name: List(TextPart))
  DisableTestcase(span: Span, bug: String)
  EnableTestcase(span: Span)
  Echo(span: Span, text: List(TextPart))
  EndTimer(span: Span)
  Error(span: Span, error_codes: List(List(TextPart)))
  Eval(span: Span, statement: List(TextPart))
  Exec(span: Span, command: List(TextPart))
  ExecInBackground(span: Span, command: List(TextPart))
  Execw(span: Span, command: List(TextPart))
  Exit(span: Span)
  Expr(
    span: Span,
    variable: String,
    variable_span: Span,
    expression: String,
  )
  FileExists(
    span: Span,
    file: List(TextPart),
    retry: option.Option(String),
  )
  Sql(span: Span, sql: String)
}

Constructors

  • Comment(span: Span, text: String)

    # comment

  • DashCommand(span: Span, dash: Span, statement: Statement)

    -- command

  • AppendFile(
      span: Span,
      filename: List(TextPart),
      open: Marker,
      close: Marker,
      content: String,
    )

    append_file file_name [marker] … content … marker

  • Assert(span: Span, expression: Expr)

    assert (expr)

  • CatFile(span: Span, file: List(TextPart))

    cat_file file_name

  • ChangeUser(
      span: Span,
      user: option.Option(List(TextPart)),
      password: option.Option(List(TextPart)),
      database: option.Option(List(TextPart)),
    )

    change_user [user], [password], [db] — empty segments are None.

  • CharacterSet(span: Span, charset: String)

    character_set charset

  • Chmod(span: Span, mode: String, file: List(TextPart))

    chmod octal_mode file_name — mode kept as text (“0644” preserves the leading zero).

  • Connect(
      span: Span,
      name: option.Option(List(TextPart)),
      params: ConnectParams,
    )

    connect (name, host, …) / connect name / connect (reconnect the current connection).

  • Connection(span: Span, name: List(TextPart))

    connection name

  • CopyFile(
      span: Span,
      source: List(TextPart),
      dest: List(TextPart),
      retry: option.Option(String),
    )

    copy_file from_file to_file [retry]

  • CopyFilesWildcard(
      span: Span,
      source_dir: List(TextPart),
      dest_dir: List(TextPart),
      pattern: List(TextPart),
      retry: option.Option(String),
    )

    copy_files_wildcard src_dir dst_dir pattern [retry]

  • Dec(span: Span, variable: String, variable_span: Span)

    dec $var — variable_span covers the $name token (register $0-$9 included); real line/column, always on the statement’s first line.

  • Toggle(span: Span, kind: ToggleKind, enable: Bool)

    enable_X / disable_X — a boolean-setting toggle.

  • ForceCpdir(
      span: Span,
      source_dir: List(TextPart),
      dest_dir: List(TextPart),
    )

    force-cpdir src_dir dst_dir — recursive directory copy.

  • ForceRmdir(span: Span, dir: List(TextPart))

    force-rmdir dir_name

  • HorizontalResults(span: Span)

    horizontal_results — default result display format.

  • Let(
      span: Span,
      variable: String,
      variable_span: Span,
      value: LetValue,
    )

    let $var= value / let ENV_VAR= value — variable_span covers the $name (or bare environment-variable name) token; real line/column, always on the statement’s first line.

  • ListFiles(
      span: Span,
      dir: option.Option(List(TextPart)),
      pattern: option.Option(List(TextPart)),
    )

    list_files dir [pattern]

  • ListFilesAppendFile(
      span: Span,
      file: List(TextPart),
      dir: List(TextPart),
      pattern: option.Option(List(TextPart)),
    )

    list_files_append_file file dir [pattern]

  • ListFilesWriteFile(
      span: Span,
      file: List(TextPart),
      dir: List(TextPart),
      pattern: option.Option(List(TextPart)),
    )

    list_files_write_file file dir [pattern]

  • LowercaseResults(span: Span)

    lowercase_result

  • Mkdir(span: Span, dir: List(TextPart))

    mkdir dir_name

  • MoveFile(
      span: Span,
      source: List(TextPart),
      dest: List(TextPart),
      retry: option.Option(String),
    )

    move_file from to [retry]

  • Output(span: Span, file: List(TextPart))

    output file_name

  • OptimizerTrace(span: Span)

    optimizer_trace — (MariaDB) enable optimizer tracing.

  • PsPrepare(span: Span, sql: List(TextPart))

    ps_prepare statement — (MariaDB, Galera) prepare for later execution.

  • PsBind(span: Span, params: List(List(TextPart)))

    ps_bind value [value]... — (MariaDB) positional parameter values, typed at runtime (int / decimal / string).

  • PsExecute(span: Span)

    ps_execute — (MariaDB) execute the current prepared statement.

  • PsClose(span: Span)

    ps_close — (MariaDB) close the current prepared statement.

  • SkipIfHypergraph(span: Span)

    skip_if_hypergraph — (MySQL 8.0+) one-shot flag: skip the next query when running with –hypergraph.

  • WriteLine(span: Span, line: List(TextPart), file: List(TextPart))

    write_line line file_name — (MariaDB) append one line (a newline is added) to the file.

  • Evalp(span: Span, statement: List(TextPart))

    evalp statement — (MariaDB) prepare-execute-deallocate; shares eval’s form verbatim.

  • Perl(span: Span, open: Marker, close: Marker, content: String)

    perl [terminator] … code … terminator — the code is raw text (no variable interpolation).

  • Ping(span: Span)

    ping

  • QueryCommand(span: Span, sql: List(TextPart))

    query statement — force-send to the server even if it starts with a command keyword.

  • QueryHorizontal(span: Span, sql: List(TextPart))

    query_horizontal statement — execute and display horizontally (the Rust version collapsed this into argument-less HorizontalResults, dropping the statement — fixed here).

  • QueryVertical(span: Span, sql: List(TextPart))

    query_vertical statement — execute and display vertically.

  • Reap(span: Span)

    reap — collect the result of the last send.

  • RealSleep(span: Span, seconds: List(TextPart))

    real_sleep num — always uses the argument’s delay, unlike sleep (which honors the –sleep option).

  • Require(span: Span, file: List(TextPart))

    require file_name — (5.7) remember the result file for the next statement.

  • QueryAttributes(
      span: Span,
      attributes: List(#(List(TextPart), List(TextPart))),
    )

    query_attributes name value [name value]... — (8.0+) attach attributes to the next statement.

  • System(span: Span, command: List(TextPart))

    system command — (5.7, deprecated at runtime) shell command; parse only.

  • RemoveFile(
      span: Span,
      file: List(TextPart),
      retry: option.Option(String),
    )

    remove_file file_name [retry]

  • RemoveFilesWildcard(
      span: Span,
      dir: List(TextPart),
      pattern: List(TextPart),
      retry: option.Option(String),
    )

    remove_files_wildcard dir pattern [retry]

  • ReplaceColumn(span: Span, pairs: List(#(Int, List(TextPart))))

    replace_column col value [col value]... — column numbers from 1; values may be double-quoted (variables expanded when unquoted).

  • ReplaceNumericRound(span: Span, precision: Int)

    replace_numeric_round precision — digits after the decimal point.

  • ReplaceRegex(span: Span, rules: List(RegexRule))

    replace_regex /pattern/replacement/[i] ...

  • ReplaceRegexVariable(span: Span, variable: List(TextPart))
  • ReplaceResult(
      span: Span,
      pairs: List(#(List(TextPart), List(TextPart))),
    )

    replace_result from to [from to]... — quoted or bare values, variables expanded, matched literally.

  • ResetConnection(span: Span)

    reset_connection

  • ResultFormat(span: Span, version: Int)

    result_format version — 1 (default) or 2.

  • If(
      span: Span,
      condition: Expr,
      body: List(Statement),
      open_brace: Span,
      close_brace: Span,
    )

    if (expr) { body } — the body ends at a } or end line (the block terminator is consumed by the if, never a standalone statement).

  • While(
      span: Span,
      condition: Expr,
      body: List(Statement),
      open_brace: Span,
      close_brace: Span,
    )

    while (expr) { body } — same block structure as if.

  • WriteFile(
      span: Span,
      filename: List(TextPart),
      open: Marker,
      close: Marker,
      content: String,
    )

    write_file file [marker] … content … marker — the file must not exist.

  • PartiallySortedResult(span: Span, start_column: Int)

    partially_sorted_result start_column — first N columns presorted.

  • Rmdir(span: Span, dir: List(TextPart))

    rmdir dir_name

  • SaveMasterPos(span: Span)

    save_master_pos

  • Send(span: Span, sql: option.Option(String))

    send [statement] — no statement ⇒ applies to the next one.

  • SendEval(span: Span, sql: option.Option(List(TextPart)))

    send_eval [statement] — eval + send.

  • SendQuit(span: Span, connection: List(TextPart))

    send_quit connection

  • SendShutdown(span: Span)

    send_shutdown

  • ShutdownServer(
      span: Span,
      timeout: option.Option(List(TextPart)),
    )

    shutdown_server [timeout] — seconds; default 60 at runtime.

  • Skip(span: Span, message: option.Option(String))

    skip [message]

  • Sleep(span: Span, seconds: List(TextPart))

    sleep num — fractional seconds allowed.

  • SortedResult(span: Span)

    sorted_result

  • Source(span: Span, file: List(TextPart))

    source file_name

  • StartTimer(span: Span)

    start_timer

  • SyncSlaveWithMaster(
      span: Span,
      connection: option.Option(List(TextPart)),
    )

    sync_slave_with_master [connection]

  • SyncWithMaster(span: Span, offset: option.Option(List(TextPart)))

    sync_with_master offset

  • VerticalResults(span: Span)

    vertical_results

  • WaitForSlaveToStop(span: Span)

    wait_for_slave_to_stop

  • Inc(span: Span, variable: String, variable_span: Span)

    inc $var — variable_span covers the $name token (register $0-$9 included); real line/column, always on the statement’s first line.

  • Delimiter(span: Span, new_delimiter: String)

    delimiter str — the only command that changes parser state.

  • Die(span: Span, message: option.Option(String))

    die [message]

  • DiffFiles(
      span: Span,
      file1: List(TextPart),
      file2: List(TextPart),
    )

    diff_files file_name1 file_name2

  • DirtyClose(span: Span, name: List(TextPart))

    dirty_close connection_name

  • Disconnect(span: Span, name: List(TextPart))

    disconnect connection_name

  • DisableTestcase(span: Span, bug: String)

    disable_testcase BUG#NNNN — disable a section due to a known bug.

  • EnableTestcase(span: Span)

    enable_testcase — re-enable the section.

  • Echo(span: Span, text: List(TextPart))

    echo text

  • EndTimer(span: Span)

    end_timer — stop the timer.

  • Error(span: Span, error_codes: List(List(TextPart)))

    error code[, code]... — expected errors for the next command (numbers, S-prefixed SQLSTATE, or symbolic names).

  • Eval(span: Span, statement: List(TextPart))

    eval statement — variable expansion, then sent to the server.

  • Exec(span: Span, command: List(TextPart))

    exec command [arg]... — run a shell command.

  • ExecInBackground(span: Span, command: List(TextPart))

    exec_in_background command [arg]...

  • Execw(span: Span, command: List(TextPart))

    execw command [arg]... — Windows non-ASCII variant of exec.

  • Exit(span: Span)

    exit — normal termination of the test case.

  • Expr(
      span: Span,
      variable: String,
      variable_span: Span,
      expression: String,
    )

    expr $var= operand operator operand — variable_span covers the $name token; the right-hand expression is kept raw (the calculator grammar is a runtime concern).

  • FileExists(
      span: Span,
      file: List(TextPart),
      retry: option.Option(String),
    )

    file_exists file_name [retry]

  • Sql(span: Span, sql: String)

    SQL statement, or unrecognized command text (degraded).

A segment: literal text, or a variable reference (name without $).

pub type TextPart {
  Literal(text: String, span: Span)
  Variable(name: String, span: Span)
}

Constructors

  • Literal(text: String, span: Span)
  • Variable(name: String, span: Span)

The boolean settings toggled by enable_X / disable_X.

pub type ToggleKind {
  AbortOnError
  AsyncClient
  ConnectLog
  Info
  Metadata
  PsProtocol
  QueryLog
  ResultLog
  RplParse
  SessionTrackInfo
  Parsing
  Reconnect
  PrepareWarnings
  CursorProtocol
  NonBlockingApi
  Ps2Protocol
  ServiceConnection
  ViewProtocol
  ColumnNames
  Warnings
}

Constructors

  • AbortOnError
  • AsyncClient
  • ConnectLog
  • Info
  • Metadata
  • PsProtocol
  • QueryLog
  • ResultLog
  • RplParse
  • SessionTrackInfo
  • Parsing
  • Reconnect
  • PrepareWarnings
  • CursorProtocol
  • NonBlockingApi
  • Ps2Protocol
  • ServiceConnection
  • ViewProtocol
  • ColumnNames
  • Warnings

$variable_name reference.

pub type VariableRef {
  VariableRef(span: Span, name: String)
}

Constructors

  • VariableRef(span: Span, name: String)

Values

pub fn span(statement: Statement) -> Span

The span of a statement.

✨ Search Document