storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/s3select/sql/record.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 sql
    18  
    19  import (
    20  	"fmt"
    21  	"io"
    22  
    23  	"github.com/minio/simdjson-go"
    24  )
    25  
    26  // SelectObjectFormat specifies the format of the underlying data
    27  type SelectObjectFormat int
    28  
    29  const (
    30  	// SelectFmtUnknown - unknown format (default value)
    31  	SelectFmtUnknown SelectObjectFormat = iota
    32  	// SelectFmtCSV - CSV format
    33  	SelectFmtCSV
    34  	// SelectFmtJSON - JSON format
    35  	SelectFmtJSON
    36  	// SelectFmtSIMDJSON - SIMD JSON format
    37  	SelectFmtSIMDJSON
    38  	// SelectFmtParquet - Parquet format
    39  	SelectFmtParquet
    40  )
    41  
    42  // WriteCSVOpts - encapsulates options for Select CSV output
    43  type WriteCSVOpts struct {
    44  	FieldDelimiter rune
    45  	Quote          rune
    46  	QuoteEscape    rune
    47  	AlwaysQuote    bool
    48  }
    49  
    50  // Record - is a type containing columns and their values.
    51  type Record interface {
    52  	Get(name string) (*Value, error)
    53  
    54  	// Set a value.
    55  	// Can return a different record type.
    56  	Set(name string, value *Value) (Record, error)
    57  	WriteCSV(writer io.Writer, opts WriteCSVOpts) error
    58  	WriteJSON(writer io.Writer) error
    59  
    60  	// Clone the record and if possible use the destination provided.
    61  	Clone(dst Record) Record
    62  	Reset()
    63  
    64  	// Returns underlying representation
    65  	Raw() (SelectObjectFormat, interface{})
    66  
    67  	// Replaces the underlying data
    68  	Replace(k interface{}) error
    69  }
    70  
    71  // IterToValue converts a simdjson Iter to its underlying value.
    72  // Objects are returned as simdjson.Object
    73  // Arrays are returned as []interface{} with parsed values.
    74  func IterToValue(iter simdjson.Iter) (interface{}, error) {
    75  	switch iter.Type() {
    76  	case simdjson.TypeString:
    77  		v, err := iter.String()
    78  		if err != nil {
    79  			return nil, err
    80  		}
    81  		return v, nil
    82  	case simdjson.TypeFloat:
    83  		v, err := iter.Float()
    84  		if err != nil {
    85  			return nil, err
    86  		}
    87  		return v, nil
    88  	case simdjson.TypeInt:
    89  		v, err := iter.Int()
    90  		if err != nil {
    91  			return nil, err
    92  		}
    93  		return v, nil
    94  	case simdjson.TypeUint:
    95  		v, err := iter.Int()
    96  		if err != nil {
    97  			// Can't fit into int, convert to float.
    98  			v, err := iter.Float()
    99  			return v, err
   100  		}
   101  		return v, nil
   102  	case simdjson.TypeBool:
   103  		v, err := iter.Bool()
   104  		if err != nil {
   105  			return nil, err
   106  		}
   107  		return v, nil
   108  	case simdjson.TypeObject:
   109  		obj, err := iter.Object(nil)
   110  		if err != nil {
   111  			return nil, err
   112  		}
   113  		return *obj, err
   114  	case simdjson.TypeArray:
   115  		arr, err := iter.Array(nil)
   116  		if err != nil {
   117  			return nil, err
   118  		}
   119  		iter := arr.Iter()
   120  		var dst []interface{}
   121  		var next simdjson.Iter
   122  		for {
   123  			typ, err := iter.AdvanceIter(&next)
   124  			if err != nil {
   125  				return nil, err
   126  			}
   127  			if typ == simdjson.TypeNone {
   128  				break
   129  			}
   130  			v, err := IterToValue(next)
   131  			if err != nil {
   132  				return nil, err
   133  			}
   134  			dst = append(dst, v)
   135  		}
   136  		return dst, err
   137  	case simdjson.TypeNull:
   138  		return nil, nil
   139  	}
   140  	return nil, fmt.Errorf("IterToValue: unknown JSON type: %s", iter.Type().String())
   141  }