github.com/XiaoMi/Gaea@v1.2.5/parser/tidb-types/json/constants.go (about)

     1  // Copyright 2017 PingCAP, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package json
    15  
    16  import (
    17  	"encoding/binary"
    18  	"unicode/utf8"
    19  
    20  	"github.com/XiaoMi/Gaea/mysql"
    21  	"github.com/XiaoMi/Gaea/parser/terror"
    22  )
    23  
    24  // TypeCode indicates JSON type.
    25  type TypeCode = byte
    26  
    27  const (
    28  	// TypeCodeObject indicates the JSON is an object.
    29  	TypeCodeObject TypeCode = 0x01
    30  	// TypeCodeArray indicates the JSON is an array.
    31  	TypeCodeArray TypeCode = 0x03
    32  	// TypeCodeLiteral indicates the JSON is a literal.
    33  	TypeCodeLiteral TypeCode = 0x04
    34  	// TypeCodeInt64 indicates the JSON is a signed integer.
    35  	TypeCodeInt64 TypeCode = 0x09
    36  	// TypeCodeUint64 indicates the JSON is a unsigned integer.
    37  	TypeCodeUint64 TypeCode = 0x0a
    38  	// TypeCodeFloat64 indicates the JSON is a double float number.
    39  	TypeCodeFloat64 TypeCode = 0x0b
    40  	// TypeCodeString indicates the JSON is a string.
    41  	TypeCodeString TypeCode = 0x0c
    42  )
    43  
    44  const (
    45  	// LiteralNil represents JSON null.
    46  	LiteralNil byte = 0x00
    47  	// LiteralTrue represents JSON true.
    48  	LiteralTrue byte = 0x01
    49  	// LiteralFalse represents JSON false.
    50  	LiteralFalse byte = 0x02
    51  )
    52  
    53  const unknownTypeCodeErrorMsg = "unknown type code: %d"
    54  const unknownTypeErrorMsg = "unknown type: %s"
    55  
    56  // htmlSafeSet holds the value true if the ASCII character with the given
    57  // array position can be safely represented inside a JSON string, embedded
    58  // inside of HTML <script> tags, without any additional escaping.
    59  //
    60  // All values are true except for the ASCII control characters (0-31), the
    61  // double quote ("), the backslash character ("\"), HTML opening and closing
    62  // tags ("<" and ">"), and the ampersand ("&").
    63  var htmlSafeSet = [utf8.RuneSelf]bool{
    64  	' ':      true,
    65  	'!':      true,
    66  	'"':      false,
    67  	'#':      true,
    68  	'$':      true,
    69  	'%':      true,
    70  	'&':      false,
    71  	'\'':     true,
    72  	'(':      true,
    73  	')':      true,
    74  	'*':      true,
    75  	'+':      true,
    76  	',':      true,
    77  	'-':      true,
    78  	'.':      true,
    79  	'/':      true,
    80  	'0':      true,
    81  	'1':      true,
    82  	'2':      true,
    83  	'3':      true,
    84  	'4':      true,
    85  	'5':      true,
    86  	'6':      true,
    87  	'7':      true,
    88  	'8':      true,
    89  	'9':      true,
    90  	':':      true,
    91  	';':      true,
    92  	'<':      false,
    93  	'=':      true,
    94  	'>':      false,
    95  	'?':      true,
    96  	'@':      true,
    97  	'A':      true,
    98  	'B':      true,
    99  	'C':      true,
   100  	'D':      true,
   101  	'E':      true,
   102  	'F':      true,
   103  	'G':      true,
   104  	'H':      true,
   105  	'I':      true,
   106  	'J':      true,
   107  	'K':      true,
   108  	'L':      true,
   109  	'M':      true,
   110  	'N':      true,
   111  	'O':      true,
   112  	'P':      true,
   113  	'Q':      true,
   114  	'R':      true,
   115  	'S':      true,
   116  	'T':      true,
   117  	'U':      true,
   118  	'V':      true,
   119  	'W':      true,
   120  	'X':      true,
   121  	'Y':      true,
   122  	'Z':      true,
   123  	'[':      true,
   124  	'\\':     false,
   125  	']':      true,
   126  	'^':      true,
   127  	'_':      true,
   128  	'`':      true,
   129  	'a':      true,
   130  	'b':      true,
   131  	'c':      true,
   132  	'd':      true,
   133  	'e':      true,
   134  	'f':      true,
   135  	'g':      true,
   136  	'h':      true,
   137  	'i':      true,
   138  	'j':      true,
   139  	'k':      true,
   140  	'l':      true,
   141  	'm':      true,
   142  	'n':      true,
   143  	'o':      true,
   144  	'p':      true,
   145  	'q':      true,
   146  	'r':      true,
   147  	's':      true,
   148  	't':      true,
   149  	'u':      true,
   150  	'v':      true,
   151  	'w':      true,
   152  	'x':      true,
   153  	'y':      true,
   154  	'z':      true,
   155  	'{':      true,
   156  	'|':      true,
   157  	'}':      true,
   158  	'~':      true,
   159  	'\u007f': true,
   160  }
   161  
   162  var (
   163  	hexChars = "0123456789abcdef"
   164  	endian   = binary.LittleEndian
   165  )
   166  
   167  const (
   168  	headerSize   = 8 // element size + data size.
   169  	dataSizeOff  = 4
   170  	keyEntrySize = 6 // keyOff +  keyLen
   171  	keyLenOff    = 4
   172  	valTypeSize  = 1
   173  	valEntrySize = 5
   174  )
   175  
   176  // jsonTypePrecedences is for comparing two json.
   177  // See: https://dev.mysql.com/doc/refman/5.7/en/json.html#json-comparison
   178  var jsonTypePrecedences = map[string]int{
   179  	"BLOB":             -1,
   180  	"BIT":              -2,
   181  	"OPAQUE":           -3,
   182  	"DATETIME":         -4,
   183  	"TIME":             -5,
   184  	"DATE":             -6,
   185  	"BOOLEAN":          -7,
   186  	"ARRAY":            -8,
   187  	"OBJECT":           -9,
   188  	"STRING":           -10,
   189  	"INTEGER":          -11,
   190  	"UNSIGNED INTEGER": -11,
   191  	"DOUBLE":           -11,
   192  	"NULL":             -12,
   193  }
   194  
   195  // ModifyType is for modify a JSON. There are three valid values:
   196  // ModifyInsert, ModifyReplace and ModifySet.
   197  type ModifyType byte
   198  
   199  const (
   200  	// ModifyInsert is for insert a new element into a JSON.
   201  	ModifyInsert ModifyType = 0x01
   202  	// ModifyReplace is for replace an old elemList from a JSON.
   203  	ModifyReplace ModifyType = 0x02
   204  	// ModifySet = ModifyInsert | ModifyReplace
   205  	ModifySet ModifyType = 0x03
   206  )
   207  
   208  var (
   209  	// ErrInvalidJSONText means invalid JSON text.
   210  	ErrInvalidJSONText = terror.ClassJSON.New(mysql.ErrInvalidJSONText, mysql.MySQLErrName[mysql.ErrInvalidJSONText])
   211  	// ErrInvalidJSONPath means invalid JSON path.
   212  	ErrInvalidJSONPath = terror.ClassJSON.New(mysql.ErrInvalidJSONPath, mysql.MySQLErrName[mysql.ErrInvalidJSONPath])
   213  	// ErrInvalidJSONData means invalid JSON data.
   214  	ErrInvalidJSONData = terror.ClassJSON.New(mysql.ErrInvalidJSONData, mysql.MySQLErrName[mysql.ErrInvalidJSONData])
   215  	// ErrInvalidJSONPathWildcard means invalid JSON path that contain wildcard characters.
   216  	ErrInvalidJSONPathWildcard = terror.ClassJSON.New(mysql.ErrInvalidJSONPathWildcard, mysql.MySQLErrName[mysql.ErrInvalidJSONPathWildcard])
   217  	// ErrInvalidJSONContainsPathType means invalid JSON contains path type.
   218  	ErrInvalidJSONContainsPathType = terror.ClassJSON.New(mysql.ErrInvalidJSONContainsPathType, mysql.MySQLErrName[mysql.ErrInvalidJSONContainsPathType])
   219  )
   220  
   221  func init() {
   222  	terror.ErrClassToMySQLCodes[terror.ClassJSON] = map[terror.ErrCode]uint16{
   223  		mysql.ErrInvalidJSONText:             mysql.ErrInvalidJSONText,
   224  		mysql.ErrInvalidJSONPath:             mysql.ErrInvalidJSONPath,
   225  		mysql.ErrInvalidJSONData:             mysql.ErrInvalidJSONData,
   226  		mysql.ErrInvalidJSONPathWildcard:     mysql.ErrInvalidJSONPathWildcard,
   227  		mysql.ErrInvalidJSONContainsPathType: mysql.ErrInvalidJSONContainsPathType,
   228  	}
   229  }
   230  
   231  // json_contains_path function type choices
   232  // See: https://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html#function_json-contains-path
   233  const (
   234  	// 'all': 1 if all paths exist within the document, 0 otherwise.
   235  	ContainsPathAll = "all"
   236  	// 'one': 1 if at least one path exists within the document, 0 otherwise.
   237  	ContainsPathOne = "one"
   238  )