Skip to content

Commit c2e21ab

Browse files
authored
Merge branch 'main' into insert-performance-improvements
2 parents 73d9f63 + 75a2e2a commit c2e21ab

31 files changed

+3128
-26
lines changed

chcol.go

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Licensed to ClickHouse, Inc. under one or more contributor
2+
// license agreements. See the NOTICE file distributed with
3+
// this work for additional information regarding copyright
4+
// ownership. ClickHouse, Inc. licenses this file to you under
5+
// the Apache License, Version 2.0 (the "License"); you may
6+
// not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package clickhouse
19+
20+
import "github.com/ClickHouse/clickhouse-go/v2/lib/chcol"
21+
22+
// Re-export chcol types/funcs to top level clickhouse package
23+
24+
type (
25+
Variant = chcol.Variant
26+
Dynamic = chcol.Dynamic
27+
)
28+
29+
// NewVariant creates a new Variant with the given value
30+
func NewVariant(v any) Variant {
31+
return chcol.NewVariant(v)
32+
}
33+
34+
// NewVariantWithType creates a new Variant with the given value and ClickHouse type
35+
func NewVariantWithType(v any, chType string) Variant {
36+
return chcol.NewVariantWithType(v, chType)
37+
}
38+
39+
// NewDynamic creates a new Dynamic with the given value
40+
func NewDynamic(v any) Dynamic {
41+
return chcol.NewDynamic(v)
42+
}
43+
44+
// NewDynamicWithType creates a new Dynamic with the given value and ClickHouse type
45+
func NewDynamicWithType(v any, chType string) Dynamic {
46+
return chcol.NewDynamicWithType(v, chType)
47+
}

clickhouse_std.go

