diff --git a/sqlite.go b/sqlite.go index 8617f00..4f0da2e 100644 --- a/sqlite.go +++ b/sqlite.go @@ -4,7 +4,6 @@ import ( "context" "database/sql" "strconv" - "strings" "gorm.io/gorm/callbacks" @@ -143,19 +142,51 @@ func (dialector Dialector) BindVarTo(writer clause.Writer, stmt *gorm.Statement, } func (dialector Dialector) QuoteTo(writer clause.Writer, str string) { - writer.WriteByte('`') - if strings.Contains(str, ".") { - for idx, str := range strings.Split(str, ".") { - if idx > 0 { - writer.WriteString(".`") + var ( + underQuoted, selfQuoted bool + continuousBacktick int8 + shiftDelimiter int8 + ) + + for _, v := range []byte(str) { + switch v { + case '`': + continuousBacktick++ + if continuousBacktick == 2 { + writer.WriteString("``") + continuousBacktick = 0 } - writer.WriteString(str) - writer.WriteByte('`') + case '.': + if continuousBacktick > 0 || !selfQuoted { + shiftDelimiter = 0 + underQuoted = false + continuousBacktick = 0 + writer.WriteString("`") + } + writer.WriteByte(v) + continue + default: + if shiftDelimiter-continuousBacktick <= 0 && !underQuoted { + writer.WriteString("`") + underQuoted = true + if selfQuoted = continuousBacktick > 0; selfQuoted { + continuousBacktick -= 1 + } + } + + for ; continuousBacktick > 0; continuousBacktick -= 1 { + writer.WriteString("``") + } + + writer.WriteByte(v) } - } else { - writer.WriteString(str) - writer.WriteByte('`') + shiftDelimiter++ } + + if continuousBacktick > 0 && !selfQuoted { + writer.WriteString("``") + } + writer.WriteString("`") } func (dialector Dialector) Explain(sql string, vars ...interface{}) string {