sqlscript

package
v1.0.0-rc.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 5, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package sqlscript lexes and splits SQL scripts.

The console and the importer both need to break an uploaded or typed script into statements, and doing that correctly means a full quote/comment-aware lexer: string escapes, dollar quoting, bracket identifiers, DELIMITER directives, TableX's opaque frames and procedural BEGIN…END bodies. That is ~800 lines of pure text processing which lived inside the HTTP handler package, importing nothing from net/http.

The grammar itself is not defined here: it comes from the dialect, as a driver.LexerProfile, so the splitter never branches on an engine name.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsQuery

func IsQuery(stmt string, p driver.LexerProfile) bool

IsQuery reports whether stmt should be run as a row-returning query (p is the dialect's lexer profile, as for Scan). Keywords are matched on a skeleton with string literals and comments blanked out, so a literal value like INSERT ... VALUES ('RETURNING') cannot mis-route the statement.

func ParseConnectLine

func ParseConnectLine(line string) (db string, ok bool, err error)

ParseConnectLine recognizes a `\connect dbname` / `\c dbname` line and extracts the database name with psql's tokenization: the name ends at the first unquoted whitespace (trailing username/host/port arguments are ignored), double-quoted segments may embed doubled quotes and concatenate with adjacent unquoted text, and an unterminated quote is an error — psql would not read it as a name, so silently targeting a mangled one is worse than failing the import.

func Split

func Split(script string, p driver.LexerProfile) []string

Split splits a SQL script into individual statements on top-level statement separators, dropping marker events (see Scan).

Types

type Event

type Event struct {
	Stmt   string
	Marker *driver.DumpMarker
}

Event is one item of a scanned script, in source order: an executable statement (marker == nil), or a validated TableX db-collation marker the import path surfaces as a warning check. The console path ignores markers.

func Scan

func Scan(script string, p driver.LexerProfile) []Event

Scan tokenizes a SQL script into executable statements plus validated TableX marker events, in source order. Lexing is grammar-driven via the dialect's driver.LexerProfile:

  • single/double/backtick quoted strings with doubled-quote escapes (all engines), plus backslash escapes inside '...' / "..." strings where the profile says so (MySQL) and inside E'…' escape strings (PostgreSQL);
  • `--` and /* */ comments; `#` line comments and the "-- must be followed by whitespace" rule are profile-gated (MySQL);
  • dollar-quoted strings ($$...$$ / $tag$...$tag$) where enabled (PostgreSQL) — `$` is an ordinary identifier character in MySQL and SQLite (a$$b must not open a quote);
  • mysql-client `DELIMITER` directives, so dumped routine/trigger bodies round-trip exactly as the mysql CLI would run them. Ordinary DELIMITER blocks keep full quote-aware lexing — an uploaded script may legally carry its delimiter inside a string literal ('a//b' under DELIMITER //);
  • TableX opaque frames (a frame marker line + DELIMITER wrap around a binary-fetched object body): the framed bytes are replayed VERBATIM as one statement with no string/comment interpretation and no re-encoding — the body may be non-UTF-8 or authored under NO_BACKSLASH_ESCAPES, where ordinary lexing would mis-split. Opacity is keyed strictly on TableX's own marker, never on "any non-default delimiter";
  • BEGIN...END procedural bodies of routine-creating statements (profile regex), so the semicolons inside a trigger or routine body do not split the statement;
  • chunks containing only comments are dropped: they execute as nothing, and some drivers (modernc.org/sqlite) return a nil result for them.

Statements are emitted as trimmed spans of the ORIGINAL script bytes — lexing tracks byte offsets, never a rune rebuild, so invalid UTF-8 passes through unreplaced (no U+FFFD substitution).

type Section

type Section struct {
	DB     string
	Script string
}

Section is a chunk of a restore script bound to one database (db == "" means the import target).

func SplitRestoreSections

func SplitRestoreSections(script string, allowConnect bool) ([]Section, error)

SplitRestoreSections splits a script on lines holding psql-style \connect (or \c) markers. Text before the first marker belongs to the import target. Recognition is gated: only a PostgreSQL server-scope import (allowConnect) honors markers — TableX emits them only in that dump shape, and honoring one in a db/table-scoped import would silently execute part of the script against another database. When enabled, the scan is quote-aware with PostgreSQL rules: a \connect line inside a '…' / E'…' / "…" / $tag$…$tag$ span or a comment is content, never a marker. A recognized marker with an unterminated quoted name is a hard error, not a mis-split.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL