github.com/dolthub/go-mysql-server@v0.18.0/sql/expression/function/json/json_unsupported.go (about)

     1  // Copyright 2021 Dolthub, 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  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package json
    16  
    17  import (
    18  	"gopkg.in/src-d/go-errors.v1"
    19  
    20  	"github.com/dolthub/go-mysql-server/sql"
    21  )
    22  
    23  // ErrUnsupportedJSONFunction is returned when a unsupported JSON function is called.
    24  var ErrUnsupportedJSONFunction = errors.NewKind("unsupported JSON function: %s")
    25  
    26  ///////////////////////////
    27  // JSON search functions //
    28  ///////////////////////////
    29  
    30  // JSON_OVERLAPS(json_doc1, json_doc2)
    31  //
    32  // JSONOverlaps Compares two JSON documents. Returns true (1) if the two document have any key-value pairs or array
    33  // elements in common. If both arguments are scalars, the function performs a simple equality test.
    34  //
    35  // This function serves as counterpart to JSON_CONTAINS(), which requires all elements of the array searched for to be
    36  // present in the array searched in. Thus, JSON_CONTAINS() performs an AND operation on search keys, while
    37  // JSON_OVERLAPS() performs an OR operation.
    38  //
    39  // Queries on JSON columns of InnoDB tables using JSON_OVERLAPS() in the WHERE clause can be optimized using
    40  // multi-valued indexes. Multi-Valued Indexes, provides detailed information and examples.
    41  //
    42  // https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#function_json-overlaps
    43  type JSONOverlaps struct {
    44  	sql.Expression
    45  }
    46  
    47  var _ sql.FunctionExpression = JSONOverlaps{}
    48  
    49  // NewJSONOverlaps creates a new JSONOverlaps function.
    50  func NewJSONOverlaps(args ...sql.Expression) (sql.Expression, error) {
    51  	return nil, ErrUnsupportedJSONFunction.New(JSONOverlaps{}.FunctionName())
    52  }
    53  
    54  // FunctionName implements sql.FunctionExpression
    55  func (j JSONOverlaps) FunctionName() string {
    56  	return "json_overlaps"
    57  }
    58  
    59  // Description implements sql.FunctionExpression
    60  func (j JSONOverlaps) Description() string {
    61  	return "compares two JSON documents, returns TRUE (1) if these have any key-value pairs or array elements in common, otherwise FALSE (0)."
    62  }
    63  
    64  // IsUnsupported implements sql.UnsupportedFunctionStub
    65  func (j JSONOverlaps) IsUnsupported() bool {
    66  	return true
    67  }
    68  
    69  // JSON_SEARCH(json_doc, one_or_all, search_str[, escape_char[, path] ...])
    70  //
    71  // JSONSearch Returns the path to the given string within a JSON document. Returns NULL if any of the json_doc,
    72  // search_str, or path arguments are NULL; no path exists within the document; or search_str is not found. An error
    73  // occurs if the json_doc argument is not a valid JSON document, any path argument is not a valid path expression,
    74  // one_or_all is not 'one' or 'all', or escape_char is not a constant expression.
    75  // The one_or_all argument affects the search as follows:
    76  //   - 'one': The search terminates after the first match and returns one path string. It is undefined which match is
    77  //     considered first.
    78  //   - 'all': The search returns all matching path strings such that no duplicate paths are included. If there are
    79  //     multiple strings, they are autowrapped as an array. The order of the array elements is undefined.
    80  //
    81  // Within the search_str search string argument, the % and _ characters work as for the LIKE operator: % matches any
    82  // number of characters (including zero characters), and _ matches exactly one character.
    83  //
    84  // To specify a literal % or _ character in the search string, precede it by the escape character. The default is \ if
    85  // the escape_char argument is missing or NULL. Otherwise, escape_char must be a constant that is empty or one character.
    86  // For more information about matching and escape character behavior, see the description of LIKE in Section 12.8.1,
    87  // “String Comparison Functions and Operators”: https://dev.mysql.com/doc/refman/8.0/en/string-comparison-functions.html
    88  // For escape character handling, a difference from the LIKE behavior is that the escape character for JSON_SEARCH()
    89  // must evaluate to a constant at compile time, not just at execution time. For example, if JSON_SEARCH() is used in a
    90  // prepared statement and the escape_char argument is supplied using a ? parameter, the parameter value might be
    91  // constant at execution time, but is not at compile time.
    92  //
    93  // https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#function_json-search
    94  type JSONSearch struct {
    95  	sql.Expression
    96  }
    97  
    98  var _ sql.FunctionExpression = JSONSearch{}
    99  
   100  // NewJSONSearch creates a new NewJSONSearch function.
   101  func NewJSONSearch(args ...sql.Expression) (sql.Expression, error) {
   102  	return nil, ErrUnsupportedJSONFunction.New(JSONSearch{}.FunctionName())
   103  }
   104  
   105  // FunctionName implements sql.FunctionExpression
   106  func (j JSONSearch) FunctionName() string {
   107  	return "json_search"
   108  }
   109  
   110  // Description implements sql.FunctionExpression
   111  func (j JSONSearch) Description() string {
   112  	return "path to value within JSON document."
   113  }
   114  
   115  // IsUnsupported implements sql.UnsupportedFunctionStub
   116  func (j JSONSearch) IsUnsupported() bool {
   117  	return true
   118  }
   119  
   120  // value MEMBER OF(json_array)
   121  //
   122  // Returns true (1) if value is an element of json_array, otherwise returns false (0). value must be a scalar or a JSON
   123  // document; if it is a scalar, the operator attempts to treat it as an element of a JSON array. Queries using
   124  // MEMBER OF() on JSON columns of InnoDB tables in the WHERE clause can be optimized using multi-valued indexes. See
   125  // Multi-Valued Indexes, for detailed information and examples.
   126  //
   127  // https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_member-of
   128  // TODO(andy): relocate
   129  
   130  /////////////////////////////
   131  // JSON creation functions //
   132  /////////////////////////////
   133  
   134  // JSON_QUOTE(string)
   135  //
   136  // JSONQuote Quotes a string as a JSON value by wrapping it with double quote characters and escaping interior quote and
   137  // other characters, then returning the result as a utf8mb4 string. Returns NULL if the argument is NULL. This function
   138  // is typically used to produce a valid JSON string literal for inclusion within a JSON document. Certain special
   139  // characters are escaped with backslashes per the escape sequences shown in Table 12.23, “JSON_UNQUOTE() Special
   140  // Character Escape Sequences”:
   141  // https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html#json-unquote-character-escape-sequences
   142  //
   143  // https://dev.mysql.com/doc/refman/8.0/en/json-creation-functions.html#function_json-quote
   144  type JSONQuote struct {
   145  	sql.Expression
   146  }
   147  
   148  var _ sql.FunctionExpression = JSONQuote{}
   149  
   150  // NewJSONQuote creates a new JSONQuote function.
   151  func NewJSONQuote(args ...sql.Expression) (sql.Expression, error) {
   152  	return nil, ErrUnsupportedJSONFunction.New(JSONQuote{}.FunctionName())
   153  }
   154  
   155  // FunctionName implements sql.FunctionExpression
   156  func (j JSONQuote) FunctionName() string {
   157  	return "json_quote"
   158  }
   159  
   160  // Description implements sql.FunctionExpression
   161  func (j JSONQuote) Description() string {
   162  	return "extracts data from a json document using json paths. Extracting a string will result in that string being quoted. To avoid this, use JSON_UNQUOTE(JSON_EXTRACT(json_doc, path, ...))."
   163  }
   164  
   165  // IsUnsupported implements sql.UnsupportedFunctionStub
   166  func (j JSONQuote) IsUnsupported() bool {
   167  	return true
   168  }
   169  
   170  /////////////////////////////////
   171  // JSON modification functions //
   172  /////////////////////////////////
   173  
   174  // JSON_MERGE_PATCH(json_doc, json_doc[, json_doc] ...)
   175  //
   176  // JSONMergePatch Performs an RFC 7396 compliant merge of two or more JSON documents and returns the merged result,
   177  // without preserving members having duplicate keys. Raises an error if at least one of the documents passed as arguments
   178  // to this function is not valid. JSONMergePatch performs a merge as follows:
   179  //   - If the first argument is not an object, the result of the merge is the same as if an empty object had been merged
   180  //     with the second argument.
   181  //   - If the second argument is not an object, the result of the merge is the second argument.
   182  //   - If both arguments are objects, the result of the merge is an object with the following members:
   183  //   - All members of the first object which do not have a corresponding member with the same key in the second
   184  //     object.
   185  //   - All members of the second object which do not have a corresponding key in the first object, and whose value is
   186  //     not the JSON null literal.
   187  //   - All members with a key that exists in both the first and the second object, and whose value in the second
   188  //     object is not the JSON null literal. The values of these members are the results of recursively merging the
   189  //     value in the first object with the value in the second object.
   190  //
   191  // The behavior of JSONMergePatch is the same as that of JSONMergePreserve, with the following two exceptions:
   192  //   - JSONMergePatch removes any member in the first object with a matching key in the second object, provided that
   193  //     the value associated with the key in the second object is not JSON null.
   194  //   - If the second object has a member with a key matching a member in the first object, JSONMergePatch replaces
   195  //     the value in the first object with the value in the second object, whereas JSONMergePreserve appends the
   196  //     second value to the first value.
   197  //
   198  // https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html#function_json-merge-patch
   199  type JSONMergePatch struct {
   200  	sql.Expression
   201  }
   202  
   203  var _ sql.FunctionExpression = JSONMergePatch{}
   204  
   205  // NewJSONMergePatch creates a new JSONMergePatch function.
   206  func NewJSONMergePatch(args ...sql.Expression) (sql.Expression, error) {
   207  	return nil, ErrUnsupportedJSONFunction.New(JSONMergePatch{}.FunctionName())
   208  }
   209  
   210  // FunctionName implements sql.FunctionExpression
   211  func (j JSONMergePatch) FunctionName() string {
   212  	return "json_merge_patch"
   213  }
   214  
   215  // Description implements sql.FunctionExpression
   216  func (j JSONMergePatch) Description() string {
   217  	return "merges JSON documents, replacing values of duplicate keys"
   218  }
   219  
   220  // IsUnsupported implements sql.UnsupportedFunctionStub
   221  func (j JSONMergePatch) IsUnsupported() bool {
   222  	return true
   223  }
   224  
   225  // JSON_MERGE(json_doc, json_doc[, json_doc] ...)
   226  //
   227  // JSONMerge Merges two or more JSON documents. Synonym for JSONMergePreserve(); deprecated in MySQL 8.0.3 and subject
   228  // to removal in a future release.
   229  //
   230  // https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html#function_json-merge
   231  type JSONMerge struct {
   232  	sql.Expression
   233  }
   234  
   235  //////////////////////////////
   236  // JSON attribute functions //
   237  //////////////////////////////
   238  
   239  // JSON_TYPE(json_val)
   240  //
   241  // Returns a utf8mb4 string indicating the type of a JSON value. This can be an object, an array, or a scalar type.
   242  // JSONType returns NULL if the argument is NULL. An error occurs if the argument is not a valid JSON value
   243  //
   244  // https://dev.mysql.com/doc/refman/8.0/en/json-attribute-functions.html#function_json-type
   245  type JSONType struct {
   246  	sql.Expression
   247  }
   248  
   249  var _ sql.FunctionExpression = JSONType{}
   250  
   251  // NewJSONType creates a new JSONType function.
   252  func NewJSONType(args ...sql.Expression) (sql.Expression, error) {
   253  	return nil, ErrUnsupportedJSONFunction.New(JSONType{}.FunctionName())
   254  }
   255  
   256  // FunctionName implements sql.FunctionExpression
   257  func (j JSONType) FunctionName() string {
   258  	return "json_type"
   259  }
   260  
   261  // Description implements sql.FunctionExpression
   262  func (j JSONType) Description() string {
   263  	return "returns type of JSON value."
   264  }
   265  
   266  // IsUnsupported implements sql.UnsupportedFunctionStub
   267  func (j JSONType) IsUnsupported() bool {
   268  	return true
   269  }
   270  
   271  //////////////////////////
   272  // JSON table functions //
   273  //////////////////////////
   274  
   275  // JSON_TABLE(expr, path COLUMNS (column_list) [AS] alias)
   276  //
   277  // JSONTable Extracts data from a JSON document and returns it as a relational table having the specified columns.
   278  // TODO(andy): this doc was heavily truncated
   279  //
   280  // https://dev.mysql.com/doc/refman/8.0/en/json-table-functions.html#function_json-table
   281  type JSONTable struct {
   282  	sql.Expression
   283  }
   284  
   285  var _ sql.FunctionExpression = JSONTable{}
   286  
   287  // NewJSONTable creates a new JSONTable function.
   288  func NewJSONTable(args ...sql.Expression) (sql.Expression, error) {
   289  	return nil, ErrUnsupportedJSONFunction.New(JSONTable{}.FunctionName())
   290  }
   291  
   292  // FunctionName implements sql.FunctionExpression
   293  func (j JSONTable) FunctionName() string {
   294  	return "json_table"
   295  }
   296  
   297  // Description implements sql.FunctionExpression
   298  func (j JSONTable) Description() string {
   299  	return "returns data from a JSON expression as a relational table."
   300  }
   301  
   302  // IsUnsupported implements sql.UnsupportedFunctionStub
   303  func (j JSONTable) IsUnsupported() bool {
   304  	return true
   305  }
   306  
   307  ///////////////////////////////
   308  // JSON validation functions //
   309  ///////////////////////////////
   310  
   311  // JSON_SCHEMA_VALID(schema,document)
   312  //
   313  // JSONSchemaValid Validates a JSON document against a JSON schema. Both schema and document are required. The schema
   314  // must be a valid JSON object; the document must be a valid JSON document. Provided that these conditions are met: If
   315  // the document validates against the schema, the function returns true (1); otherwise, it returns false (0).
   316  // https://dev.mysql.com/doc/refman/8.0/en/json-validation-functions.html#function_json-schema-valid
   317  type JSONSchemaValid struct {
   318  	sql.Expression
   319  }
   320  
   321  var _ sql.FunctionExpression = JSONSchemaValid{}
   322  
   323  // NewJSONSchemaValid creates a new JSONSchemaValid function.
   324  func NewJSONSchemaValid(args ...sql.Expression) (sql.Expression, error) {
   325  	return nil, ErrUnsupportedJSONFunction.New(JSONSchemaValid{}.FunctionName())
   326  }
   327  
   328  // FunctionName implements sql.FunctionExpression
   329  func (j JSONSchemaValid) FunctionName() string {
   330  	return "json_schema_valid"
   331  }
   332  
   333  // Description implements sql.FunctionExpression
   334  func (j JSONSchemaValid) Description() string {
   335  	return "validates JSON document against JSON schema; returns TRUE/1 if document validates against schema, or FALSE/0 if it does not."
   336  }
   337  
   338  // IsUnsupported implements sql.UnsupportedFunctionStub
   339  func (j JSONSchemaValid) IsUnsupported() bool {
   340  	return true
   341  }
   342  
   343  // JSON_SCHEMA_VALIDATION_REPORT(schema,document)
   344  //
   345  // JSONSchemaValidationReport Validates a JSON document against a JSON schema. Both schema and document are required.
   346  // As with JSONSchemaValid, the schema must be a valid JSON object, and the document must be a valid JSON document.
   347  // Provided that these conditions are met, the function returns a report, as a JSON document, on the outcome of the
   348  // validation. If the JSON document is considered valid according to the JSON Schema, the function returns a JSON object
   349  // with one property valid having the value "true". If the JSON document fails validation, the function returns a JSON
   350  // object which includes the properties listed here:
   351  //   - valid: Always "false" for a failed schema validation
   352  //   - reason: A human-readable string containing the reason for the failure
   353  //   - schema-location: A JSON pointer URI fragment identifier indicating where in the JSON schema the validation failed
   354  //     (see Note following this list)
   355  //   - document-location: A JSON pointer URI fragment identifier indicating where in the JSON document the validation
   356  //     failed (see Note following this list)
   357  //   - schema-failed-keyword: A string containing the name of the keyword or property in the JSON schema that was
   358  //     violated
   359  //
   360  // https://dev.mysql.com/doc/refman/8.0/en/json-validation-functions.html#function_json-schema-validation-report
   361  type JSONSchemaValidationReport struct {
   362  	sql.Expression
   363  }
   364  
   365  var _ sql.FunctionExpression = JSONSchemaValidationReport{}
   366  
   367  // NewJSONSchemaValidationReport creates a new JSONSchemaValidationReport function.
   368  func NewJSONSchemaValidationReport(args ...sql.Expression) (sql.Expression, error) {
   369  	return nil, ErrUnsupportedJSONFunction.New(JSONSchemaValidationReport{}.FunctionName())
   370  }
   371  
   372  // FunctionName implements sql.FunctionExpression
   373  func (j JSONSchemaValidationReport) FunctionName() string {
   374  	return "json_schema_validation_report"
   375  }
   376  
   377  // Description implements sql.FunctionExpression
   378  func (j JSONSchemaValidationReport) Description() string {
   379  	return "validates JSON document against JSON schema; returns report in JSON format on outcome on validation including success or failure and reasons for failure."
   380  }
   381  
   382  // IsUnsupported implements sql.UnsupportedFunctionStub
   383  func (j JSONSchemaValidationReport) IsUnsupported() bool {
   384  	return true
   385  }
   386  
   387  ////////////////////////////
   388  // JSON utility functions //
   389  ////////////////////////////
   390  
   391  // JSON_PRETTY(json_val)
   392  //
   393  // JSONPretty Provides pretty-printing of JSON values similar to that implemented in PHP and by other languages and
   394  // database systems. The value supplied must be a JSON value or a valid string representation of a JSON value.
   395  // Extraneous whitespaces and newlines present in this value have no effect on the output. For a NULL value, the
   396  // function returns NULL. If the value is not a JSON document, or if it cannot be parsed as one, the function fails
   397  // with an error. Formatting of the output from this function adheres to the following rules:
   398  //   - Each array element or object member appears on a separate line, indented by one additional level as compared to
   399  //     its parent.
   400  //   - Each level of indentation adds two leading spaces.
   401  //   - A comma separating individual array elements or object members is printed before the newline that separates the
   402  //     two elements or members.
   403  //   - The key and the value of an object member are separated by a colon followed by a space (': ').
   404  //   - An empty object or array is printed on a single line. No space is printed between the opening and closing brace.
   405  //   - Special characters in string scalars and key names are escaped employing the same rules used by JSONQuote.
   406  //
   407  // https://dev.mysql.com/doc/refman/8.0/en/json-utility-functions.html#function_json-pretty
   408  type JSONPretty struct {
   409  	sql.Expression
   410  }
   411  
   412  var _ sql.FunctionExpression = JSONPretty{}
   413  
   414  // NewJSONPretty creates a new JSONPretty function.
   415  func NewJSONPretty(args ...sql.Expression) (sql.Expression, error) {
   416  	return nil, ErrUnsupportedJSONFunction.New(JSONPretty{}.FunctionName())
   417  }
   418  
   419  // FunctionName implements sql.FunctionExpression
   420  func (j JSONPretty) FunctionName() string {
   421  	return "json_pretty"
   422  }
   423  
   424  // Description implements sql.FunctionExpression
   425  func (j JSONPretty) Description() string {
   426  	return "prints a JSON document in human-readable format."
   427  }
   428  
   429  // IsUnsupported implements sql.UnsupportedFunctionStub
   430  func (j JSONPretty) IsUnsupported() bool {
   431  	return true
   432  }
   433  
   434  // JSON_STORAGE_FREE(json_val)
   435  //
   436  // JSONStorageFree For a JSON column value, this function shows how much storage space was freed in its binary
   437  // representation after it was updated in place using JSON_SET(), JSON_REPLACE(), or JSON_REMOVE(). The argument can
   438  // also be a valid JSON document or a string which can be parsed as one—either as a literal value or as the value of a
   439  // user variable—in which case the function returns 0. It returns a positive, nonzero value if the argument is a JSON
   440  // column value which has been updated as described previously, such that its binary representation takes up less space
   441  // than it did prior to the update. For a JSON column which has been updated such that its binary representation is the
   442  // same as or larger than before, or if the update was not able to take advantage of a partial update, it returns 0; it
   443  // returns NULL if the argument is NULL. If json_val is not NULL, and neither is a valid JSON document nor can be
   444  // successfully parsed as one, an error results.
   445  //
   446  // https://dev.mysql.com/doc/refman/8.0/en/json-utility-functions.html#function_json-storage-size
   447  type JSONStorageFree struct {
   448  	sql.Expression
   449  }
   450  
   451  var _ sql.FunctionExpression = JSONStorageFree{}
   452  
   453  // NewJSONStorageFree creates a new JSONStorageFree function.
   454  func NewJSONStorageFree(args ...sql.Expression) (sql.Expression, error) {
   455  	return nil, ErrUnsupportedJSONFunction.New(JSONStorageFree{}.FunctionName())
   456  }
   457  
   458  // FunctionName implements sql.FunctionExpression
   459  func (j JSONStorageFree) FunctionName() string {
   460  	return "json_storage_free"
   461  }
   462  
   463  // Description implements sql.FunctionExpression
   464  func (j JSONStorageFree) Description() string {
   465  	return "returns freed space within binary representation of JSON column value following partial update."
   466  }
   467  
   468  // IsUnsupported implements sql.UnsupportedFunctionStub
   469  func (j JSONStorageFree) IsUnsupported() bool {
   470  	return true
   471  }
   472  
   473  // JSON_STORAGE_SIZE(json_val)
   474  //
   475  // JSONStorageSize This function returns the number of bytes used to store the binary representation of a JSON document.
   476  // When the argument is a JSON column, this is the space used to store the JSON document as it was inserted into the
   477  // column, prior to any partial updates that may have been performed on it afterwards. json_val must be a valid JSON
   478  // document or a string which can be parsed as one. In the case where it is string, the function returns the amount of
   479  // storage space in the JSON binary representation that is created by parsing the string as JSON and converting it to
   480  // binary. It returns NULL if the argument is NULL. An error results when json_val is not NULL, and is not—or cannot be
   481  // successfully parsed as—a JSON document.
   482  //
   483  // https://dev.mysql.com/doc/refman/8.0/en/json-utility-functions.html#function_json-storage-size
   484  type JSONStorageSize struct {
   485  	sql.Expression
   486  }
   487  
   488  var _ sql.FunctionExpression = JSONStorageSize{}
   489  
   490  // NewJSONStorageSize creates a new JSONStorageSize function.
   491  func NewJSONStorageSize(args ...sql.Expression) (sql.Expression, error) {
   492  	return nil, ErrUnsupportedJSONFunction.New(JSONStorageSize{}.FunctionName())
   493  }
   494  
   495  // FunctionName implements sql.FunctionExpression
   496  func (j JSONStorageSize) FunctionName() string {
   497  	return "json_storage_size"
   498  }
   499  
   500  // Description implements sql.FunctionExpression
   501  func (j JSONStorageSize) Description() string {
   502  	return "returns space used for storage of binary representation of a JSON document."
   503  }
   504  
   505  // IsUnsupported implements sql.UnsupportedFunctionStub
   506  func (j JSONStorageSize) IsUnsupported() bool {
   507  	return true
   508  }