turso
This commit is contained in:
117
vendor/github.com/libsql/sqlite-antlr4-parser/sqliteparserutils/utils.go
generated
vendored
Normal file
117
vendor/github.com/libsql/sqlite-antlr4-parser/sqliteparserutils/utils.go
generated
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
package sqliteparserutils
|
||||
|
||||
import (
|
||||
"github.com/antlr/antlr4/runtime/Go/antlr/v4"
|
||||
"github.com/libsql/sqlite-antlr4-parser/sqliteparser"
|
||||
)
|
||||
|
||||
// TODO: Shell test begin transaction on shell
|
||||
|
||||
type SplitStatementExtraInfo struct {
|
||||
IncompleteCreateTriggerStatement bool
|
||||
IncompleteMultilineComment bool
|
||||
LastTokenType int
|
||||
}
|
||||
|
||||
func SplitStatement(statement string) (stmts []string, extraInfo SplitStatementExtraInfo) {
|
||||
tokenStream := createTokenStream(statement)
|
||||
|
||||
stmtIntervals := make([]*antlr.Interval, 0)
|
||||
currentIntervalStart := -1
|
||||
insideCreateTriggerStmt := false
|
||||
insideMultilineComment := false
|
||||
|
||||
var previousToken antlr.Token
|
||||
var currentToken antlr.Token
|
||||
for currentToken = tokenStream.LT(1); currentToken.GetTokenType() != antlr.TokenEOF; currentToken = tokenStream.LT(1) {
|
||||
// We break loop here because we're sure multiline comment didn't finished, otherwise lexer would have just ignored
|
||||
// it
|
||||
if atIncompleteMultilineCommentStart(tokenStream) {
|
||||
insideMultilineComment = true
|
||||
break
|
||||
}
|
||||
|
||||
if currentIntervalStart == -1 {
|
||||
if currentToken.GetTokenType() == sqliteparser.SQLiteLexerSCOL {
|
||||
previousToken = currentToken
|
||||
tokenStream.Consume()
|
||||
continue
|
||||
}
|
||||
currentIntervalStart = currentToken.GetTokenIndex()
|
||||
|
||||
if atCreateTriggerStart(tokenStream) {
|
||||
insideCreateTriggerStmt = true
|
||||
previousToken = currentToken
|
||||
tokenStream.Consume()
|
||||
continue
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if insideCreateTriggerStmt {
|
||||
if currentToken.GetTokenType() == sqliteparser.SQLiteLexerEND_ {
|
||||
insideCreateTriggerStmt = false
|
||||
}
|
||||
} else if currentToken.GetTokenType() == sqliteparser.SQLiteLexerSCOL {
|
||||
stmtIntervals = append(stmtIntervals, antlr.NewInterval(currentIntervalStart, previousToken.GetTokenIndex()))
|
||||
currentIntervalStart = -1
|
||||
}
|
||||
|
||||
previousToken = currentToken
|
||||
tokenStream.Consume()
|
||||
}
|
||||
|
||||
if currentIntervalStart != -1 && previousToken != nil {
|
||||
stmtIntervals = append(stmtIntervals, antlr.NewInterval(currentIntervalStart, previousToken.GetTokenIndex()))
|
||||
}
|
||||
|
||||
stmts = make([]string, 0)
|
||||
for _, stmtInterval := range stmtIntervals {
|
||||
stmts = append(stmts, tokenStream.GetTextFromInterval(stmtInterval))
|
||||
}
|
||||
|
||||
lastTokenType := antlr.TokenInvalidType
|
||||
if previousToken != nil {
|
||||
lastTokenType = previousToken.GetTokenType()
|
||||
}
|
||||
return stmts, SplitStatementExtraInfo{IncompleteCreateTriggerStatement: insideCreateTriggerStmt, IncompleteMultilineComment: insideMultilineComment, LastTokenType: lastTokenType}
|
||||
}
|
||||
|
||||
func atCreateTriggerStart(tokenStream antlr.TokenStream) bool {
|
||||
if tokenStream.LT(1).GetTokenType() != sqliteparser.SQLiteLexerCREATE_ {
|
||||
return false
|
||||
}
|
||||
|
||||
if tokenStream.LT(2).GetTokenType() == sqliteparser.SQLiteLexerTRIGGER_ {
|
||||
return true
|
||||
}
|
||||
|
||||
if tokenStream.LT(2).GetTokenType() == sqliteparser.SQLiteLexerTEMP_ || tokenStream.LT(2).GetTokenType() == sqliteparser.SQLiteLexerTEMPORARY_ &&
|
||||
tokenStream.LT(3).GetTokenType() == sqliteparser.SQLiteLexerTRIGGER_ {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
|
||||
}
|
||||
|
||||
// Note: Only starts for incomplete multiline comments will be detected cause lexer automatically ignores complete
|
||||
// multiline comments
|
||||
func atIncompleteMultilineCommentStart(tokenStream antlr.TokenStream) bool {
|
||||
if tokenStream.LT(1).GetTokenType() != sqliteparser.SQLiteLexerDIV {
|
||||
return false
|
||||
}
|
||||
|
||||
if tokenStream.LT(2).GetTokenType() == sqliteparser.SQLiteLexerSTAR {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func createTokenStream(statement string) *antlr.CommonTokenStream {
|
||||
statementStream := antlr.NewInputStream(statement)
|
||||
|
||||
lexer := sqliteparser.NewSQLiteLexer(statementStream)
|
||||
return antlr.NewCommonTokenStream(lexer, 0)
|
||||
}
|
||||
Reference in New Issue
Block a user