+6
Original file line numberDiff line numberDiff line change
@@ -445,10 +445,16 @@ func (r *stdRows) ColumnTypePrecisionScale(idx int) (precision, scale int64, ok
445445
switch col := r.rows.block.Columns[idx].(type) {
446446
case *column.Decimal:
447447
return col.Precision(), col.Scale(), true
448+
case *column.DateTime64:
449+
p, ok := col.Precision()
450+
return p, 0, ok
448451
case interface{ Base() column.Interface }:
449452
switch col := col.Base().(type) {
450453
case *column.Decimal:
451454
return col.Precision(), col.Scale(), true
455+
case *column.DateTime64:
456+
p, ok := col.Precision()
457+
return p, 0, ok
452458
}
453459
}
454460
return 0, 0, false

examples/clickhouse_api/dynamic.go

+141
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
// Licensed to ClickHouse, Inc. under one or more contributor
2+
// license agreements. See the NOTICE file distributed with
3+
// this work for additional information regarding copyright
4+
// ownership. ClickHouse, Inc. licenses this file to you under
5+
// the Apache License, Version 2.0 (the "License"); you may
6+
// not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package clickhouse_api
19+
20+
import (
21+
"context"
22+
"fmt"
23+
"github.com/ClickHouse/clickhouse-go/v2"
24+
)
25+
26+
func DynamicExample() error {
27+
ctx := context.Background()
28+
29+
conn, err := GetNativeConnection(clickhouse.Settings{
30+
"allow_experimental_dynamic_type": true,
31+
}, nil, nil)
32+
if err != nil {
33+
return err
34+
}
35+
36+
if !CheckMinServerVersion(conn, 24, 8, 0) {
37+
fmt.Print("unsupported clickhouse version for Dynamic type")
38+
return nil
39+
}
40+
41+
err = conn.Exec(ctx, "DROP TABLE IF EXISTS go_dynamic_example")
42+
if err != nil {
43+
return err
44+
}
45+
46+
err = conn.Exec(ctx, `
47+
CREATE TABLE go_dynamic_example (
48+
c Dynamic
49+
) ENGINE = Memory
50+
`)
51+
if err != nil {
52+
return err
53+
}
54+
55+
batch, err := conn.PrepareBatch(ctx, "INSERT INTO go_dynamic_example (c)")
56+
if err != nil {
57+
return err
58+
}
59+
60+
if err = batch.Append(true); err != nil {
61+
return err
62+
}
63+
64+
if err = batch.Append(int64(42)); err != nil {
65+
return err
66+
}
67+
68+
if err = batch.Append("example"); err != nil {
69+
return err
70+
}
71+
72+
if err = batch.Append(clickhouse.NewDynamic("example dynamic")); err != nil {
73+
return err
74+
}
75+
76+
if err = batch.Append(clickhouse.NewDynamicWithType("example dynamic with specific type", "String")); err != nil {
77+
return err
78+
}
79+
80+
if err = batch.Append(nil); err != nil {
81+
return err
82+
}
83+
84+
if err = batch.Send(); err != nil {
85+
return err
86+
}
87+
88+
// Switch on Go Type
89+
90+
rows, err := conn.Query(ctx, "SELECT c FROM go_dynamic_example")
91+
if err != nil {
92+
return err
93+
}
94+
95+
for i := 0; rows.Next(); i++ {
96+
var row clickhouse.Dynamic
97+
err := rows.Scan(&row)
98+
if err != nil {
99+
return fmt.Errorf("failed to scan row index %d: %w", i, err)
100+
}
101+
102+
switch row.Any().(type) {
103+
case bool:
104+
fmt.Printf("row at index %d is Bool: %v\n", i, row.Any())
105+
case int64:
106+
fmt.Printf("row at index %d is Int64: %v\n", i, row.Any())
107+
case string:
108+
fmt.Printf("row at index %d is String: %v\n", i, row.Any())
109+
case nil:
110+
fmt.Printf("row at index %d is NULL\n", i)
111+
}
112+
}
113+
114+
// Switch on ClickHouse Type
115+
116+
rows, err = conn.Query(ctx, "SELECT c FROM go_dynamic_example")
117+
if err != nil {
118+
return err
119+
}
120+
121+
for i := 0; rows.Next(); i++ {
122+
var row clickhouse.Dynamic
123+
err := rows.Scan(&row)
124+
if err != nil {
125+
return fmt.Errorf("failed to scan row index %d: %w", i, err)
126+
}
127+
128+
switch row.Type() {
129+
case "Bool":
130+
fmt.Printf("row at index %d is bool: %v\n", i, row.Any())
131+
case "Int64":
132+
fmt.Printf("row at index %d is int64: %v\n", i, row.Any())
133+
case "String":
134+
fmt.Printf("row at index %d is string: %v\n", i, row.Any())
135+
case "":
136+
fmt.Printf("row at index %d is nil\n", i)
137+
}
138+
}
139+
140+
return nil
141+
}

examples/clickhouse_api/main_test.go

+8
Original file line numberDiff line numberDiff line change
@@ -209,3 +209,11 @@ func TestSSL(t *testing.T) {
209209
func TestSSLNoVerify(t *testing.T) {
210210
require.NoError(t, SSLNoVerifyVersion())
211211
}
212+
213+
func TestVariantExample(t *testing.T) {
214+
require.NoError(t, VariantExample())
215+
}
216+
217+
func TestDynamicExample(t *testing.T) {
218+
require.NoError(t, DynamicExample())
219+
}

examples/clickhouse_api/utils.go

+4
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,7 @@ func GetNativeTestEnvironment() (clickhouse_tests.ClickHouseTestEnvironment, err
3737
func GetNativeConnectionWithOptions(settings clickhouse.Settings, tlsConfig *tls.Config, compression *clickhouse.Compression) (driver.Conn, error) {
3838
return clickhouse_tests.GetConnection(TestSet, settings, tlsConfig, compression)
3939
}
40+
41+
func CheckMinServerVersion(conn driver.Conn, major, minor, patch uint64) bool {
42+
return clickhouse_tests.CheckMinServerServerVersion(conn, major, minor, patch)
43+
}

examples/clickhouse_api/variant.go

+143
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
// Licensed to ClickHouse, Inc. under one or more contributor
2+
// license agreements. See the NOTICE file distributed with
3+
// this work for additional information regarding copyright
4+
// ownership. ClickHouse, Inc. licenses this file to you under
5+
// the Apache License, Version 2.0 (the "License"); you may
6+
// not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package clickhouse_api
19+
20+
import (
21+
"context"
22+
"fmt"
23+
24+
"github.com/ClickHouse/clickhouse-go/v2"
25+
)
26+
27+
func VariantExample() error {
28+
ctx := context.Background()
29+
30+
conn, err := GetNativeConnection(clickhouse.Settings{
31+
"allow_experimental_variant_type": true,
32+
"allow_suspicious_variant_types": true,
33+
}, nil, nil)
34+
if err != nil {
35+
return err
36+
}
37+
38+
if !CheckMinServerVersion(conn, 24, 4, 0) {
39+
fmt.Print("unsupported clickhouse version for Variant type")
40+
return nil
41+
}
42+
43+
err = conn.Exec(ctx, "DROP TABLE IF EXISTS go_variant_example")
44+
if err != nil {
45+
return err
46+
}
47+
48+
err = conn.Exec(ctx, `
49+
CREATE TABLE go_variant_example (
50+
c Variant(Bool, Int64, String)
51+
) ENGINE = Memory
52+
`)
53+
if err != nil {
54+
return err
55+
}
56+
57+
batch, err := conn.PrepareBatch(ctx, "INSERT INTO go_variant_example (c)")
58+
if err != nil {
59+
return err
60+
}
61+
62+
if err = batch.Append(true); err != nil {
63+
return err
64+
}
65+
66+
if err = batch.Append(int64(42)); err != nil {
67+
return err
68+
}
69+
70+
if err = batch.Append("example"); err != nil {
71+
return err
72+
}
73+
74+
if err = batch.Append(clickhouse.NewVariant("example variant")); err != nil {
75+
return err
76+
}
77+
78+
if err = batch.Append(clickhouse.NewVariantWithType("example variant with specific type", "String")); err != nil {
79+
return err
80+
}
81+
82+
if err = batch.Append(nil); err != nil {
83+
return err
84+
}
85+
86+
if err = batch.Send(); err != nil {
87+
return err
88+
}
89+
90+
// Switch on Go Type
91+
92+
rows, err := conn.Query(ctx, "SELECT c FROM go_variant_example")
93+
if err != nil {
94+
return err
95+
}
96+
97+
for i := 0; rows.Next(); i++ {
98+
var row clickhouse.Variant
99+
err := rows.Scan(&row)
100+
if err != nil {
101+
return fmt.Errorf("failed to scan row index %d: %w", i, err)
102+
}
103+
104+
switch row.Any().(type) {
105+
case bool:
106+
fmt.Printf("row at index %d is Bool: %v\n", i, row.Any())
107+
case int64:
108+
fmt.Printf("row at index %d is Int64: %v\n", i, row.Any())
109+
case string:
110+
fmt.Printf("row at index %d is String: %v\n", i, row.Any())
111+
case nil:
112+
fmt.Printf("row at index %d is NULL\n", i)
113+
}
114+
}
115+
116+
// Switch on ClickHouse Type
117+
118+
rows, err = conn.Query(ctx, "SELECT c FROM go_variant_example")
119+
if err != nil {
120+
return err
121+
}
122+
123+
for i := 0; rows.Next(); i++ {
124+
var row clickhouse.Variant
125+
err := rows.Scan(&row)
126+
if err != nil {
127+
return fmt.Errorf("failed to scan row index %d: %w", i, err)
128+
}
129+
130+
switch row.Type() {
131+
case "Bool":
132+
fmt.Printf("row at index %d is bool: %v\n", i, row.Any())
133+
case "Int64":
134+
fmt.Printf("row at index %d is int64: %v\n", i, row.Any())
135+
case "String":
136+
fmt.Printf("row at index %d is string: %v\n", i, row.Any())
137+
case "":
138+
fmt.Printf("row at index %d is nil\n", i)
139+
}
140+
}
141+
142+
return nil
143+
}

0 commit comments

Comments
 (0)