@@ -24,8 +24,9 @@ type parseFunc func(*bufio.Reader) error
24
24
func parseCreateIndex (s string ) (sql.Node , error ) {
25
25
r := bufio .NewReader (strings .NewReader (s ))
26
26
27
- var name , table string
27
+ var name , table , driver string
28
28
var exprs []string
29
+ var config = make (map [string ]string )
29
30
steps := []parseFunc {
30
31
expect ("create" ),
31
32
skipSpaces ,
@@ -37,8 +38,20 @@ func parseCreateIndex(s string) (sql.Node, error) {
37
38
skipSpaces ,
38
39
readIdent (& table ),
39
40
skipSpaces ,
41
+ optional (
42
+ expect ("using" ),
43
+ skipSpaces ,
44
+ readIdent (& driver ),
45
+ skipSpaces ,
46
+ ),
40
47
readExprs (& exprs ),
41
48
skipSpaces ,
49
+ optional (
50
+ expect ("with" ),
51
+ skipSpaces ,
52
+ readKeyValue (config ),
53
+ skipSpaces ,
54
+ ),
42
55
}
43
56
44
57
for _ , step := range steps {
@@ -47,9 +60,6 @@ func parseCreateIndex(s string) (sql.Node, error) {
47
60
}
48
61
}
49
62
50
- // TODO: parse using
51
- // TODO: parse config
52
-
53
63
var indexExprs = make ([]sql.Expression , len (exprs ))
54
64
for i , e := range exprs {
55
65
var err error
@@ -63,10 +73,128 @@ func parseCreateIndex(s string) (sql.Node, error) {
63
73
name ,
64
74
plan .NewUnresolvedTable (table ),
65
75
indexExprs ,
66
- "" ,
76
+ driver ,
77
+ config ,
67
78
), nil
68
79
}
69
80
81
+ func optional (steps ... parseFunc ) parseFunc {
82
+ return func (rd * bufio.Reader ) error {
83
+ for _ , step := range steps {
84
+ err := step (rd )
85
+ if err == io .EOF || errUnexpectedSyntax .Is (err ) {
86
+ return nil
87
+ }
88
+
89
+ if err != nil {
90
+ return err
91
+ }
92
+ }
93
+
94
+ return nil
95
+ }
96
+ }
97
+
98
+ func readKeyValue (kv map [string ]string ) parseFunc {
99
+ return func (rd * bufio.Reader ) error {
100
+ r , _ , err := rd .ReadRune ()
101
+ if err != nil {
102
+ return err
103
+ }
104
+
105
+ if r != '(' {
106
+ return errUnexpectedSyntax .New ("(" , string (r ))
107
+ }
108
+
109
+ for {
110
+ var key , value string
111
+ steps := []parseFunc {
112
+ skipSpaces ,
113
+ readIdent (& key ),
114
+ skipSpaces ,
115
+ expectRune ('=' ),
116
+ skipSpaces ,
117
+ readValue (& value ),
118
+ skipSpaces ,
119
+ }
120
+
121
+ for _ , step := range steps {
122
+ if err := step (rd ); err != nil {
123
+ return err
124
+ }
125
+ }
126
+
127
+ r , _ , err := rd .ReadRune ()
128
+ if err != nil {
129
+ return err
130
+ }
131
+
132
+ switch r {
133
+ case ')' :
134
+ kv [key ] = value
135
+ return nil
136
+ case ',' :
137
+ kv [key ] = value
138
+ continue
139
+ default :
140
+ return errUnexpectedSyntax .New (", or )" , string (r ))
141
+ }
142
+ }
143
+ }
144
+ }
145
+
146
+ func readValue (val * string ) parseFunc {
147
+ return func (rd * bufio.Reader ) error {
148
+ var buf bytes.Buffer
149
+ var singleQuote , doubleQuote , ignoreNext bool
150
+ var first = true
151
+ for {
152
+ r , _ , err := rd .ReadRune ()
153
+ if err == io .EOF {
154
+ break
155
+ }
156
+
157
+ if err != nil {
158
+ return err
159
+ }
160
+
161
+ if singleQuote || doubleQuote {
162
+ switch true {
163
+ case ignoreNext :
164
+ ignoreNext = false
165
+ case r == '\\' :
166
+ ignoreNext = true
167
+ continue
168
+ case r == '\'' && singleQuote :
169
+ singleQuote = false
170
+ continue
171
+ case r == '"' && doubleQuote :
172
+ doubleQuote = false
173
+ continue
174
+ }
175
+ } else if first && (r == '\'' || r == '"' ) {
176
+ if r == '\'' {
177
+ singleQuote = true
178
+ } else {
179
+ doubleQuote = true
180
+ }
181
+ first = false
182
+ continue
183
+ } else if ! unicode .IsLetter (r ) && ! unicode .IsNumber (r ) && r != '_' {
184
+ if err := rd .UnreadRune (); err != nil {
185
+ return err
186
+ }
187
+ break
188
+ }
189
+
190
+ buf .WriteRune (r )
191
+ }
192
+
193
+ * val = strings .ToLower (buf .String ())
194
+ return nil
195
+ }
196
+ }
197
+
70
198
func parseIndexExpr (str string ) (sql.Expression , error ) {
71
199
stmt , err := sqlparser .Parse ("SELECT " + str )
72
200
if err != nil {
@@ -123,22 +251,38 @@ func readExprs(exprs *[]string) parseFunc {
123
251
var buf bytes.Buffer
124
252
r , _ , err := rd .ReadRune ()
125
253
if err != nil {
254
+ if err == io .EOF {
255
+ return errUnexpectedSyntax .New ("(" , "EOF" )
256
+ }
126
257
return err
127
258
}
128
259
129
260
if r != '(' {
130
- return errUnexpectedSyntax .New ("(" , r )
261
+ return errUnexpectedSyntax .New ("(" , string ( r ) )
131
262
}
132
263
133
264
var level int
134
265
var hasNonIdentChars bool
266
+ var singleQuote , doubleQuote bool
267
+ var ignoreNext bool
135
268
for {
136
269
r , _ , err := rd .ReadRune ()
137
270
if err != nil {
138
271
return err
139
272
}
140
273
141
274
switch true {
275
+ case singleQuote || doubleQuote :
276
+ switch true {
277
+ case ignoreNext :
278
+ ignoreNext = false
279
+ case r == '\\' :
280
+ ignoreNext = true
281
+ case r == '"' && doubleQuote :
282
+ doubleQuote = false
283
+ case r == '\'' && singleQuote :
284
+ singleQuote = false
285
+ }
142
286
case unicode .IsLetter (r ) || r == '_' :
143
287
case r == '(' :
144
288
level ++
@@ -154,6 +298,12 @@ func readExprs(exprs *[]string) parseFunc {
154
298
buf .Reset ()
155
299
return nil
156
300
}
301
+ case r == '"' :
302
+ hasNonIdentChars = true
303
+ doubleQuote = true
304
+ case r == '\'' :
305
+ hasNonIdentChars = true
306
+ singleQuote = true
157
307
case r == ',' && level == 0 :
158
308
if hasNonIdentChars {
159
309
return errUnexpectedSyntax .New ("," , ")" )
@@ -171,9 +321,25 @@ func readExprs(exprs *[]string) parseFunc {
171
321
}
172
322
}
173
323
324
+ func expectRune (expected rune ) parseFunc {
325
+ return func (rd * bufio.Reader ) error {
326
+ r , _ , err := rd .ReadRune ()
327
+ if err != nil {
328
+ return err
329
+ }
330
+
331
+ if r != expected {
332
+ return errUnexpectedSyntax .New (expected , string (r ))
333
+ }
334
+
335
+ return nil
336
+ }
337
+ }
338
+
174
339
func expect (expected string ) parseFunc {
175
340
return func (r * bufio.Reader ) error {
176
341
var ident string
342
+
177
343
if err := readIdent (& ident )(r ); err != nil {
178
344
return err
179
345
}
@@ -198,10 +364,7 @@ func skipSpaces(r *bufio.Reader) error {
198
364
}
199
365
200
366
if ! unicode .IsSpace (ru ) {
201
- if err := r .UnreadRune (); err != nil {
202
- return err
203
- }
204
- return nil
367
+ return r .UnreadRune ()
205
368
}
206
369
}
207
370
}
0 commit comments