in go/connection.go [116:219]
func (c *Connection) interpolateParams(query string, args []driver.Value) (string, error) {
c.numInput = len(args)
// Number of ? should be same to len(args)
if strings.Count(query, "?") != c.numInput {
return "", ErrInvalidQuery
}
queryBuffer := make([]byte, MAXQueryStringLength)
queryBuffer = queryBuffer[:0]
argPos := 0
for i := 0; i < len(query); i++ {
q := strings.IndexByte(query[i:], '?')
if q == -1 {
queryBuffer = append(queryBuffer, query[i:]...)
break
}
queryBuffer = append(queryBuffer, query[i:i+q]...)
i += q
arg := args[argPos]
argPos++
if arg == nil {
queryBuffer = append(queryBuffer, "NULL"...)
continue
}
// type switches of arg to handle different query parameter types
switch v := arg.(type) {
case int64:
queryBuffer = strconv.AppendInt(queryBuffer, v, 10)
case uint64:
queryBuffer = strconv.AppendUint(queryBuffer, v, 10)
case float64:
queryBuffer = strconv.AppendFloat(queryBuffer, v, 'g', -1, 64)
case bool:
if v {
queryBuffer = append(queryBuffer, '1')
} else {
queryBuffer = append(queryBuffer, '0')
}
case time.Time:
if v.IsZero() {
queryBuffer = append(queryBuffer, "'0000-00-00'"...)
} else {
v := v.In(time.UTC)
v = v.Add(time.Nanosecond * 500) // To round under microsecond
year := v.Year()
year100 := year / 100
year1 := year % 100
month := v.Month()
day := v.Day()
hour := v.Hour()
minute := v.Minute()
second := v.Second()
micro := v.Nanosecond() / 1000
queryBuffer = append(queryBuffer, []byte{
'\'',
digits10[year100], digits01[year100],
digits10[year1], digits01[year1],
'-',
digits10[month], digits01[month],
'-',
digits10[day], digits01[day],
' ',
digits10[hour], digits01[hour],
':',
digits10[minute], digits01[minute],
':',
digits10[second], digits01[second],
}...)
if micro != 0 {
micro10000 := micro / 10000
micro100 := micro / 100 % 100
micro1 := micro % 100
queryBuffer = append(queryBuffer, []byte{
'.',
digits10[micro10000], digits01[micro10000],
digits10[micro100], digits01[micro100],
digits10[micro1], digits01[micro1],
}...)
}
queryBuffer = append(queryBuffer, '\'')
}
case []byte:
queryBuffer = append(queryBuffer, "_binary'"...)
queryBuffer = escapeBytesBackslash(queryBuffer, v)
queryBuffer = append(queryBuffer, '\'')
case string:
queryBuffer = append(queryBuffer, '\'')
queryBuffer = escapeStringBackslash(queryBuffer, v)
queryBuffer = append(queryBuffer, '\'')
default:
return "", ErrQueryUnknownType
}
if len(queryBuffer)+4 > 10*MAXQueryStringLength {
return "", ErrQueryBufferOF
}
}
return string(queryBuffer), nil
}