diff --git a/kind.go b/kind.go index 3656efb..570501f 100644 --- a/kind.go +++ b/kind.go @@ -6,19 +6,20 @@ import ( ) const ( - KindUnknown = "unknown" - KindSelect = "select" - KindLoad = "load" - KindInsert = "insert" - KindUpdate = "update" - KindMerge = "merge" - KindDelete = "delete" - KindRegisterType = "register type" - KindRegisterSet = "register set" - KindCreateTable = "create table" - KindDropTable = "drop table" - KindCreateIndex = "create index" - KindDropIndex = "drop index" + KindUnknown = "unknown" + KindSelect = "select" + KindLoad = "load" + KindInsert = "insert" + KindUpdate = "update" + KindMerge = "merge" + KindDelete = "delete" + KindRegisterType = "register type" + KindRegisterSet = "register set" + KindCreateTable = "create table" + KindDropTable = "drop table" + KindCreateIndex = "create index" + KindDropIndex = "drop index" + KindTruncateTable = "truncate table" ) // Kind represents the type of SQL statement. @@ -139,6 +140,15 @@ func ParseKind(SQL string) Kind { return KindDropIndex } } + case 't': + if len(secondToken) == 0 { + return KindUnknown + } + switch secondToken[0] { + case 't': //truncate + return KindTruncateTable + } + case 'r': //register if len(secondToken) == 0 { return KindUnknown diff --git a/lex.go b/lex.go index 2c48eda..1443a35 100644 --- a/lex.go +++ b/lex.go @@ -74,6 +74,7 @@ const ( registerKeyword typeKeyword ttlKeyword + truncateTableKeyword ) var whitespaceMatcher = parsly.NewToken(whitespaceCode, "whitespace", matcher.NewWhiteSpace()) @@ -96,6 +97,7 @@ var inlineCommentMatcher = parsly.NewToken(commentBlock, "--", matcher.NewSeqBlo var selectKeywordMatcher = parsly.NewToken(selectKeyword, "SELECT", matcher.NewKeyword("select", &option.Case{})) var exceptKeywordMatcher = parsly.NewToken(exceptKeyword, "EXCEPT", matcher.NewKeyword("except", &option.Case{})) var betweenKeywordMatcher = parsly.NewToken(betweenToken, "BETWEEN", matcher.NewKeyword("between", &option.Case{})) +var truncateKeywordMatcher = parsly.NewToken(truncateTableKeyword, "TRUNCATE", matcher.NewSpacedFragment("truncate table", &option.Case{})) var fromKeywordMatcher = parsly.NewToken(fromKeyword, "FROM", matcher.NewKeyword("from", &option.Case{})) var joinMatcher = parsly.NewToken(joinToken, "LEFT OUTER JOIN|LEFT JOIN|JOIN", matcher.NewSpacedSet([]string{ diff --git a/table.go b/table.go index b9ab836..8e7df58 100644 --- a/table.go +++ b/table.go @@ -13,7 +13,7 @@ import ( "github.com/viant/sqlparser/update" ) -//TableName returns main table name +// TableName returns main table name func TableName(node node.Node) string { switch actual := node.(type) { case *query.Select: @@ -73,7 +73,35 @@ func trimEnclosure(node node.Node) string { return name } -//ParseDropTable parses drop table +// ParseTruncateTable parses truncate table +func ParseTruncateTable(SQL string) (*table.Truncate, error) { + result := &table.Truncate{} + SQL = removeSQLComments(SQL) + cursor := parsly.NewCursor("", []byte(SQL), 0) + err := parseTruncateTable(cursor, result) + if err != nil { + return result, fmt.Errorf("%s", SQL) + } + return result, err +} + +func parseTruncateTable(cursor *parsly.Cursor, result *table.Truncate) error { + match := cursor.MatchAfterOptional(whitespaceMatcher, truncateKeywordMatcher) + if match.Code != truncateTableKeyword { + return cursor.NewError(truncateKeywordMatcher) + } + if match = cursor.MatchOne(whitespaceMatcher); match.Code != whitespaceCode { + return cursor.NewError(whitespaceMatcher) + } + match = cursor.MatchAfterOptional(whitespaceMatcher, identifierMatcher) + if match.Code != identifierCode { + return cursor.NewError(identifierMatcher) + } + result.Table = match.Text(cursor) + return nil +} + +// ParseDropTable parses drop table func ParseDropTable(SQL string) (*table.Drop, error) { result := &table.Drop{} SQL = removeSQLComments(SQL) @@ -104,7 +132,7 @@ func parseDropTable(cursor *parsly.Cursor, dest *table.Drop) error { return nil } -//ParseCreateTable parses create table +// ParseCreateTable parses create table func ParseCreateTable(SQL string) (*table.Create, error) { result := &table.Create{} SQL = removeSQLComments(SQL) diff --git a/table/truncate.go b/table/truncate.go new file mode 100644 index 0000000..6194b77 --- /dev/null +++ b/table/truncate.go @@ -0,0 +1,6 @@ +package table + +// Truncate represents a truncate table statement +type Truncate struct { + Table string +}