Skip to content

Commit 673b9c5

Browse files
committed
🩹 Ensure the query splitter handle comments
So that when someone use anyquery run [id], the query splitter for the shell doesn't mess with comments
1 parent c73835e commit 673b9c5

File tree

2 files changed

+51
-5
lines changed

2 files changed

+51
-5
lines changed

controller/shell.go

+31-5
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ func (p *shell) AddMiddleware(m middleware) {
146146
//
147147
// If a middleware returns false, the pipeline stops.
148148
// The pipeline will always run the middlewares in the order they were added
149-
func (p *shell) Run(rawQuery string) bool {
149+
func (p *shell) Run(rawQuery string, args ...interface{}) bool {
150150
queries := splitMultipleQuery(rawQuery)
151151

152152
if len(queries) == 0 {
@@ -163,6 +163,7 @@ func (p *shell) Run(rawQuery string) bool {
163163
SQLQuery: query,
164164
Config: p.Config,
165165
DB: p.DB,
166+
Args: args,
166167
}
167168

168169
// If the query is .read, we read the file
@@ -407,7 +408,7 @@ func splitMultipleQuery(sqlQuery string) []string {
407408
// isDotCommand => true if the query is a dot command or a slash command
408409
// isEscaped => true if the character is escaped (in a string '' or "")
409410
// mustResetWord => true if we find a query that can be appened to queries
410-
var isDotCommand, isEscapedSimpleQuote, isEscapedDoubleQuote, mustResetWord bool
411+
var isDotCommand, isEscapedSimpleQuote, isEscapedDoubleQuote, isMultiLineComment, isSingleLineComment, mustResetWord bool
411412

412413
queries := make([]string, 0)
413414
// The index character of the current query
@@ -431,6 +432,25 @@ func splitMultipleQuery(sqlQuery string) []string {
431432
isDotCommand = true
432433
}
433434

435+
case '/':
436+
if len(sqlQuery) > i+1 && sqlQuery[i+1] == '*' {
437+
isMultiLineComment = true
438+
}
439+
440+
case '*':
441+
// If we find a star and we are in a slash command
442+
// we can assume that it is the end of the slash command
443+
if isMultiLineComment && len(sqlQuery) > i+1 &&
444+
sqlQuery[i+1] == '/' {
445+
isMultiLineComment = false
446+
}
447+
case '-':
448+
// If we find a dash and we are at the beginning of the query
449+
// we can assume that it is a single line comment
450+
if i == 0 && len(sqlQuery) > i+1 && sqlQuery[i+1] == '-' {
451+
isSingleLineComment = true
452+
}
453+
434454
case '.':
435455
// If we find a dot and we are at the beginning of the query
436456
// we can assume that it is a dot command
@@ -454,7 +474,7 @@ func splitMultipleQuery(sqlQuery string) []string {
454474
//
455475
// It could be simplified as mustResetWord = condition
456476
// but I prefer to keep it like this for readability
457-
if !isEscapedSimpleQuote && !isEscapedDoubleQuote {
477+
if !isEscapedSimpleQuote && !isEscapedDoubleQuote && !isMultiLineComment && !isSingleLineComment {
458478
mustResetWord = true
459479
}
460480

@@ -467,17 +487,21 @@ func splitMultipleQuery(sqlQuery string) []string {
467487

468488
// If we find a newline, we're not in a string
469489
// and it's a dot command, it means that the query is finished
470-
if !isEscapedSimpleQuote && !isEscapedDoubleQuote && isDotCommand {
490+
if !isEscapedSimpleQuote && !isEscapedDoubleQuote && !isMultiLineComment && !isSingleLineComment && isDotCommand {
471491
mustResetWord = true
472492
}
473493

494+
if isSingleLineComment {
495+
isSingleLineComment = false
496+
}
497+
474498
}
475499

476500
// We append the character to the query
477501
// unless it is a newline and it is a dot command
478502
//
479503
// Or it's a ; and we are not in a string
480-
if !((c == '\n' && isDotCommand) || (c == ';' && !isEscapedSimpleQuote && !isEscapedDoubleQuote)) {
504+
if !((c == '\n' && isDotCommand) || (c == ';' && !isEscapedSimpleQuote && !isEscapedDoubleQuote && !isMultiLineComment && !isSingleLineComment)) {
481505
tempQuery.WriteRune(c)
482506
}
483507
currentPosition++
@@ -495,6 +519,8 @@ func splitMultipleQuery(sqlQuery string) []string {
495519
mustResetWord = false
496520
isEscapedSimpleQuote = false
497521
isEscapedDoubleQuote = false
522+
isMultiLineComment = false
523+
isSingleLineComment = false
498524
}
499525

500526
}

controller/shell_test.go

+20
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,26 @@ func TestQuerySplitter(t *testing.T) {
6464
query: " .mode\n\nSELECT * FROM table; .exit ",
6565
expected: []string{".mode", "SELECT * FROM table", ".exit"},
6666
},
67+
{
68+
name: "a query with a comment and a sql command",
69+
query: `-- This is a; comment
70+
SELECT * FROM table`,
71+
expected: []string{"-- This is a; comment\nSELECT * FROM table"},
72+
},
73+
{
74+
name: "a query with a multi-line comment and a sql command",
75+
query: `/*
76+
This is a multi-line comment; with a semi-colon
77+
Hey
78+
*/
79+
SELECT * FROM table; .exit`,
80+
expected: []string{"/*\nThis is a multi-line comment; with a semi-colon\nHey\n*/\nSELECT * FROM table", ".exit"},
81+
},
82+
{
83+
name: "a query with a multi-line comment in the middle of a sql command",
84+
query: `SELECT * /* This is a 'multi-line' comment; with "a" semi-colon*/ FROM table; .exit`,
85+
expected: []string{"SELECT * /* This is a 'multi-line' comment; with \"a\" semi-colon*/ FROM table", ".exit"},
86+
},
6787
}
6888

6989
for _, tt := range test {

0 commit comments

Comments
 (0)