Skip to content

Commit 7112491

Browse files
俞子丰俞子丰
authored andcommitted
port variant type
1 parent 9be7a2b commit 7112491

38 files changed

+3489
-522
lines changed

chcol.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
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 proton
19+
20+
import "github.com/timeplus-io/proton-go-driver/v2/lib/chcol"
21+
22+
// Re-export chcol types/funcs to top level proton package
23+
24+
type (
25+
// Variant represents a ClickHouse Variant type that can hold multiple possible types
26+
Variant = chcol.Variant
27+
// Dynamic is an alias for the Variant type
28+
Dynamic = chcol.Dynamic
29+
// JSON represents a ClickHouse JSON type that can hold multiple possible types
30+
JSON = chcol.JSON
31+
32+
// JSONSerializer interface allows a struct to be manually converted to an optimized JSON structure instead of relying
33+
// on recursive reflection.
34+
// Note that the struct must be a pointer in order for the interface to be matched, reflection will be used otherwise.
35+
JSONSerializer = chcol.JSONSerializer
36+
// JSONDeserializer interface allows a struct to load its data from an optimized JSON structure instead of relying
37+
// on recursive reflection to set its fields.
38+
JSONDeserializer = chcol.JSONDeserializer
39+
)
40+
41+
// NewVariant creates a new Variant with the given value
42+
func NewVariant(v any) Variant {
43+
return chcol.NewVariant(v)
44+
}
45+
46+
// NewVariantWithType creates a new Variant with the given value and ClickHouse type
47+
func NewVariantWithType(v any, chType string) Variant {
48+
return chcol.NewVariantWithType(v, chType)
49+
}
50+
51+
// NewDynamic creates a new Dynamic with the given value
52+
func NewDynamic(v any) Dynamic {
53+
return chcol.NewDynamic(v)
54+
}
55+
56+
// NewDynamicWithType creates a new Dynamic with the given value and ClickHouse type
57+
func NewDynamicWithType(v any, chType string) Dynamic {
58+
return chcol.NewDynamicWithType(v, chType)
59+
}
60+
61+
// NewJSON creates a new empty JSON value
62+
func NewJSON() *JSON {
63+
return chcol.NewJSON()
64+
}
65+
66+
// ExtractJSONPathAs is a convenience function for asserting a path to a specific type.
67+
// The underlying value is also extracted from its Dynamic wrapper if present.
68+
// func ExtractJSONPathAs[T any](o *JSON, path string) (valueAs T, ok bool) {
69+
// return chcol.ExtractJSONPathAs[T](o, path)
70+
// }

clickhouse_rows.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,6 @@ func (r *rows) Close() error {
117117
}
118118
}
119119
}
120-
return r.err
121120
}
122121

123122
func (r *rows) Err() error {

examples/native/variant/variant.go

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
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 main
19+
20+
import (
21+
"context"
22+
"fmt"
23+
"log"
24+
"time"
25+
26+
"github.com/timeplus-io/proton-go-driver/v2"
27+
proton_tests "github.com/timeplus-io/proton-go-driver/v2/tests"
28+
)
29+
30+
func VariantExample() error {
31+
ctx := context.Background()
32+
33+
conn, err := proton.Open(&proton.Options{
34+
Addr: []string{"127.0.0.1:8463"},
35+
Auth: proton.Auth{
36+
Database: "default",
37+
Username: "default",
38+
Password: "",
39+
},
40+
//Debug: true,
41+
Settings: proton.Settings{
42+
"allow_experimental_variant_type": true,
43+
"allow_suspicious_variant_types": true,
44+
},
45+
DialTimeout: time.Second,
46+
MaxOpenConns: 10,
47+
MaxIdleConns: 5,
48+
ConnMaxLifetime: time.Hour,
49+
Compression: &proton.Compression{
50+
Method: proton.CompressionLZ4,
51+
},
52+
})
53+
54+
if err != nil {
55+
return err
56+
}
57+
58+
if err := proton_tests.CheckMinServerVersion(conn, 2, 9); err != nil {
59+
fmt.Print("unsupported timeplus version for Variant type")
60+
return err
61+
}
62+
63+
err = conn.Exec(ctx, "DROP STREAM IF EXISTS go_variant_example")
64+
if err != nil {
65+
return err
66+
}
67+
68+
err = conn.Exec(ctx, `
69+
CREATE STREAM go_variant_example (
70+
c variant(bool, int64, string)
71+
) ENGINE = Memory
72+
`)
73+
if err != nil {
74+
return err
75+
}
76+
77+
batch, err := conn.PrepareBatch(ctx, "INSERT INTO go_variant_example (c)")
78+
if err != nil {
79+
return err
80+
}
81+
82+
if err = batch.Append(true); err != nil {
83+
return err
84+
}
85+
86+
if err = batch.Append(int64(42)); err != nil {
87+
return err
88+
}
89+
90+
if err = batch.Append("example"); err != nil {
91+
return err
92+
}
93+
94+
if err = batch.Append(proton.NewVariant("example variant")); err != nil {
95+
return err
96+
}
97+
98+
if err = batch.Append(proton.NewVariantWithType("example variant with specific type", "string")); err != nil {
99+
return err
100+
}
101+
102+
if err = batch.Append(nil); err != nil {
103+
return err
104+
}
105+
106+
if err = batch.Send(); err != nil {
107+
return err
108+
}
109+
110+
// Switch on Go Type
111+
112+
rows, err := conn.Query(ctx, "SELECT c FROM go_variant_example")
113+
if err != nil {
114+
return err
115+
}
116+
117+
for i := 0; rows.Next(); i++ {
118+
var row proton.Variant
119+
err := rows.Scan(&row)
120+
if err != nil {
121+
return fmt.Errorf("failed to scan row index %d: %w", i, err)
122+
}
123+
124+
switch row.Any().(type) {
125+
case bool:
126+
fmt.Printf("row at index %d is bool: %v\n", i, row.Any())
127+
case int64:
128+
fmt.Printf("row at index %d is int64: %v\n", i, row.Any())
129+
case string:
130+
fmt.Printf("row at index %d is string: %v\n", i, row.Any())
131+
case nil:
132+
fmt.Printf("row at index %d is NULL\n", i)
133+
}
134+
}
135+
136+
// Switch on Timeplus Type
137+
138+
rows, err = conn.Query(ctx, "SELECT c FROM go_variant_example")
139+
if err != nil {
140+
return err
141+
}
142+
143+
for i := 0; rows.Next(); i++ {
144+
var row proton.Variant
145+
err := rows.Scan(&row)
146+
if err != nil {
147+
return fmt.Errorf("failed to scan row index %d: %w", i, err)
148+
}
149+
150+
switch row.Type() {
151+
case "bool":
152+
fmt.Printf("row at index %d is bool: %v\n", i, row.Any())
153+
case "int64":
154+
fmt.Printf("row at index %d is int64: %v\n", i, row.Any())
155+
case "string":
156+
fmt.Printf("row at index %d is string: %v\n", i, row.Any())
157+
case "":
158+
fmt.Printf("row at index %d is nil\n", i)
159+
}
160+
}
161+
162+
return nil
163+
}
164+
165+
func main() {
166+
if err := VariantExample(); err != nil {
167+
log.Fatal(err)
168+
}
169+
}

examples/std/batch/main.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,6 @@ func example() error {
3333
return err
3434
}
3535
conn.SetMaxIdleConns(5)
36-
if err != nil {
37-
return err
38-
}
3936
if _, err := conn.Exec(`DROP STREAM IF EXISTS example`); err != nil {
4037
return err
4138
}

0 commit comments

Comments
 (0)