Documentation
¶
Overview ¶
Package sqlparse provides a lightweight MySQL tokenizer.
It is not a full parser. Its job is to answer the questions guard and the editor ask — where does a statement start and end, what kind is it, does it have a top-level WHERE — with enough precision that literals, comments and quoted identifiers can never be mistaken for syntax.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AppendLimit ¶
AppendLimit returns stmt's SQL with "LIMIT n" inserted, or the SQL unchanged when doing so would be unsafe.
Insertion is by token position rather than string concatenation, because the two shapes that break naive appending are common:
- a trailing comment would swallow the clause
- a locking clause (FOR UPDATE, LOCK IN SHARE MODE) must follow LIMIT, not precede it
Shapes this cannot place the clause in confidently — SELECT ... INTO — are returned untouched. An over-large result set is an inconvenience; a query rewritten into invalid SQL destroys trust in the tool.
func IsIdentifierByte ¶
IsIdentifierByte reports whether a byte can appear in an unquoted MySQL identifier.
It is exported so that cursor movement in the editor uses the same notion of a word as the tokenizer does. Without that, "user_id" would be one word to completion and three to the arrow keys, and the difference would be impossible for a user to account for.
func QuoteIdentifier ¶
QuoteIdentifier renders a name as a backtick-quoted MySQL identifier.
A backtick inside a name is escaped by doubling it, which is MySQL's own rule. Without this, a table called "we`ird" would end the quoted section early and turn the rest of the name into syntax.
It lives here rather than beside either of its callers because both the catalog and the query stream paste identifiers into statements, and a second copy of this rule is a second place for it to be got wrong.
Types ¶
type CompletionContext ¶
type CompletionContext struct {
Kind CompletionKind
// Prefix is the partial identifier already typed.
Prefix string
// Qualifier is the name before the dot, when Kind is CompleteQualified.
Qualifier string
// Tables are the statement's tables, so a qualifier can be resolved
// without parsing again.
Tables []TableRef
// ReplaceFrom and ReplaceTo delimit the text a chosen candidate replaces.
ReplaceFrom, ReplaceTo int
}
CompletionContext describes what to offer at a caret position.
func CompletionAt ¶
func CompletionAt(sql string, offset int) CompletionContext
CompletionAt analyses the caret position within sql.
The whole statement is parsed, not just the text before the caret: in "SELECT u.| FROM users u" the meaning of "u" is established after the caret, and looking only backwards would leave it unresolvable.
type CompletionKind ¶
type CompletionKind int
CompletionKind says what sort of name belongs at the caret.
const ( // CompleteNone means nothing should be offered — inside a literal, a // comment, or before any clause has established a context. CompleteNone CompletionKind = iota // CompleteTable means a table name is expected. CompleteTable // CompleteColumn means a column of the statement's tables is expected. CompleteColumn // CompleteQualified means the caret follows "something.", where the // qualifier is either a table alias or a schema name. CompleteQualified )
type Statement ¶
Statement is one SQL statement with its tokens and its span in the source buffer. The span lets the editor highlight exactly what will run.
func Split ¶
Split breaks sql into statements on unquoted semicolons. Blank statements and comment-only fragments are dropped.
func StatementAt ¶
StatementAt returns the statement containing the byte offset, which is how Ctrl+Enter decides what to run.
Whitespace between statements attaches to the preceding one: a cursor resting just after "SELECT 1;" belongs to that statement, not to whatever comes next. Running the following statement there would be a surprise.
func (Statement) HasTopLevelLimit ¶
HasTopLevelLimit reports whether the statement already limits its result, which is what stops the auto-limit from overriding an explicit choice.
func (Statement) HasTopLevelWhere ¶
HasTopLevelWhere reports whether the statement is bounded by a WHERE clause of its own, ignoring any that belong to subqueries.
type StmtKind ¶
type StmtKind int
StmtKind classifies a statement by what it does to the server.
const ( // StmtOther is anything not recognised. Guard treats it as unsafe. StmtOther StmtKind = iota // StmtSelect reads rows. StmtSelect // StmtRead is a non-SELECT read: SHOW, DESCRIBE, EXPLAIN. StmtRead // StmtSession changes connection state: USE, SET. StmtSession // StmtInsert adds rows (INSERT, REPLACE). StmtInsert // StmtUpdate modifies rows. StmtUpdate // StmtDelete removes rows and can be bounded by WHERE. StmtDelete // StmtTruncate empties a table and cannot be bounded or rolled back. StmtTruncate // StmtDrop removes a schema object. StmtDrop // StmtDDL is any other schema change: CREATE, ALTER, RENAME. StmtDDL )
type TableRef ¶
type TableRef struct {
Schema string
Name string
Alias string
// Derived marks a subquery: it has an alias but no name to look up.
Derived bool
}
TableRef is one entry of a FROM, JOIN, UPDATE or INSERT clause.
func ResolveQualifier ¶
ResolveQualifier finds the table a qualifier stands for.
An alias wins; failing that, a table answers to its own name, which is what makes "users.id" work in a statement that never aliased users.
type Token ¶
type Token struct {
Kind Kind
Text string
// Pos and End delimit the token in the input as a half-open byte range.
Pos, End int
// Depth is the parenthesis nesting level at the token's start. A
// top-level clause has Depth 0; anything inside a subquery is deeper.
Depth int
}
Token is a single lexical element with its source span.