Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions lex/dialect_sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,17 @@ func lexAs(l *Lexer) StateFn {
}
return nil
}
func lexOn(l *Lexer) StateFn {
l.SkipWhiteSpaces()
keyWord := strings.ToLower(l.PeekWord())
switch keyWord {
case "on":
l.ConsumeWord(keyWord)
l.Emit(TokenOn)
return nil
}
return nil
}
func lexNotExists(l *Lexer) StateFn {
l.SkipWhiteSpaces()
keyWord := strings.ToLower(l.PeekWord())
Expand Down Expand Up @@ -534,6 +545,9 @@ func LexDrop(l *Lexer) StateFn {
case "table":
l.ConsumeWord(keyWord)
l.Emit(TokenTable)
case "index":
l.ConsumeWord(keyWord)
l.Emit(TokenIndex)
case "source":
l.ConsumeWord(keyWord)
l.Emit(TokenSource)
Expand All @@ -553,6 +567,8 @@ func LexDrop(l *Lexer) StateFn {
return nil
}
l.Push("LexIdentifier", LexIdentifier)
l.Push("LexOn", lexOn)
l.Push("LexIdentifier", LexIdentifier)
return lexNotExists
}

Expand Down
27 changes: 23 additions & 4 deletions rel/parse_sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -860,28 +860,47 @@ func (m *Sqlbridge) parseDrop() (*SqlDrop, error) {
req.Temp = true
}

// DROP (TABLE|VIEW|SOURCE|CONTINUOUSVIEW) <identity>
// DROP (TABLE|VIEW|SOURCE|INDEX|CONTINUOUSVIEW) <identity>
switch m.Cur().T {
case lex.TokenTable, lex.TokenView, lex.TokenSource, lex.TokenContinuousView,
case lex.TokenTable, lex.TokenView, lex.TokenIndex, lex.TokenSource, lex.TokenContinuousView,
lex.TokenSchema, lex.TokenDatabase:
req.Tok = m.Next()
case lex.TokenIdentity:
// triggers, indexes
req.Tok = m.Next()
default:
return nil, m.ErrMsg("Expected view, database,schema, table, source, continuousview for DROP got")
return nil, m.ErrMsg("Expected view, database, index, schema, table, source, continuousview for DROP got")
}

if m.Cur().T == lex.TokenIf {
m.Next() // Consume IF
if m.Next().T != lex.TokenExists {
return nil, m.ErrMsg("Expected CREATE {TABLE|INDEX|SCHEMA|DATABASE} IF EXISTS <identity>")
}
req.IfExists = true
}

switch m.Cur().T {
case lex.TokenTable, lex.TokenIdentity:
req.Identity = m.Next().V
default:
return nil, m.ErrMsg("Expected identity after DROP (TABLE|VIEW|SOURCE|SCHEMA|DATABASE) ")
return nil, m.ErrMsg("Expected identity after DROP (TABLE|INDEX|VIEW|SOURCE|SCHEMA|DATABASE) ")
}

switch req.Tok.T {
case lex.TokenTable:
// just table
case lex.TokenIndex:
t := m.Next() // consume ON
if t.T != lex.TokenOn {
return nil, m.ErrMsg("Expected ON")
}
t = m.Next() // consume Identity
if t.T != lex.TokenIdentity {
return nil, m.ErrMsg("Expected Identity table name")
}
req.Parent = t.V
discardComments(m)
case lex.TokenSource, lex.TokenSchema:
// schema
case lex.TokenContinuousView, lex.TokenView:
Expand Down
26 changes: 24 additions & 2 deletions rel/parse_sql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -740,13 +740,35 @@ func TestSqlDrop(t *testing.T) {
t.Parallel()
sql := `DROP TABLE articles;`
req, err := rel.ParseSql(sql)
assert.Equal(t, nil, err)
assert.NotEqual(t, nil, req)
assert.NoError(t, err)
assert.NotNil(t, req)
ds, ok := req.(*rel.SqlDrop)
assert.True(t, ok, "wanted SqlDrop got %T", req)
assert.Equal(t, lex.TokenDrop, ds.Keyword(), "Has keyword DROP")
assert.Equal(t, "TABLE", ds.Tok.V, "Wanted TABLE: got %q", ds.Tok.V)
assert.Equal(t, "articles", ds.Identity, "has articles: %v", ds.Identity)

sql = `DROP INDEX idx_user_email ON users;`
req, err = rel.ParseSql(sql)
assert.NoError(t, err)
assert.NotNil(t, req)
ds, ok = req.(*rel.SqlDrop)
assert.True(t, ok, "wanted SqlDrop got %T", req)
assert.Equal(t, lex.TokenDrop, ds.Keyword(), "Has keyword DROP")
assert.Equal(t, "INDEX", ds.Tok.V, "Wanted INDEX: got %q", ds.Tok.V)
assert.Equal(t, "idx_user_email", ds.Identity, "has idx_user_email: %v", ds.Identity)

sql = `DROP INDEX IF EXISTS idx_user_name ON users;`
req, err = rel.ParseSql(sql)
assert.NoError(t, err)
assert.NotNil(t, req)
ds, ok = req.(*rel.SqlDrop)
assert.True(t, ok, "wanted SqlDrop got %T", req)
assert.Equal(t, lex.TokenDrop, ds.Keyword(), "Has keyword DROP")
assert.Equal(t, "INDEX", ds.Tok.V, "Wanted INDEX: got %q", ds.Tok.V)
assert.Equal(t, "idx_user_name", ds.Identity, "has idx_user_name: %v", ds.Identity)
assert.Equal(t, "users", ds.Parent, "has table users: %v", ds.Parent)
assert.True(t, ds.IfExists, "Expected IfExists to be true")
}

func TestWithNameValue(t *testing.T) {
Expand Down
2 changes: 2 additions & 0 deletions rel/sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@ type (
Temp bool // Temp?
Tok lex.Token // DROP [TEMP] [TABLE,VIEW,CONTINUOUSVIEW,TRIGGER] etc
With u.JsonHelper
IfExists bool
Parent string
}
// SqlAlter SQL ALTER statement
SqlAlter struct {
Expand Down