MCPcopy
hub / github.com/jmoiron/sqlx / compileNamedQuery

Function compileNamedQuery

named.go:331–406  ·  view source on GitHub ↗

FIXME: this function isn't safe for unicode named params, as a failing test can testify. This is not a regression but a failure of the original code as well. It should be modified to range over runes in a string rather than bytes, even though this is less convenient and slower. Hopefully the addi

(qs []byte, bindType int)

Source from the content-addressed store, hash-verified

329// compile a NamedQuery into an unbound query (using the '?' bindvar) and
330// a list of names.
331func compileNamedQuery(qs []byte, bindType int) (query string, names []string, err error) {
332 names = make([]string, 0, 10)
333 rebound := make([]byte, 0, len(qs))
334
335 inName := false
336 last := len(qs) - 1
337 currentVar := 1
338 name := make([]byte, 0, 10)
339
340 for i, b := range qs {
341 // a ':' while we're in a name is an error
342 if b == ':' {
343 // if this is the second ':' in a '::' escape sequence, append a ':'
344 if inName && i > 0 && qs[i-1] == ':' {
345 rebound = append(rebound, ':')
346 inName = false
347 continue
348 } else if inName {
349 err = errors.New("unexpected `:` while reading named param at " + strconv.Itoa(i))
350 return query, names, err
351 }
352 inName = true
353 name = []byte{}
354 } else if inName && i > 0 && b == '=' && len(name) == 0 {
355 rebound = append(rebound, ':', '=')
356 inName = false
357 continue
358 // if we're in a name, and this is an allowed character, continue
359 } else if inName && (unicode.IsOneOf(allowedBindRunes, rune(b)) || b == '_' || b == '.') && i != last {
360 // append the byte to the name if we are in a name and not on the last byte
361 name = append(name, b)
362 // if we're in a name and it's not an allowed character, the name is done
363 } else if inName {
364 inName = false
365 // if this is the final byte of the string and it is part of the name, then
366 // make sure to add it to the name
367 if i == last && unicode.IsOneOf(allowedBindRunes, rune(b)) {
368 name = append(name, b)
369 }
370 // add the string representation to the names list
371 names = append(names, string(name))
372 // add a proper bindvar for the bindType
373 switch bindType {
374 // oracle only supports named type bind vars even for positional
375 case NAMED:
376 rebound = append(rebound, ':')
377 rebound = append(rebound, name...)
378 case QUESTION, UNKNOWN:
379 rebound = append(rebound, '?')
380 case DOLLAR:
381 rebound = append(rebound, '$')
382 for _, b := range strconv.Itoa(currentVar) {
383 rebound = append(rebound, byte(b))
384 }
385 currentVar++
386 case AT:
387 rebound = append(rebound, '@', 'p')
388 for _, b := range strconv.Itoa(currentVar) {

Callers 7

TestCompileQueryFunction · 0.85
TestEscapedColonsFunction · 0.85
prepareNamedContextFunction · 0.85
prepareNamedFunction · 0.85
bindStructFunction · 0.85
bindArrayFunction · 0.85
bindMapFunction · 0.85

Calls

no outgoing calls

Tested by 2

TestCompileQueryFunction · 0.68
TestEscapedColonsFunction · 0.68