1// Copyright (c) 2021 Snowflake Computing Inc. All right reserved.
2
3package gosnowflake
4
5import (
6	"bytes"
7	"reflect"
8	"testing"
9)
10
11const (
12	forceJSON = "ALTER SESSION SET GO_QUERY_RESULT_FORMAT = JSON"
13)
14
15func TestJSONInt(t *testing.T) {
16	testInt(t, true)
17}
18
19func TestJSONFloat32(t *testing.T) {
20	testFloat32(t, true)
21}
22
23func TestJSONFloat64(t *testing.T) {
24	testFloat64(t, true)
25}
26
27func TestJSONVariousTypes(t *testing.T) {
28	runTests(t, dsn, func(dbt *DBTest) {
29		dbt.mustExec(forceJSON)
30		rows := dbt.mustQuery(selectVariousTypes)
31		defer rows.Close()
32		if !rows.Next() {
33			dbt.Error("failed to query")
34		}
35		cc, err := rows.Columns()
36		if err != nil {
37			dbt.Errorf("columns: %v", cc)
38		}
39		ct, err := rows.ColumnTypes()
40		if err != nil {
41			dbt.Errorf("column types: %v", ct)
42		}
43		var v1 float32
44		var v2 int
45		var v3 string
46		var v4 float64
47		var v5 []byte
48		var v6 bool
49		err = rows.Scan(&v1, &v2, &v3, &v4, &v5, &v6)
50		if err != nil {
51			dbt.Errorf("failed to scan: %#v", err)
52		}
53		if v1 != 1.0 {
54			dbt.Errorf("failed to scan. %#v", v1)
55		}
56		if ct[0].Name() != "C1" || ct[1].Name() != "C2" || ct[2].Name() != "C3" || ct[3].Name() != "C4" || ct[4].Name() != "C5" || ct[5].Name() != "C6" {
57			dbt.Errorf("failed to get column names: %#v", ct)
58		}
59		if ct[0].ScanType() != reflect.TypeOf(float64(0)) {
60			dbt.Errorf("failed to get scan type. expected: %v, got: %v", reflect.TypeOf(float64(0)), ct[0].ScanType())
61		}
62		if ct[1].ScanType() != reflect.TypeOf(int64(0)) {
63			dbt.Errorf("failed to get scan type. expected: %v, got: %v", reflect.TypeOf(int64(0)), ct[1].ScanType())
64		}
65		var pr, sc int64
66		var cLen int64
67		var canNull bool
68		pr, sc = dbt.mustDecimalSize(ct[0])
69		if pr != 30 || sc != 2 {
70			dbt.Errorf("failed to get precision and scale. %#v", ct[0])
71		}
72		dbt.mustFailLength(ct[0])
73		canNull = dbt.mustNullable(ct[0])
74		if canNull {
75			dbt.Errorf("failed to get nullable. %#v", ct[0])
76		}
77		if cLen != 0 {
78			dbt.Errorf("failed to get length. %#v", ct[0])
79		}
80		if v2 != 2 {
81			dbt.Errorf("failed to scan. %#v", v2)
82		}
83		pr, sc = dbt.mustDecimalSize(ct[1])
84		if pr != 38 || sc != 0 {
85			dbt.Errorf("failed to get precision and scale. %#v", ct[1])
86		}
87		dbt.mustFailLength(ct[1])
88		canNull = dbt.mustNullable(ct[1])
89		if canNull {
90			dbt.Errorf("failed to get nullable. %#v", ct[1])
91		}
92		if v3 != "t3" {
93			dbt.Errorf("failed to scan. %#v", v3)
94		}
95		dbt.mustFailDecimalSize(ct[2])
96		cLen = dbt.mustLength(ct[2])
97		if cLen != 2 {
98			dbt.Errorf("failed to get length. %#v", ct[2])
99		}
100		canNull = dbt.mustNullable(ct[2])
101		if canNull {
102			dbt.Errorf("failed to get nullable. %#v", ct[2])
103		}
104		if v4 != 4.2 {
105			dbt.Errorf("failed to scan. %#v", v4)
106		}
107		dbt.mustFailDecimalSize(ct[3])
108		dbt.mustFailLength(ct[3])
109		canNull = dbt.mustNullable(ct[3])
110		if canNull {
111			dbt.Errorf("failed to get nullable. %#v", ct[3])
112		}
113		if !bytes.Equal(v5, []byte{0xab, 0xcd}) {
114			dbt.Errorf("failed to scan. %#v", v5)
115		}
116		dbt.mustFailDecimalSize(ct[4])
117		cLen = dbt.mustLength(ct[4]) // BINARY
118		if cLen != 8388608 {
119			dbt.Errorf("failed to get length. %#v", ct[4])
120		}
121		canNull = dbt.mustNullable(ct[4])
122		if canNull {
123			dbt.Errorf("failed to get nullable. %#v", ct[4])
124		}
125		if !v6 {
126			dbt.Errorf("failed to scan. %#v", v6)
127		}
128		dbt.mustFailDecimalSize(ct[5])
129		dbt.mustFailLength(ct[5])
130		/*canNull = dbt.mustNullable(ct[5])
131		if canNull {
132			dbt.Errorf("failed to get nullable. %#v", ct[5])
133		}*/
134
135	})
136}
137
138func TestJSONString(t *testing.T) {
139	testString(t, true)
140}
141
142func TestJSONSimpleDateTimeTimestampFetch(t *testing.T) {
143	testSimpleDateTimeTimestampFetch(t, true)
144}
145
146func TestJSONDateTime(t *testing.T) {
147	testDateTime(t, true)
148}
149
150func TestJSONTimestampLTZ(t *testing.T) {
151	testTimestampLTZ(t, true)
152}
153
154func TestJSONTimestampTZ(t *testing.T) {
155	testTimestampTZ(t, true)
156}
157
158func TestJSONNULL(t *testing.T) {
159	testNULL(t, true)
160}
161
162func TestJSONVariant(t *testing.T) {
163	testVariant(t, true)
164}
165
166func TestJSONArray(t *testing.T) {
167	testArray(t, true)
168}
169
170func TestLargeSetJSONResultWithDecoder(t *testing.T) {
171	testLargeSetResult(t, 10000, true)
172}
173
174func TestLargeSetResultWithCustomJSONDecoder(t *testing.T) {
175	CustomJSONDecoderEnabled = true
176	// less number of rows to avoid Travis timeout
177	testLargeSetResult(t, 20000, true)
178}
179
180func TestBindingJSONInterface(t *testing.T) {
181	runTests(t, dsn, func(dbt *DBTest) {
182		dbt.mustExec(forceJSON)
183		rows := dbt.mustQuery(selectVariousTypes)
184		defer rows.Close()
185		if !rows.Next() {
186			dbt.Error("failed to query")
187		}
188		var v1, v2, v3, v4, v5, v6 interface{}
189		if err := rows.Scan(&v1, &v2, &v3, &v4, &v5, &v6); err != nil {
190			dbt.Errorf("failed to scan: %#v", err)
191		}
192		if s, ok := v1.(string); !ok || s != "1.00" {
193			dbt.Fatalf("failed to fetch. ok: %v, value: %v", ok, v1)
194		}
195		if s, ok := v2.(string); !ok || s != "2" {
196			dbt.Fatalf("failed to fetch. ok: %v, value: %v", ok, v2)
197		}
198		if s, ok := v3.(string); !ok || s != "t3" {
199			dbt.Fatalf("failed to fetch. ok: %v, value: %v", ok, v3)
200		}
201		if s, ok := v4.(string); !ok || s != "4.2" {
202			dbt.Fatalf("failed to fetch. ok: %v, value: %v", ok, v4)
203		}
204	})
205}
206