storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/s3select/internal/parquet-go/data/result.go (about)

     1  /*
     2   * Minio Cloud Storage, (C) 2019 Minio, Inc.
     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 data
    18  
    19  import (
    20  	"fmt"
    21  	"math"
    22  
    23  	"github.com/tidwall/gjson"
    24  
    25  	"storj.io/minio/pkg/s3select/internal/parquet-go/gen-go/parquet"
    26  )
    27  
    28  func resultToBool(result gjson.Result) (value interface{}, err error) {
    29  	switch result.Type {
    30  	case gjson.False, gjson.True:
    31  		return result.Bool(), nil
    32  	}
    33  
    34  	return nil, fmt.Errorf("result is not Bool but %v", result.Type)
    35  }
    36  
    37  func resultToInt32(result gjson.Result) (value interface{}, err error) {
    38  	if value, err = resultToInt64(result); err != nil {
    39  		return nil, err
    40  	}
    41  
    42  	if value.(int64) < math.MinInt32 || value.(int64) > math.MaxInt32 {
    43  		return nil, fmt.Errorf("int32 overflow")
    44  	}
    45  
    46  	return int32(value.(int64)), nil
    47  }
    48  
    49  func resultToInt64(result gjson.Result) (value interface{}, err error) {
    50  	if result.Type == gjson.Number {
    51  		return result.Int(), nil
    52  	}
    53  
    54  	return nil, fmt.Errorf("result is not Number but %v", result.Type)
    55  }
    56  
    57  func resultToFloat(result gjson.Result) (value interface{}, err error) {
    58  	if result.Type == gjson.Number {
    59  		return float32(result.Float()), nil
    60  	}
    61  
    62  	return nil, fmt.Errorf("result is not float32 but %v", result.Type)
    63  }
    64  
    65  func resultToDouble(result gjson.Result) (value interface{}, err error) {
    66  	if result.Type == gjson.Number {
    67  		return result.Float(), nil
    68  	}
    69  
    70  	return nil, fmt.Errorf("result is not float64 but %v", result.Type)
    71  }
    72  
    73  func resultToBytes(result gjson.Result) (interface{}, error) {
    74  	if result.Type != gjson.JSON || !result.IsArray() {
    75  		return nil, fmt.Errorf("result is not byte array but %v", result.Type)
    76  	}
    77  
    78  	data := []byte{}
    79  	for i, r := range result.Array() {
    80  		if r.Type != gjson.Number {
    81  			return nil, fmt.Errorf("result[%v] is not byte but %v", i, r.Type)
    82  		}
    83  
    84  		value := r.Uint()
    85  		if value > math.MaxUint8 {
    86  			return nil, fmt.Errorf("byte overflow in result[%v]", i)
    87  		}
    88  
    89  		data = append(data, byte(value))
    90  	}
    91  
    92  	return data, nil
    93  }
    94  
    95  func resultToString(result gjson.Result) (value interface{}, err error) {
    96  	if result.Type == gjson.String {
    97  		return result.String(), nil
    98  	}
    99  
   100  	return nil, fmt.Errorf("result is not String but %v", result.Type)
   101  }
   102  
   103  func resultToUint8(result gjson.Result) (value interface{}, err error) {
   104  	if value, err = resultToUint64(result); err != nil {
   105  		return nil, err
   106  	}
   107  
   108  	if value.(uint64) > math.MaxUint8 {
   109  		return nil, fmt.Errorf("uint8 overflow")
   110  	}
   111  
   112  	return uint8(value.(uint64)), nil
   113  }
   114  
   115  func resultToUint16(result gjson.Result) (value interface{}, err error) {
   116  	if value, err = resultToUint64(result); err != nil {
   117  		return nil, err
   118  	}
   119  
   120  	if value.(uint64) > math.MaxUint16 {
   121  		return nil, fmt.Errorf("uint16 overflow")
   122  	}
   123  
   124  	return uint16(value.(uint64)), nil
   125  }
   126  
   127  func resultToUint32(result gjson.Result) (value interface{}, err error) {
   128  	if value, err = resultToUint64(result); err != nil {
   129  		return nil, err
   130  	}
   131  
   132  	if value.(uint64) > math.MaxUint32 {
   133  		return nil, fmt.Errorf("uint32 overflow")
   134  	}
   135  
   136  	return uint32(value.(uint64)), nil
   137  }
   138  
   139  func resultToUint64(result gjson.Result) (value interface{}, err error) {
   140  	if result.Type == gjson.Number {
   141  		return result.Uint(), nil
   142  	}
   143  
   144  	return nil, fmt.Errorf("result is not Number but %v", result.Type)
   145  }
   146  
   147  func resultToInt8(result gjson.Result) (value interface{}, err error) {
   148  	if value, err = resultToInt64(result); err != nil {
   149  		return nil, err
   150  	}
   151  
   152  	if value.(int64) < math.MinInt8 || value.(int64) > math.MaxInt8 {
   153  		return nil, fmt.Errorf("int8 overflow")
   154  	}
   155  
   156  	return int8(value.(int64)), nil
   157  }
   158  
   159  func resultToInt16(result gjson.Result) (value interface{}, err error) {
   160  	if value, err = resultToInt64(result); err != nil {
   161  		return nil, err
   162  	}
   163  
   164  	if value.(int64) < math.MinInt16 || value.(int64) > math.MaxInt16 {
   165  		return nil, fmt.Errorf("int16 overflow")
   166  	}
   167  
   168  	return int16(value.(int64)), nil
   169  }
   170  
   171  func stringToParquetValue(value interface{}, parquetType parquet.Type) (interface{}, error) {
   172  	switch parquetType {
   173  	case parquet.Type_INT96, parquet.Type_BYTE_ARRAY, parquet.Type_FIXED_LEN_BYTE_ARRAY:
   174  		return []byte(value.(string)), nil
   175  	}
   176  
   177  	return nil, fmt.Errorf("string cannot be converted to parquet type %v", parquetType)
   178  }
   179  
   180  func uint8ToParquetValue(value interface{}, parquetType parquet.Type) (interface{}, error) {
   181  	switch parquetType {
   182  	case parquet.Type_INT32:
   183  		return int32(value.(uint8)), nil
   184  	case parquet.Type_INT64:
   185  		return int64(value.(uint8)), nil
   186  	}
   187  
   188  	return nil, fmt.Errorf("uint8 cannot be converted to parquet type %v", parquetType)
   189  }
   190  
   191  func uint16ToParquetValue(value interface{}, parquetType parquet.Type) (interface{}, error) {
   192  	switch parquetType {
   193  	case parquet.Type_INT32:
   194  		return int32(value.(uint16)), nil
   195  	case parquet.Type_INT64:
   196  		return int64(value.(uint16)), nil
   197  	}
   198  
   199  	return nil, fmt.Errorf("uint16 cannot be converted to parquet type %v", parquetType)
   200  }
   201  
   202  func uint32ToParquetValue(value interface{}, parquetType parquet.Type) (interface{}, error) {
   203  	switch parquetType {
   204  	case parquet.Type_INT32:
   205  		return int32(value.(uint32)), nil
   206  	case parquet.Type_INT64:
   207  		return int64(value.(uint32)), nil
   208  	}
   209  
   210  	return nil, fmt.Errorf("uint32 cannot be converted to parquet type %v", parquetType)
   211  }
   212  
   213  func uint64ToParquetValue(value interface{}, parquetType parquet.Type) (interface{}, error) {
   214  	switch parquetType {
   215  	case parquet.Type_INT32:
   216  		return int32(value.(uint64)), nil
   217  	case parquet.Type_INT64:
   218  		return int64(value.(uint64)), nil
   219  	}
   220  
   221  	return nil, fmt.Errorf("uint64 cannot be converted to parquet type %v", parquetType)
   222  }
   223  
   224  func int8ToParquetValue(value interface{}, parquetType parquet.Type) (interface{}, error) {
   225  	switch parquetType {
   226  	case parquet.Type_INT32:
   227  		return int32(value.(int8)), nil
   228  	case parquet.Type_INT64:
   229  		return int64(value.(int8)), nil
   230  	}
   231  
   232  	return nil, fmt.Errorf("int8 cannot be converted to parquet type %v", parquetType)
   233  }
   234  
   235  func int16ToParquetValue(value interface{}, parquetType parquet.Type) (interface{}, error) {
   236  	switch parquetType {
   237  	case parquet.Type_INT32:
   238  		return int32(value.(int16)), nil
   239  	case parquet.Type_INT64:
   240  		return int64(value.(int16)), nil
   241  	}
   242  
   243  	return nil, fmt.Errorf("int16 cannot be converted to parquet type %v", parquetType)
   244  }
   245  
   246  func int32ToParquetValue(value interface{}, parquetType parquet.Type) (interface{}, error) {
   247  	switch parquetType {
   248  	case parquet.Type_INT32:
   249  		return value.(int32), nil
   250  	case parquet.Type_INT64:
   251  		return int64(value.(int32)), nil
   252  	}
   253  
   254  	return nil, fmt.Errorf("int32 cannot be converted to parquet type %v", parquetType)
   255  }
   256  
   257  func int64ToParquetValue(value interface{}, parquetType parquet.Type) (interface{}, error) {
   258  	switch parquetType {
   259  	case parquet.Type_INT32:
   260  		return int32(value.(int64)), nil
   261  	case parquet.Type_INT64:
   262  		return value.(int64), nil
   263  	}
   264  
   265  	return nil, fmt.Errorf("int64 cannot be converted to parquet type %v", parquetType)
   266  }
   267  
   268  func resultToParquetValueByConvertedValue(result gjson.Result, convertedType parquet.ConvertedType, parquetType parquet.Type) (value interface{}, err error) {
   269  	if result.Type == gjson.Null {
   270  		return nil, nil
   271  	}
   272  
   273  	switch convertedType {
   274  	case parquet.ConvertedType_UTF8:
   275  		if value, err = resultToString(result); err != nil {
   276  			return nil, err
   277  		}
   278  		return stringToParquetValue(value, parquetType)
   279  	case parquet.ConvertedType_UINT_8:
   280  		if value, err = resultToUint8(result); err != nil {
   281  			return nil, err
   282  		}
   283  		return uint8ToParquetValue(value, parquetType)
   284  	case parquet.ConvertedType_UINT_16:
   285  		if value, err = resultToUint16(result); err != nil {
   286  			return nil, err
   287  		}
   288  		return uint16ToParquetValue(value, parquetType)
   289  	case parquet.ConvertedType_UINT_32:
   290  		if value, err = resultToUint32(result); err != nil {
   291  			return nil, err
   292  		}
   293  		return uint32ToParquetValue(value, parquetType)
   294  	case parquet.ConvertedType_UINT_64:
   295  		if value, err = resultToUint64(result); err != nil {
   296  			return nil, err
   297  		}
   298  		return uint64ToParquetValue(value, parquetType)
   299  	case parquet.ConvertedType_INT_8:
   300  		if value, err = resultToInt8(result); err != nil {
   301  			return nil, err
   302  		}
   303  		return int8ToParquetValue(value, parquetType)
   304  	case parquet.ConvertedType_INT_16:
   305  		if value, err = resultToInt16(result); err != nil {
   306  			return nil, err
   307  		}
   308  		return int16ToParquetValue(value, parquetType)
   309  	case parquet.ConvertedType_INT_32:
   310  		if value, err = resultToInt32(result); err != nil {
   311  			return nil, err
   312  		}
   313  		return int32ToParquetValue(value, parquetType)
   314  	case parquet.ConvertedType_INT_64:
   315  		if value, err = resultToInt64(result); err != nil {
   316  			return nil, err
   317  		}
   318  		return int64ToParquetValue(value, parquetType)
   319  	}
   320  
   321  	return nil, fmt.Errorf("unsupported converted type %v", convertedType)
   322  }
   323  
   324  func resultToParquetValue(result gjson.Result, parquetType parquet.Type, convertedType *parquet.ConvertedType) (interface{}, error) {
   325  	if convertedType != nil {
   326  		return resultToParquetValueByConvertedValue(result, *convertedType, parquetType)
   327  	}
   328  
   329  	if result.Type == gjson.Null {
   330  		return nil, nil
   331  	}
   332  
   333  	switch parquetType {
   334  	case parquet.Type_BOOLEAN:
   335  		return resultToBool(result)
   336  	case parquet.Type_INT32:
   337  		return resultToInt32(result)
   338  	case parquet.Type_INT64:
   339  		return resultToInt64(result)
   340  	case parquet.Type_FLOAT:
   341  		return resultToFloat(result)
   342  	case parquet.Type_DOUBLE:
   343  		return resultToDouble(result)
   344  	case parquet.Type_INT96, parquet.Type_BYTE_ARRAY, parquet.Type_FIXED_LEN_BYTE_ARRAY:
   345  		return resultToBytes(result)
   346  	}
   347  
   348  	return nil, fmt.Errorf("unknown parquet type %v", parquetType)
   349  }
   350  
   351  func resultToArray(result gjson.Result) ([]gjson.Result, error) {
   352  	if result.Type == gjson.Null {
   353  		return nil, nil
   354  	}
   355  
   356  	if result.Type != gjson.JSON || !result.IsArray() {
   357  		return nil, fmt.Errorf("result is not Array but %v", result.Type)
   358  	}
   359  
   360  	return result.Array(), nil
   361  }