-
Notifications
You must be signed in to change notification settings - Fork 594
feat: add support for time/time64 #1596
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: add support for time/time64 #1596
Conversation
303b18b
to
58d8921
Compare
Hey @SpencerTorres when you get some time, can you please take a look at this one? (also tagging you as some other PRs which can get some help from your reviews) Thanks! |
ca6efd1
to
73d50d0
Compare
ClickHouse/ch-go#1074 is now, merged, this is now ready for review/merge. |
Released ch-go v0.67.0 https://github.com/ClickHouse/ch-go/releases/tag/v0.67.0 I'll review once you get the mod file updated. Thanks! |
25c62ce
to
15a81a7
Compare
Done, bumped ch-go to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey! Thanks for submitting this.
The implementation itself looks good, but there's definitely some changes needed.
Apologies for the testing issues as well, I'm not sure if you have docker available but we have a really easy way of running integration tests to where you don't need to run your own instance. Let me know if you have any questions about this or any other notes I've left.
Overall I'd recommend you take a look at the other column types and integration tests.
Also it would be good to get some tests for the standard library database/sql
interface. You can find those in tests/std
. These are important for ensuring our driver works with other SQL wrappers.
return col.name | ||
} | ||
|
||
func (col *Time) parse(t Type, tz *time.Location) (_ Interface, err error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update function signature to the latest. I recently changed this on main
, the parse
function is now expected to accept a sc *ServerContext
. You could then use sc.Timezone
.
You could keep the param as timezone though, see my other comment about column.tpl
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same for Time64
return time.Time{}, fmt.Errorf("cannot parse time value: %s", value) | ||
} | ||
|
||
func (col *Time) WriteStatePrefix(buffer *proto.Buffer) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this is an optional interface, along with ReadStatePrefix
. You should be able to remove these.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same for Time64
Op: "Decode", | ||
Err: errors.New(fmt.Sprintf("custom serialization for column %s. not supported by clickhouse-go driver", columnName)), | ||
// Allow Time and Time64 columns with custom serialization | ||
if columnType != "Time" && columnType != "Time64" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this? How is Time and Time64 encoded where this is something that needs to be changed? I never saw what hasCustom
is in the protocol, is this really the first column that has the bool set to true
?
If we need to support some columns with custom encoding let's make an interface similar to CustomSerialization
with WriteStatePrefix
and ReadStatePrefix
. Perhaps an interface that has a single AllowCustom() bool
on it. If it returns false then we throw this error.
Also note that columnType
could be complex such as Time64(precision)
, so Time
and Time64
would never match if they had any parameters.
tests/time_test.go
Outdated
) | ||
|
||
func TestTimeBasic(t *testing.T) { | ||
// Skip if no ClickHouse server is available |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ClickHouse server is always available in this testing folder, these are integration tests. There are other places we could put this logic, let's not duplicate these skips everywhere.
If you're testing logic related to the column type itself, you can put it in the column
package next to the source file. time_test.go
and such.
tests/time_test.go
Outdated
} | ||
|
||
ctx := context.Background() | ||
conn, err := clickhouse.Open(&clickhouse.Options{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should reference variant_test
or dynamic_test
or json_test
, these are also experimental/new similar to the time type.
This connection will not run on CI due to the server being unavailable. Our local machines and CI machines usually have docker so we can run multiple versions of ClickHouse through the same tests.
Some considerations/notes:
- Use a setup function. This will be useful for skipping versions that don't have this column type.
- The setup function can also be used to include the
enable_time_timet64_type
setting - Use the
GetNativeConnection
function as seen in the other tests - We must test TCP and HTTP connections, use
TestProtocols
wapper in each test as seen in the other tests
tests/time_test.go
Outdated
require.NoError(t, conn.Exec(ctx, "DROP TABLE IF EXISTS test_time_registration")) | ||
|
||
const ddl = ` | ||
CREATE TABLE test_time_registration ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is good that the table names are different. This prevents session/table locking issues for HTTP tests. It's best that each test has its own table name
|
||
const defaultTimeFormat = "15:04:05" | ||
|
||
type Time struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You will need to add Time
and Time64
to lib/column/codegen/column.tpl
and run the codegen to re-generate column_gen.go
. This will allow our column parser to automatically initialize the Time
and Time64
types.
This is critical for actually adding the type, otherwise the column won't be recognized in the driver. It also helps other wrapper types like Array(Time)
init the type.
99e5511
to
aeadbc7
Compare
fixes: #1579
related to ClickHouse/ClickHouse#81217
depends on ClickHouse/ch-go#1074
Summary
Checklist
Delete items not relevant to your PR: