mirror of
https://github.com/minio/minio.git
synced 2025-11-10 05:59:43 -05:00
Add JSON Path expression evaluation support (#7315)
- Includes support for FROM clause JSON path
This commit is contained in:
committed by
Harshavardhana
parent
b296b3cf8b
commit
e463386921
@@ -17,7 +17,6 @@
|
||||
package json
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
|
||||
"github.com/minio/minio/pkg/s3select/sql"
|
||||
@@ -43,24 +42,22 @@ func (r *Reader) Read() (sql.Record, error) {
|
||||
return nil, io.EOF
|
||||
}
|
||||
|
||||
var data []byte
|
||||
var err error
|
||||
|
||||
var kvs jstream.KVS
|
||||
if v.ValueType == jstream.Object {
|
||||
data, err = json.Marshal(v.Value)
|
||||
// This is a JSON object type (that preserves key
|
||||
// order)
|
||||
kvs = v.Value.(jstream.KVS)
|
||||
} else {
|
||||
// To be AWS S3 compatible Select for JSON needs to
|
||||
// output non-object JSON as single column value
|
||||
// i.e. a map with `_1` as key and value as the
|
||||
// non-object.
|
||||
data, err = json.Marshal(jstream.KVS{jstream.KV{Key: "_1", Value: v.Value}})
|
||||
}
|
||||
if err != nil {
|
||||
return nil, errJSONParsingError(err)
|
||||
kvs = jstream.KVS{jstream.KV{Key: "_1", Value: v.Value}}
|
||||
}
|
||||
|
||||
return &Record{
|
||||
Data: data,
|
||||
KVS: kvs,
|
||||
SelectFormat: sql.SelectFmtJSON,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ import (
|
||||
|
||||
"github.com/bcicen/jstream"
|
||||
"github.com/minio/minio/pkg/s3select/sql"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
// RawJSON is a byte-slice that contains valid JSON
|
||||
@@ -40,34 +39,20 @@ func (b RawJSON) MarshalJSON() ([]byte, error) {
|
||||
|
||||
// Record - is JSON record.
|
||||
type Record struct {
|
||||
// Used in Get()
|
||||
Data []byte
|
||||
|
||||
// Used in Set(), Marshal*()
|
||||
kvs jstream.KVS
|
||||
KVS jstream.KVS
|
||||
|
||||
SelectFormat sql.SelectObjectFormat
|
||||
}
|
||||
|
||||
// Get - gets the value for a column name.
|
||||
func (r *Record) Get(name string) (*sql.Value, error) {
|
||||
result := gjson.GetBytes(r.Data, name)
|
||||
switch result.Type {
|
||||
case gjson.Null:
|
||||
return sql.FromNull(), nil
|
||||
case gjson.False:
|
||||
return sql.FromBool(false), nil
|
||||
case gjson.Number:
|
||||
return sql.FromFloat(result.Float()), nil
|
||||
case gjson.String:
|
||||
return sql.FromString(result.String()), nil
|
||||
case gjson.True:
|
||||
return sql.FromBool(true), nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("unsupported gjson value %v; %v", result, result.Type)
|
||||
// Get is implemented directly in the sql package.
|
||||
return nil, errors.New("not implemented here")
|
||||
}
|
||||
|
||||
// Set - sets the value for a column name.
|
||||
func (r *Record) Set(name string, value *sql.Value) (err error) {
|
||||
func (r *Record) Set(name string, value *sql.Value) error {
|
||||
var v interface{}
|
||||
if b, ok := value.ToBool(); ok {
|
||||
v = b
|
||||
@@ -88,14 +73,14 @@ func (r *Record) Set(name string, value *sql.Value) (err error) {
|
||||
}
|
||||
|
||||
name = strings.Replace(name, "*", "__ALL__", -1)
|
||||
r.kvs = append(r.kvs, jstream.KV{Key: name, Value: v})
|
||||
return err
|
||||
r.KVS = append(r.KVS, jstream.KV{Key: name, Value: v})
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalCSV - encodes to CSV data.
|
||||
func (r *Record) MarshalCSV(fieldDelimiter rune) ([]byte, error) {
|
||||
var csvRecord []string
|
||||
for _, kv := range r.kvs {
|
||||
for _, kv := range r.KVS {
|
||||
var columnValue string
|
||||
switch val := kv.Value.(type) {
|
||||
case bool, float64, int64, string:
|
||||
@@ -125,14 +110,26 @@ func (r *Record) MarshalCSV(fieldDelimiter rune) ([]byte, error) {
|
||||
return data[:len(data)-1], nil
|
||||
}
|
||||
|
||||
// Raw - returns the underlying representation.
|
||||
func (r *Record) Raw() (sql.SelectObjectFormat, interface{}) {
|
||||
return r.SelectFormat, r.KVS
|
||||
}
|
||||
|
||||
// MarshalJSON - encodes to JSON data.
|
||||
func (r *Record) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(r.kvs)
|
||||
return json.Marshal(r.KVS)
|
||||
}
|
||||
|
||||
// Replace the underlying buffer of json data.
|
||||
func (r *Record) Replace(k jstream.KVS) error {
|
||||
r.KVS = k
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewRecord - creates new empty JSON record.
|
||||
func NewRecord() *Record {
|
||||
func NewRecord(f sql.SelectObjectFormat) *Record {
|
||||
return &Record{
|
||||
Data: []byte("{}"),
|
||||
KVS: jstream.KVS{},
|
||||
SelectFormat: f,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user