-
Notifications
You must be signed in to change notification settings - Fork 5k
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
Time datatype support #6109
Time datatype support #6109
Conversation
83c7bc7
to
e30bdc1
Compare
cba5a87
to
2948225
Compare
src/metabase/driver/bigquery.clj
Outdated
@@ -283,7 +302,7 @@ | |||
(let [sql (str "-- " (qputil/query->remark outer-query) "\n" (if (seq params) | |||
(unprepare/unprepare (cons sql params)) | |||
sql)) | |||
results (process-native* database sql) | |||
results (process-native* database sql) |
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.
accidental space?
src/metabase/util.clj
Outdated
@@ -113,6 +113,22 @@ | |||
java.sql.Timestamp (->iso-8601-datetime [this timezone-id] (time/unparse (ISO8601Formatter timezone-id) (coerce/from-sql-time this))) | |||
org.joda.time.DateTime (->iso-8601-datetime [this timezone-id] (time/unparse (ISO8601Formatter timezone-id) this))) | |||
|
|||
(def ^:private time-formatter |
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 not super important but for functions defined by def
it's nice to add :arglists
metadata so when you're playing around in the CIDER repl it will show you what args it expects in the minibuffer. e.g.
(def ^:private ^{:arglists '([timezone-id])} time-formatted
...)
Normally I wouldn't even bother to suggest this but since it's in metabase.util
it might be worth it to go back and add it
{:field-name "number-of-cans", :base-type {:native "tinyint(1)"}}] | ||
[["Six Pack" 6] | ||
["Toucan" 2] | ||
["Empty Vending Machine" 0]]]]) |
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 fake dataset 😂
We need to add this to the Sample Data 😂
.getTime))) | ||
|
||
(defn- time-only | ||
"This function will return a java.sql.Time object. To create a Time |
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 isn't important but something I learned about recently that you might find useful:
I've just started using column-enforce-mode
in Emacs. It's a minor mode that font locks text past a certain column (defined by column-enforce-column
) as red. Maybe worth looking into.
It looks like these lines are all about ~70 characters wide, so I'm guessing you're trying to keep them less than the classic 80 chars, and since they're a little under 80 I'm guessing you're eyeballing them. So maybe it's a tool that you might find useful to make your life a little easier
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.
Do you have a preference on line length? I'm betting what I did here is write a big docstring, then M-q paredit-reindent-defun
. I'm usually a fan of 120 chars, but I haven't changed the paredit defaults.
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.
Yeah, 120 is a good number. It seems like GitHub's limit is 120 characters before they add horizontal scrollbars to code, but with the +
at the beginning of a PR I've figured out that you can only actually do 119 characters before GH cuts it off. So I have my column limit set to 118 just to be safe.
I didn't know about paredit-reindent-defun
, I'll have to check that out. I've just been setting up a keyboard macro to do re-indentation manually like a chump 😓
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 think I've found a way to automate this. if you set the vars below:
;; Anywhere
(setq clojure-docstring-fill-column 118)
;; In the clojure-mode-hook
(set-fill-column 118)
The first will set clojure docstrings correctly at 118 and the second one will set code comments to wrap at 118, then you can just use the built in emacs fill-paragraph stuff that M-q uses.
@sbelak You might be interested in this too.
test/metabase/test/data/presto.clj
Outdated
@@ -10,7 +13,7 @@ | |||
(:import java.util.Date | |||
metabase.driver.presto.PrestoDriver)) | |||
|
|||
(resolve-private-vars metabase.driver.presto execute-presto-query! presto-type->base-type quote-name quote+combine-names) | |||
(resolve-private-vars metabase.driver.presto execute-presto-query! presto-type->base-type quote-name quote+combine-names time->str) |
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.
Going forward it's preferable IMO to stop using resolve-private-vars
and just do something like #'presto/time->str
when you want to use something private in a test. The only reason I wrote resolve-private-vars
in the first place was because I didn't realize you could do that
Also, don't forget to require
metabase.driver.presto
, otherwise import
will potentially barf because Clojure doesn't know it needs to load a certain namespace for that class to get defined. It's working fine here because somebody else is implicitly loading it but relying on such things is sketchy
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.
Those sorts of errors usually end up popping up in confusing ways, like if you try to test a single namespace that ends up skipping loading all the other namespaces that normally implicitly load whatever it is you're expecting to be loaded
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.
Oops. I just noticed you didn't add this code and it was already like that... 😬
Mind fixing it while you're here?
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.
Totally agree on the metabase.driver.presto
thing and the resolve-private-vars I have always found confusing as the #' syntax is so easy. I'm 👍, I'll get it fixed up
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.
Looks really good!
2948225
to
5b0388b
Compare
fc88f48
to
aae113d
Compare
@tlrobinson Rebased on master but still fixing up test failures. Pushed up a fix for presto, bigquery is breaking now. I'll work on getting this green first thing in the morning |
It also occurs to me that a common use-case for filtering by a time is on an extract from a date/time field (e.x. all records created_at 9am to 5pm, where created_at is a date/time). However that generalizes to other extracts like day-of-week, which we don't support in the UI currently anyway, so it's probably best handled together as a separate feature. |
For the UI we should probably let you choose AM/PM or 24-hour clock somewhere since the majority of the world uses the 24-hour clock e.g. 17:00 instead of 5:00 PM |
@camsaul We wouldn't put an option to choose a 24-hour clock choice in the filter UI itself (Yet Another Knob™), but I definitely think that's something we could and should put as a global setting in the General part of the admin panel. There's a whole host of international formatting options that should really be included there, like default currency symbol, numeric separator style, first day of the week, etc. |
@tlrobinson Here's some UI guidance, broken up into the quickest and simplest thing we could do, and then an incremental improvement that we could tackle as a separate project to improve the time selection component globally. Let me know if this is what you were looking for. Simplest thingFor Between, we'd just include more space between the two time selectors. This is the same exact width as the Between state for Date filters. (Incidentally, a nicety would be to put the For situations where only a single time needs to be chosen, we could put everything on a single line, like so: Where I'd like to go eventuallyI'm including this here for context (and on the off chance that it's trivial work). I think we could improve the time selection component and make it a single input box that would let you type hours, minutes, and am/pm — even allow 24-hour syntax. I think this is an improvement for a few reasons: saves space and simplifies the UI a bunch; still allows for custom times like 5:17pm; requires fewer clicks and less interaction. So I could type Examples: Between Before |
@metabase/core-developers I believe this is ready for review |
👍 the backend was reviewed by @camsaul already, so just needs a front end review |
Could an example time field be added to the sample dataset? That would both make reviewing PRs like this easier and more importantly make it possible to write integration tests for this feature. After the sample dataset is updated (ping @senior), it's easy for Tom or me to add integration tests which verify that you are able to create a time filter in QB and edit its values afterwards. Frontend code itself looks good and it seems that visualizations display time values correctly. Issues I found:
|
@attekei For testing I took the test-data set that the backend uses and split one of the datetime columns to separate date and time fields https://github.com/metabase/metabase/pull/6109/files#diff-0dfb1f2e187020bac353f144592a0137R58. Is something like that usable by you? If not I can look into adding something to the sample datatset, but my guess is it'd need to be a new/separate table with new generated data. |
@senior Yeah I also created a new column to one of my local PostgreSQL test databases. I'm referring to a conversation our team had in autumn related to #6266, where we wanted that all x-ray insights should be testable with our sample dataset data. That also made writing frontend tests easy.
Yeah if a time column doesn't make sense in the context of any current tables (Orders / People / Products / Reviews), then maybe creating a new table is the only option... but it would still be useful both for the discoverability of the feature and easiness of frontend testing. I don't want to make this a hard blocker but it's still something that would be really nice to have. |
What @attekei said. This is going to be a PITA for me to test the UI. |
can we add a column to the sample database? Users could be given a "wakeupTime" time column |
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.
Breakout granularities should change for time fields
oh, and even the ones that are relevant (eg Minute of Hour) don't actually work. |
@salsakran @tlrobinson it shouldn't be showing any bucketing. Databases don't support bucketing of time fields like they do date fields, so any bucketing we'd have to implement ourselves. |
This reminds me, our Currently:
But we also use I feel like
As it is, to determine if something has (at least) a time component you have to check that it's a |
In relation to this PR, I'm not sure if it's better to change |
@senior Actually I forgot, the breakout options are sent by the backend now. Do you mind handling it there? |
@tlrobinson Just pushed up a change so that dimension options aren't included for time fields |
Are we good to go on this? If so I'll squash the commits and force push for merge |
49c139b
to
283bed9
Compare
This commit adds code needed to query time fields and to filter by time fields. Support is included for all database backends that support time fields. Previously depending on the backend, the result of querying a time field was either an exception or an incorrect "zeroed out" date of 1970-01-01 followed by the time. Fixes #5563, fixes #5829
This primarily focuses on a time picker rather than the date picker when users are attempting to filter based on a time column. There are also some minor changes to how time field results are displayed/formatted.
283bed9
to
2a8dc4f
Compare
This PR adds support for Time datatypes on those databases that support them.
java.sql.Time
objects in Java are a subclass ofjava.util.Date
, but have their year/month/day set to epoch. On some databases, lack of support for Time datatypes will maybe them look like all of the times took place on 1970-01-01. On other databases (like BigQuery) this will cause errors.This PR adds support for returning Time fields in query results and querying/filtering using time fields.
TODO: