github.com/ydb-platform/ydb-go-sdk/v3@v3.57.0/internal/bind/sql_lexer.go (about) 1 package bind 2 3 import "unicode/utf8" 4 5 type sqlLexer struct { 6 src string 7 start int 8 pos int 9 nested int // multiline comment nesting level. 10 stateFn stateFn 11 rawStateFn stateFn 12 parts []interface{} 13 } 14 15 type ( 16 positionalArg struct{} 17 numericArg int 18 19 stateFn func(*sqlLexer) stateFn 20 ) 21 22 func isLetter(r rune) bool { 23 return (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') 24 } 25 26 func isNumber(r rune) bool { 27 return r >= '0' && r <= '9' 28 } 29 30 func backtickState(l *sqlLexer) stateFn { 31 for { 32 r, width := utf8.DecodeRuneInString(l.src[l.pos:]) 33 l.pos += width 34 35 switch r { 36 case '`': 37 nextRune, width := utf8.DecodeRuneInString(l.src[l.pos:]) 38 if nextRune != '`' { 39 return l.rawStateFn 40 } 41 l.pos += width 42 case utf8.RuneError: 43 if l.pos-l.start > 0 { 44 l.parts = append(l.parts, l.src[l.start:l.pos]) 45 l.start = l.pos 46 } 47 48 return nil 49 } 50 } 51 } 52 53 func singleQuoteState(l *sqlLexer) stateFn { 54 for { 55 r, width := utf8.DecodeRuneInString(l.src[l.pos:]) 56 l.pos += width 57 58 switch r { 59 case '\'': 60 nextRune, width := utf8.DecodeRuneInString(l.src[l.pos:]) 61 if nextRune != '\'' { 62 return l.rawStateFn 63 } 64 l.pos += width 65 case utf8.RuneError: 66 if l.pos-l.start > 0 { 67 l.parts = append(l.parts, l.src[l.start:l.pos]) 68 l.start = l.pos 69 } 70 71 return nil 72 } 73 } 74 } 75 76 func doubleQuoteState(l *sqlLexer) stateFn { 77 for { 78 r, width := utf8.DecodeRuneInString(l.src[l.pos:]) 79 l.pos += width 80 81 switch r { 82 case '"': 83 nextRune, width := utf8.DecodeRuneInString(l.src[l.pos:]) 84 if nextRune != '"' { 85 return l.rawStateFn 86 } 87 l.pos += width 88 case utf8.RuneError: 89 if l.pos-l.start > 0 { 90 l.parts = append(l.parts, l.src[l.start:l.pos]) 91 l.start = l.pos 92 } 93 94 return nil 95 } 96 } 97 } 98 99 func oneLineCommentState(l *sqlLexer) stateFn { 100 for { 101 r, width := utf8.DecodeRuneInString(l.src[l.pos:]) 102 l.pos += width 103 104 switch r { 105 case '\\': 106 _, width = utf8.DecodeRuneInString(l.src[l.pos:]) 107 l.pos += width 108 case '\n', '\r': 109 return l.rawStateFn 110 case utf8.RuneError: 111 if l.pos-l.start > 0 { 112 l.parts = append(l.parts, l.src[l.start:l.pos]) 113 l.start = l.pos 114 } 115 116 return nil 117 } 118 } 119 } 120 121 func multilineCommentState(l *sqlLexer) stateFn { 122 for { 123 r, width := utf8.DecodeRuneInString(l.src[l.pos:]) 124 l.pos += width 125 126 switch r { 127 case '/': 128 nextRune, width := utf8.DecodeRuneInString(l.src[l.pos:]) 129 if nextRune == '*' { 130 l.pos += width 131 l.nested++ 132 } 133 case '*': 134 nextRune, width := utf8.DecodeRuneInString(l.src[l.pos:]) 135 if nextRune != '/' { 136 continue 137 } 138 139 l.pos += width 140 if l.nested == 0 { 141 return l.rawStateFn 142 } 143 l.nested-- 144 145 case utf8.RuneError: 146 if l.pos-l.start > 0 { 147 l.parts = append(l.parts, l.src[l.start:l.pos]) 148 l.start = l.pos 149 } 150 151 return nil 152 } 153 } 154 }