github.com/dolthub/go-mysql-server@v0.18.0/sql/expression/function/json/json_merge_preserve_test.go (about) 1 // Copyright 2022 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 "testing" 19 20 "github.com/stretchr/testify/require" 21 22 "github.com/dolthub/go-mysql-server/sql" 23 "github.com/dolthub/go-mysql-server/sql/expression" 24 "github.com/dolthub/go-mysql-server/sql/types" 25 ) 26 27 func TestJSONMergePreserve(t *testing.T) { 28 f2, err := NewJSONMergePreserve( 29 expression.NewGetField(0, types.LongText, "arg1", false), 30 expression.NewGetField(1, types.LongText, "arg2", false), 31 ) 32 require.NoError(t, err) 33 34 f3, err := NewJSONMergePreserve( 35 expression.NewGetField(0, types.LongText, "arg1", false), 36 expression.NewGetField(1, types.LongText, "arg2", false), 37 expression.NewGetField(2, types.LongText, "arg3", false), 38 ) 39 require.NoError(t, err) 40 41 f4, err := NewJSONMergePreserve( 42 expression.NewGetField(0, types.LongText, "arg1", false), 43 expression.NewGetField(1, types.LongText, "arg2", false), 44 expression.NewGetField(2, types.LongText, "arg3", false), 45 expression.NewGetField(3, types.LongText, "arg4", false), 46 ) 47 require.NoError(t, err) 48 49 jsonArray1 := []interface{}{1, 2} 50 jsonArray2 := []interface{}{true, false} 51 jsonValue1 := `"single Value"` 52 jsonObj1 := map[string]interface{}{"name": "x"} 53 jsonObj2 := map[string]interface{}{"id": 47} 54 jsonObj3 := map[string]interface{}{"a": 1, "b": 2} 55 jsonObj4 := map[string]interface{}{"a": 3, "c": 4} 56 jsonObj5 := map[string]interface{}{"a": 5, "d": 6} 57 jsonObj6 := map[string]interface{}{"a": 3, "e": 8} 58 jsonObj7 := map[string]interface{}{"a": map[string]interface{}{"one": false, "two": 2.55}, "e": 8} 59 json3ObjResult := map[string]interface{}{"a": []interface{}{float64(1), float64(3), float64(5)}, "b": float64(2), "c": float64(4), "d": float64(6)} 60 json4ObjResult := map[string]interface{}{"a": []interface{}{float64(1), float64(3), float64(5), float64(3)}, "b": float64(2), "c": float64(4), "d": float64(6), "e": float64(8)} 61 sData1 := map[string]interface{}{ 62 "Suspect": map[string]interface{}{ 63 "Name": "Bart", 64 "Hobbies": []interface{}{"Skateboarding", "Mischief"}, 65 }, 66 "Victim": "Lisa", 67 "Case": map[string]interface{}{ 68 "Id": 33845, 69 "Date": "2006-01-02T15:04:05-07:00", 70 "Closed": true, 71 }, 72 } 73 sData2 := map[string]interface{}{ 74 "Suspect": map[string]interface{}{ 75 "Age": 10, 76 "Parents": []interface{}{"Marge", "Homer"}, 77 "Hobbies": []interface{}{"Trouble"}, 78 }, 79 "Witnesses": []interface{}{"Maggie", "Ned"}, 80 } 81 resultData := map[string]interface{}{ 82 "Suspect": map[string]interface{}{ 83 "Age": float64(10), 84 "Name": "Bart", 85 "Hobbies": []interface{}{"Skateboarding", "Mischief", "Trouble"}, 86 "Parents": []interface{}{"Marge", "Homer"}, 87 }, 88 "Victim": "Lisa", 89 "Case": map[string]interface{}{ 90 "Id": float64(33845), 91 "Date": "2006-01-02T15:04:05-07:00", 92 "Closed": true, 93 }, 94 "Witnesses": []interface{}{"Maggie", "Ned"}, 95 } 96 mixedData := []interface{}{ 97 map[string]interface{}{ 98 "a": []interface{}{ 99 float64(1), 100 map[string]interface{}{ 101 "one": false, 102 "two": 2.55, 103 }, 104 }, 105 "b": float64(2), 106 "e": float64(8), 107 }, 108 "single Value", 109 } 110 111 testCases := []struct { 112 f sql.Expression 113 row sql.Row 114 expected interface{} 115 err error 116 }{ 117 {f2, sql.Row{nil, nil}, types.JSONDocument{Val: []interface{}{nil, nil}}, nil}, 118 {f2, sql.Row{jsonArray1, nil}, types.JSONDocument{Val: []interface{}{float64(1), float64(2), nil}}, nil}, 119 {f2, sql.Row{jsonArray1, jsonArray2}, types.JSONDocument{Val: []interface{}{float64(1), float64(2), true, false}}, nil}, 120 {f2, sql.Row{jsonObj1, jsonObj2}, types.JSONDocument{Val: map[string]interface{}{"name": "x", "id": float64(47)}}, nil}, 121 {f2, sql.Row{1, true}, types.JSONDocument{Val: []interface{}{float64(1), true}}, nil}, 122 {f2, sql.Row{jsonArray1, jsonObj2}, types.JSONDocument{Val: []interface{}{float64(1), float64(2), map[string]interface{}{"id": float64(47)}}}, nil}, 123 {f3, sql.Row{jsonObj3, jsonObj4, jsonObj5}, types.JSONDocument{Val: json3ObjResult}, nil}, 124 {f2, sql.Row{sData1, sData2}, types.JSONDocument{Val: resultData}, nil}, 125 {f4, sql.Row{jsonObj3, jsonObj4, jsonObj5, jsonObj6}, types.JSONDocument{Val: json4ObjResult}, nil}, 126 {f3, sql.Row{jsonObj3, jsonObj7, jsonValue1}, types.JSONDocument{Val: mixedData}, nil}, 127 } 128 129 for _, tt := range testCases { 130 t.Run(tt.f.String(), func(t *testing.T) { 131 require := require.New(t) 132 result, err := tt.f.Eval(sql.NewEmptyContext(), tt.row) 133 if tt.err == nil { 134 require.NoError(err) 135 } else { 136 require.Equal(err.Error(), tt.err.Error()) 137 } 138 139 require.Equal(tt.expected, result) 140 }) 141 } 142 }