vitess.io/vitess@v0.16.2/go/sqltypes/value.go (about)

     1  /*
     2  Copyright 2019 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  // Package sqltypes implements interfaces and types that represent SQL values.
    18  package sqltypes
    19  
    20  import (
    21  	"encoding/base64"
    22  	"encoding/hex"
    23  	"encoding/json"
    24  	"errors"
    25  	"fmt"
    26  	"math/big"
    27  	"strconv"
    28  	"strings"
    29  
    30  	"vitess.io/vitess/go/bytes2"
    31  	"vitess.io/vitess/go/hack"
    32  
    33  	querypb "vitess.io/vitess/go/vt/proto/query"
    34  	"vitess.io/vitess/go/vt/proto/vtrpc"
    35  	vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc"
    36  	"vitess.io/vitess/go/vt/vterrors"
    37  )
    38  
    39  var (
    40  	// NULL represents the NULL value.
    41  	NULL = Value{}
    42  
    43  	// DontEscape tells you if a character should not be escaped.
    44  	DontEscape = byte(255)
    45  
    46  	nullstr = []byte("null")
    47  
    48  	// ErrIncompatibleTypeCast indicates a casting problem
    49  	ErrIncompatibleTypeCast = errors.New("Cannot convert value to desired type")
    50  )
    51  
    52  type (
    53  	// BinWriter interface is used for encoding values.
    54  	// Types like bytes.Buffer conform to this interface.
    55  	// We expect the writer objects to be in-memory buffers.
    56  	// So, we don't expect the write operations to fail.
    57  	BinWriter interface {
    58  		Write([]byte) (int, error)
    59  	}
    60  
    61  	// Value can store any SQL value. If the value represents
    62  	// an integral type, the bytes are always stored as a canonical
    63  	// representation that matches how MySQL returns such values.
    64  	Value struct {
    65  		typ querypb.Type
    66  		val []byte
    67  	}
    68  
    69  	Row = []Value
    70  )
    71  
    72  // NewValue builds a Value using typ and val. If the value and typ
    73  // don't match, it returns an error.
    74  func NewValue(typ querypb.Type, val []byte) (v Value, err error) {
    75  	switch {
    76  	case IsSigned(typ):
    77  		if _, err := strconv.ParseInt(string(val), 10, 64); err != nil {
    78  			return NULL, err
    79  		}
    80  		return MakeTrusted(typ, val), nil
    81  	case IsUnsigned(typ):
    82  		if _, err := strconv.ParseUint(string(val), 10, 64); err != nil {
    83  			return NULL, err
    84  		}
    85  		return MakeTrusted(typ, val), nil
    86  	case IsFloat(typ) || typ == Decimal:
    87  		if _, err := strconv.ParseFloat(string(val), 64); err != nil {
    88  			return NULL, err
    89  		}
    90  		return MakeTrusted(typ, val), nil
    91  	case IsQuoted(typ) || typ == Bit || typ == HexNum || typ == HexVal || typ == Null || typ == BitNum:
    92  		return MakeTrusted(typ, val), nil
    93  	}
    94  	// All other types are unsafe or invalid.
    95  	return NULL, fmt.Errorf("invalid type specified for MakeValue: %v", typ)
    96  }
    97  
    98  // MakeTrusted makes a new Value based on the type.
    99  // This function should only be used if you know the value
   100  // and type conform to the rules. Every place this function is
   101  // called, a comment is needed that explains why it's justified.
   102  // Exceptions: The current package and mysql package do not need
   103  // comments. Other packages can also use the function to create
   104  // VarBinary or VarChar values.
   105  func MakeTrusted(typ querypb.Type, val []byte) Value {
   106  
   107  	if typ == Null {
   108  		return NULL
   109  	}
   110  
   111  	return Value{typ: typ, val: val}
   112  }
   113  
   114  // NewHexNum builds an Hex Value.
   115  func NewHexNum(v []byte) Value {
   116  	return MakeTrusted(HexNum, v)
   117  }
   118  
   119  // NewHexVal builds a HexVal Value.
   120  func NewHexVal(v []byte) Value {
   121  	return MakeTrusted(HexVal, v)
   122  }
   123  
   124  // NewBitNum builds a BitNum Value.
   125  func NewBitNum(v []byte) Value {
   126  	return MakeTrusted(BitNum, v)
   127  }
   128  
   129  // NewInt64 builds an Int64 Value.
   130  func NewInt64(v int64) Value {
   131  	return MakeTrusted(Int64, strconv.AppendInt(nil, v, 10))
   132  }
   133  
   134  // NewInt8 builds an Int8 Value.
   135  func NewInt8(v int8) Value {
   136  	return MakeTrusted(Int8, strconv.AppendInt(nil, int64(v), 10))
   137  }
   138  
   139  // NewInt32 builds an Int64 Value.
   140  func NewInt32(v int32) Value {
   141  	return MakeTrusted(Int32, strconv.AppendInt(nil, int64(v), 10))
   142  }
   143  
   144  // NewUint64 builds an Uint64 Value.
   145  func NewUint64(v uint64) Value {
   146  	return MakeTrusted(Uint64, strconv.AppendUint(nil, v, 10))
   147  }
   148  
   149  // NewUint32 builds an Uint32 Value.
   150  func NewUint32(v uint32) Value {
   151  	return MakeTrusted(Uint32, strconv.AppendUint(nil, uint64(v), 10))
   152  }
   153  
   154  // NewFloat64 builds an Float64 Value.
   155  func NewFloat64(v float64) Value {
   156  	return MakeTrusted(Float64, strconv.AppendFloat(nil, v, 'g', -1, 64))
   157  }
   158  
   159  // NewVarChar builds a VarChar Value.
   160  func NewVarChar(v string) Value {
   161  	return MakeTrusted(VarChar, []byte(v))
   162  }
   163  
   164  // NewVarBinary builds a VarBinary Value.
   165  // The input is a string because it's the most common use case.
   166  func NewVarBinary(v string) Value {
   167  	return MakeTrusted(VarBinary, []byte(v))
   168  }
   169  
   170  // NewDate builds a Date value.
   171  func NewDate(v string) Value {
   172  	return MakeTrusted(Date, []byte(v))
   173  }
   174  
   175  // NewTime builds a Time value.
   176  func NewTime(v string) Value {
   177  	return MakeTrusted(Time, []byte(v))
   178  }
   179  
   180  // NewTimestamp builds a Timestamp value.
   181  func NewTimestamp(v string) Value {
   182  	return MakeTrusted(Timestamp, []byte(v))
   183  }
   184  
   185  // NewDatetime builds a Datetime value.
   186  func NewDatetime(v string) Value {
   187  	return MakeTrusted(Datetime, []byte(v))
   188  }
   189  
   190  // NewDecimal builds a Decimal value.
   191  func NewDecimal(v string) Value {
   192  	return MakeTrusted(Decimal, []byte(v))
   193  }
   194  
   195  // NewIntegral builds an integral type from a string representation.
   196  // The type will be Int64 or Uint64. Int64 will be preferred where possible.
   197  func NewIntegral(val string) (n Value, err error) {
   198  	signed, err := strconv.ParseInt(val, 0, 64)
   199  	if err == nil {
   200  		return MakeTrusted(Int64, strconv.AppendInt(nil, signed, 10)), nil
   201  	}
   202  	unsigned, err := strconv.ParseUint(val, 0, 64)
   203  	if err != nil {
   204  		return Value{}, err
   205  	}
   206  	return MakeTrusted(Uint64, strconv.AppendUint(nil, unsigned, 10)), nil
   207  }
   208  
   209  // InterfaceToValue builds a value from a go type.
   210  // Supported types are nil, int64, uint64, float64,
   211  // string and []byte.
   212  // This function is deprecated. Use the type-specific
   213  // functions instead.
   214  func InterfaceToValue(goval any) (Value, error) {
   215  	switch goval := goval.(type) {
   216  	case nil:
   217  		return NULL, nil
   218  	case []byte:
   219  		return MakeTrusted(VarBinary, goval), nil
   220  	case int64:
   221  		return NewInt64(goval), nil
   222  	case uint64:
   223  		return NewUint64(goval), nil
   224  	case float64:
   225  		return NewFloat64(goval), nil
   226  	case string:
   227  		return NewVarChar(goval), nil
   228  	default:
   229  		return NULL, fmt.Errorf("unexpected type %T: %v", goval, goval)
   230  	}
   231  }
   232  
   233  // Type returns the type of Value.
   234  func (v Value) Type() querypb.Type {
   235  	return v.typ
   236  }
   237  
   238  // Raw returns the internal representation of the value. For newer types,
   239  // this may not match MySQL's representation.
   240  func (v Value) Raw() []byte {
   241  	return v.val
   242  }
   243  
   244  // RawStr returns the internal representation of the value as a string instead
   245  // of a byte slice. This is equivalent to calling `string(v.Raw())` but does
   246  // not allocate.
   247  func (v Value) RawStr() string {
   248  	return hack.String(v.val)
   249  }
   250  
   251  // ToBytes returns the value as MySQL would return it as []byte.
   252  // In contrast, Raw returns the internal representation of the Value, which may not
   253  // match MySQL's representation for hex encoded binary data or newer types.
   254  // If the value is not convertible like in the case of Expression, it returns an error.
   255  func (v Value) ToBytes() ([]byte, error) {
   256  	switch v.typ {
   257  	case Expression:
   258  		return nil, vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "expression cannot be converted to bytes")
   259  	case HexVal: // TODO: all the decode below have problem when decoding odd number of bytes. This needs to be fixed.
   260  		return v.decodeHexVal()
   261  	case HexNum:
   262  		return v.decodeHexNum()
   263  	case BitNum:
   264  		return v.decodeBitNum()
   265  	default:
   266  		return v.val, nil
   267  	}
   268  }
   269  
   270  // Len returns the length.
   271  func (v Value) Len() int {
   272  	return len(v.val)
   273  }
   274  
   275  // ToInt64 returns the value as MySQL would return it as a int64.
   276  func (v Value) ToInt64() (int64, error) {
   277  	if !v.IsIntegral() {
   278  		return 0, ErrIncompatibleTypeCast
   279  	}
   280  
   281  	return strconv.ParseInt(v.RawStr(), 10, 64)
   282  }
   283  
   284  // ToFloat64 returns the value as MySQL would return it as a float64.
   285  func (v Value) ToFloat64() (float64, error) {
   286  	if !IsNumber(v.typ) {
   287  		return 0, ErrIncompatibleTypeCast
   288  	}
   289  
   290  	return strconv.ParseFloat(v.RawStr(), 64)
   291  }
   292  
   293  // ToUint64 returns the value as MySQL would return it as a uint64.
   294  func (v Value) ToUint64() (uint64, error) {
   295  	if !v.IsIntegral() {
   296  		return 0, ErrIncompatibleTypeCast
   297  	}
   298  
   299  	return strconv.ParseUint(v.RawStr(), 10, 64)
   300  }
   301  
   302  // ToBool returns the value as a bool value
   303  func (v Value) ToBool() (bool, error) {
   304  	i, err := v.ToInt64()
   305  	if err != nil {
   306  		return false, err
   307  	}
   308  	switch i {
   309  	case 0:
   310  		return false, nil
   311  	case 1:
   312  		return true, nil
   313  	}
   314  	return false, ErrIncompatibleTypeCast
   315  }
   316  
   317  // ToString returns the value as MySQL would return it as string.
   318  // If the value is not convertible like in the case of Expression, it returns nil.
   319  func (v Value) ToString() string {
   320  	if v.typ == Expression {
   321  		return ""
   322  	}
   323  	return hack.String(v.val)
   324  }
   325  
   326  // String returns a printable version of the value.
   327  func (v Value) String() string {
   328  	if v.typ == Null {
   329  		return "NULL"
   330  	}
   331  	if v.IsQuoted() || v.typ == Bit {
   332  		return fmt.Sprintf("%v(%q)", v.typ, v.val)
   333  	}
   334  	return fmt.Sprintf("%v(%s)", v.typ, v.val)
   335  }
   336  
   337  // EncodeSQL encodes the value into an SQL statement. Can be binary.
   338  func (v Value) EncodeSQL(b BinWriter) {
   339  	switch {
   340  	case v.typ == Null:
   341  		b.Write(nullstr)
   342  	case v.IsQuoted():
   343  		encodeBytesSQL(v.val, b)
   344  	case v.typ == Bit:
   345  		encodeBytesSQLBits(v.val, b)
   346  	default:
   347  		b.Write(v.val)
   348  	}
   349  }
   350  
   351  // EncodeSQLStringBuilder is identical to EncodeSQL but it takes a strings.Builder
   352  // as its writer, so it can be inlined for performance.
   353  func (v Value) EncodeSQLStringBuilder(b *strings.Builder) {
   354  	switch {
   355  	case v.typ == Null:
   356  		b.Write(nullstr)
   357  	case v.IsQuoted():
   358  		encodeBytesSQLStringBuilder(v.val, b)
   359  	case v.typ == Bit:
   360  		encodeBytesSQLBits(v.val, b)
   361  	default:
   362  		b.Write(v.val)
   363  	}
   364  }
   365  
   366  // EncodeSQLBytes2 is identical to EncodeSQL but it takes a bytes2.Buffer
   367  // as its writer, so it can be inlined for performance.
   368  func (v Value) EncodeSQLBytes2(b *bytes2.Buffer) {
   369  	switch {
   370  	case v.typ == Null:
   371  		b.Write(nullstr)
   372  	case v.IsQuoted():
   373  		encodeBytesSQLBytes2(v.val, b)
   374  	case v.typ == Bit:
   375  		encodeBytesSQLBits(v.val, b)
   376  	default:
   377  		b.Write(v.val)
   378  	}
   379  }
   380  
   381  // EncodeASCII encodes the value using 7-bit clean ascii bytes.
   382  func (v Value) EncodeASCII(b BinWriter) {
   383  	switch {
   384  	case v.typ == Null:
   385  		b.Write(nullstr)
   386  	case v.IsQuoted() || v.typ == Bit:
   387  		encodeBytesASCII(v.val, b)
   388  	default:
   389  		b.Write(v.val)
   390  	}
   391  }
   392  
   393  // IsNull returns true if Value is null.
   394  func (v Value) IsNull() bool {
   395  	return v.typ == Null
   396  }
   397  
   398  // IsIntegral returns true if Value is an integral.
   399  func (v Value) IsIntegral() bool {
   400  	return IsIntegral(v.typ)
   401  }
   402  
   403  // IsSigned returns true if Value is a signed integral.
   404  func (v Value) IsSigned() bool {
   405  	return IsSigned(v.typ)
   406  }
   407  
   408  // IsUnsigned returns true if Value is an unsigned integral.
   409  func (v Value) IsUnsigned() bool {
   410  	return IsUnsigned(v.typ)
   411  }
   412  
   413  // IsFloat returns true if Value is a float.
   414  func (v Value) IsFloat() bool {
   415  	return IsFloat(v.typ)
   416  }
   417  
   418  // IsQuoted returns true if Value must be SQL-quoted.
   419  func (v Value) IsQuoted() bool {
   420  	return IsQuoted(v.typ)
   421  }
   422  
   423  // IsText returns true if Value is a collatable text.
   424  func (v Value) IsText() bool {
   425  	return IsText(v.typ)
   426  }
   427  
   428  // IsBinary returns true if Value is binary.
   429  func (v Value) IsBinary() bool {
   430  	return IsBinary(v.typ)
   431  }
   432  
   433  // IsDateTime returns true if Value is datetime.
   434  func (v Value) IsDateTime() bool {
   435  	dt := int(querypb.Type_DATETIME)
   436  	return int(v.typ)&dt == dt
   437  }
   438  
   439  // IsComparable returns true if the Value is null safe comparable without collation information.
   440  func (v *Value) IsComparable() bool {
   441  	if v.typ == Null || IsNumber(v.typ) || IsBinary(v.typ) {
   442  		return true
   443  	}
   444  	switch v.typ {
   445  	case Timestamp, Date, Time, Datetime, Enum, Set, TypeJSON, Bit:
   446  		return true
   447  	}
   448  	return false
   449  }
   450  
   451  // MarshalJSON should only be used for testing.
   452  // It's not a complete implementation.
   453  func (v Value) MarshalJSON() ([]byte, error) {
   454  	switch {
   455  	case v.IsQuoted() || v.typ == Bit:
   456  		return json.Marshal(v.ToString())
   457  	case v.typ == Null:
   458  		return nullstr, nil
   459  	}
   460  	return v.val, nil
   461  }
   462  
   463  // UnmarshalJSON should only be used for testing.
   464  // It's not a complete implementation.
   465  func (v *Value) UnmarshalJSON(b []byte) error {
   466  	if len(b) == 0 {
   467  		return fmt.Errorf("error unmarshaling empty bytes")
   468  	}
   469  	var val any
   470  	var err error
   471  	switch b[0] {
   472  	case '-':
   473  		var ival int64
   474  		err = json.Unmarshal(b, &ival)
   475  		val = ival
   476  	case '"':
   477  		var bval []byte
   478  		err = json.Unmarshal(b, &bval)
   479  		val = bval
   480  	case 'n': // null
   481  		err = json.Unmarshal(b, &val)
   482  	default:
   483  		var uval uint64
   484  		err = json.Unmarshal(b, &uval)
   485  		val = uval
   486  	}
   487  	if err != nil {
   488  		return err
   489  	}
   490  	*v, err = InterfaceToValue(val)
   491  	return err
   492  }
   493  
   494  // decodeHexVal decodes the SQL hex value of the form x'A1' into a byte
   495  // array matching what MySQL would return when querying the column where
   496  // an INSERT was performed with x'A1' having been specified as a value
   497  func (v *Value) decodeHexVal() ([]byte, error) {
   498  	if len(v.val) < 3 || (v.val[0] != 'x' && v.val[0] != 'X') || v.val[1] != '\'' || v.val[len(v.val)-1] != '\'' {
   499  		return nil, vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "invalid hex value: %v", v.val)
   500  	}
   501  	hexBytes := v.val[2 : len(v.val)-1]
   502  	decodedHexBytes, err := hex.DecodeString(string(hexBytes))
   503  	if err != nil {
   504  		return nil, err
   505  	}
   506  	return decodedHexBytes, nil
   507  }
   508  
   509  // decodeHexNum decodes the SQL hex value of the form 0xA1 into a byte
   510  // array matching what MySQL would return when querying the column where
   511  // an INSERT was performed with 0xA1 having been specified as a value
   512  func (v *Value) decodeHexNum() ([]byte, error) {
   513  	if len(v.val) < 3 || v.val[0] != '0' || v.val[1] != 'x' {
   514  		return nil, vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "invalid hex number: %v", v.val)
   515  	}
   516  	hexBytes := v.val[2:]
   517  	decodedHexBytes, err := hex.DecodeString(string(hexBytes))
   518  	if err != nil {
   519  		return nil, err
   520  	}
   521  	return decodedHexBytes, nil
   522  }
   523  
   524  // decodeBitNum decodes the SQL bit value of the form 0b101 into a byte
   525  // array matching what MySQL would return when querying the column where
   526  // an INSERT was performed with 0x5 having been specified as a value
   527  func (v *Value) decodeBitNum() ([]byte, error) {
   528  	if len(v.val) < 3 || v.val[0] != '0' || v.val[1] != 'b' {
   529  		return nil, vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "invalid bit number: %v", v.val)
   530  	}
   531  	var i big.Int
   532  	_, ok := i.SetString(string(v.val), 0)
   533  	if !ok {
   534  		return nil, vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "invalid bit number: %v", v.val)
   535  	}
   536  	return i.Bytes(), nil
   537  }
   538  
   539  func encodeBytesSQL(val []byte, b BinWriter) {
   540  	buf := &bytes2.Buffer{}
   541  	encodeBytesSQLBytes2(val, buf)
   542  	b.Write(buf.Bytes())
   543  }
   544  
   545  func encodeBytesSQLBytes2(val []byte, buf *bytes2.Buffer) {
   546  	buf.WriteByte('\'')
   547  	for idx, ch := range val {
   548  		// If \% or \_ is present, we want to keep them as is, and don't want to escape \ again
   549  		if ch == '\\' && idx+1 < len(val) && (val[idx+1] == '%' || val[idx+1] == '_') {
   550  			buf.WriteByte(ch)
   551  			continue
   552  		}
   553  		if encodedChar := SQLEncodeMap[ch]; encodedChar == DontEscape {
   554  			buf.WriteByte(ch)
   555  		} else {
   556  			buf.WriteByte('\\')
   557  			buf.WriteByte(encodedChar)
   558  		}
   559  	}
   560  	buf.WriteByte('\'')
   561  }
   562  
   563  func encodeBytesSQLStringBuilder(val []byte, buf *strings.Builder) {
   564  	buf.WriteByte('\'')
   565  	for idx, ch := range val {
   566  		// If \% or \_ is present, we want to keep them as is, and don't want to escape \ again
   567  		if ch == '\\' && idx+1 < len(val) && (val[idx+1] == '%' || val[idx+1] == '_') {
   568  			buf.WriteByte(ch)
   569  			continue
   570  		}
   571  		if encodedChar := SQLEncodeMap[ch]; encodedChar == DontEscape {
   572  			buf.WriteByte(ch)
   573  		} else {
   574  			buf.WriteByte('\\')
   575  			buf.WriteByte(encodedChar)
   576  		}
   577  	}
   578  	buf.WriteByte('\'')
   579  }
   580  
   581  // BufEncodeStringSQL encodes the string into a strings.Builder
   582  func BufEncodeStringSQL(buf *strings.Builder, val string) {
   583  	buf.WriteByte('\'')
   584  	for idx, ch := range val {
   585  		if ch > 255 {
   586  			buf.WriteRune(ch)
   587  			continue
   588  		}
   589  		// If \% or \_ is present, we want to keep them as is, and don't want to escape \ again
   590  		if ch == '\\' && idx+1 < len(val) && (val[idx+1] == '%' || val[idx+1] == '_') {
   591  			buf.WriteRune(ch)
   592  			continue
   593  		}
   594  		if encodedChar := SQLEncodeMap[ch]; encodedChar == DontEscape {
   595  			buf.WriteRune(ch)
   596  		} else {
   597  			buf.WriteByte('\\')
   598  			buf.WriteByte(encodedChar)
   599  		}
   600  	}
   601  	buf.WriteByte('\'')
   602  }
   603  
   604  // EncodeStringSQL encodes the string as a SQL string.
   605  func EncodeStringSQL(val string) string {
   606  	var buf strings.Builder
   607  	BufEncodeStringSQL(&buf, val)
   608  	return buf.String()
   609  }
   610  
   611  func encodeBytesSQLBits(val []byte, b BinWriter) {
   612  	fmt.Fprint(b, "b'")
   613  	for _, ch := range val {
   614  		fmt.Fprintf(b, "%08b", ch)
   615  	}
   616  	fmt.Fprint(b, "'")
   617  }
   618  
   619  func encodeBytesASCII(val []byte, b BinWriter) {
   620  	buf := &bytes2.Buffer{}
   621  	buf.WriteByte('\'')
   622  	encoder := base64.NewEncoder(base64.StdEncoding, buf)
   623  	encoder.Write(val)
   624  	encoder.Close()
   625  	buf.WriteByte('\'')
   626  	b.Write(buf.Bytes())
   627  }
   628  
   629  // SQLEncodeMap specifies how to escape binary data with '\'.
   630  // Complies to https://dev.mysql.com/doc/refman/5.7/en/string-literals.html
   631  // Handling escaping of % and _ is different than other characters.
   632  // When escaped in a like clause, they are supposed to be treated as literals
   633  // Everywhere else, they evaluate to strings '\%' and '\_' respectively.
   634  // In Vitess, the way we are choosing to handle this behaviour is to always
   635  // preserve the escaping of % and _ as is in all the places and handle it like MySQL
   636  // in our evaluation engine for Like.
   637  var SQLEncodeMap [256]byte
   638  
   639  // SQLDecodeMap is the reverse of SQLEncodeMap
   640  var SQLDecodeMap [256]byte
   641  
   642  var encodeRef = map[byte]byte{
   643  	'\x00': '0',
   644  	'\'':   '\'',
   645  	'"':    '"',
   646  	'\b':   'b',
   647  	'\n':   'n',
   648  	'\r':   'r',
   649  	'\t':   't',
   650  	26:     'Z', // ctl-Z
   651  	'\\':   '\\',
   652  }
   653  
   654  func init() {
   655  	for i := range SQLEncodeMap {
   656  		SQLEncodeMap[i] = DontEscape
   657  		SQLDecodeMap[i] = DontEscape
   658  	}
   659  	for i := range SQLEncodeMap {
   660  		if to, ok := encodeRef[byte(i)]; ok {
   661  			SQLEncodeMap[byte(i)] = to
   662  			SQLDecodeMap[to] = byte(i)
   663  		}
   664  	}
   665  }