-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Add a test for varchar cast to date predicate #13605
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -503,6 +503,49 @@ public void testSortItemsReflectedInExplain() | |
| expectedPattern); | ||
| } | ||
|
|
||
| // CAST(a_varchar AS date) = DATE '...' is an interesting condition which may want to be optimized by the engine or a connector | ||
| @Test | ||
| public void testVarcharCastToDateInPredicate() | ||
| { | ||
| skipTestUnless(hasBehavior(SUPPORTS_CREATE_TABLE_WITH_DATA)); | ||
|
|
||
| try (TestTable table = new TestTable( | ||
| getQueryRunner()::execute, | ||
| "varchar_as_date_pred", | ||
| "(a varchar)", | ||
| List.of( | ||
| "'999-09-09'", | ||
| "'1005-09-09'", | ||
| "'2005-06-06'", "'2005-06-6'", "'2005-6-06'", "'2005-6-6'", "' 2005-06-06'", "'2005-06-06 '", "' +2005-06-06'", "'02005-06-06'", | ||
| "'2005-09-06'", "'2005-09-6'", "'2005-9-06'", "'2005-9-6'", "' 2005-09-06'", "'2005-09-06 '", "' +2005-09-06'", "'02005-09-06'", | ||
| "'2005-09-09'", "'2005-09-9'", "'2005-9-09'", "'2005-9-9'", "' 2005-09-09'", "'2005-09-09 '", "' +2005-09-09'", "'02005-09-09'", | ||
| "'2005-09-10'", "'2005-9-10'", "' 2005-09-10'", "'2005-09-10 '", "' +2005-09-10'", "'02005-09-10'", | ||
| "'9999-09-09'", | ||
| "'99999-09-09'"))) { | ||
| for (String date : List.of("2005-09-06", "2005-09-09", "2005-09-10")) { | ||
| for (String operator : List.of("=", "<=", "<", ">", ">=", "!=", "IS DISTINCT FROM", "IS NOT DISTINCT FROM")) { | ||
| assertThat(query("SELECT a FROM %s WHERE CAST(a AS date) %s DATE '%s'".formatted(table.getName(), operator, date))) | ||
| .hasCorrectResultsRegardlessOfPushdown(); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| try (TestTable table = new TestTable( | ||
| getQueryRunner()::execute, | ||
| "varchar_as_date_pred", | ||
| "(a varchar)", | ||
| List.of("'2005-06-bad-date'", "'2005-09-10'"))) { | ||
| assertThatThrownBy(() -> query("SELECT a FROM %s WHERE CAST(a AS date) < DATE '2005-09-10'".formatted(table.getName()))) | ||
| .hasMessage("Value cannot be cast to date: 2005-06-bad-date"); | ||
| // This failure isn't guaranteed. TODO make test more flexible when need arises. | ||
| assertThatThrownBy(() -> query("SELECT a FROM %s WHERE CAST(a AS date) = DATE '2005-09-10'".formatted(table.getName()))) | ||
| .hasMessage("Value cannot be cast to date: 2005-06-bad-date"); | ||
|
Comment on lines
541
to
542
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we want to guarantee this, then I don't think any improvement like #12925 is possible.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Why? Because we might miss the error in data?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @sopel39 yes, but idk whether it matters. This is a question.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @martint do you have an opinion?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indeed, that's hard/impossible to guarantee. In Trino, a query that should succeed according to standard SQL semantics will succeed and produce correct results. A query that might fail due to bad data or bad assumptions about data may or may not fail depending on optimizations performed by the engine and connectors. A trivial example is the following: Let's say there's a row with values
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @martint that's a good example and pretty compelling. My question is about case with one column. Does it change anything for you, @martint ?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Kept the test case, but added a comment: |
||
| // This failure isn't guaranteed. TODO make test more flexible when need arises. | ||
| assertThatThrownBy(() -> query("SELECT a FROM %s WHERE CAST(a AS date) > DATE '2022-08-10'".formatted(table.getName()))) | ||
| .hasMessage("Value cannot be cast to date: 2005-06-bad-date"); | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
| public void testConcurrentScans() | ||
| { | ||
|
|
||
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.
Since
hasCorrectResultsRegardlessOfPushdown()returns a QueryAssert, shouldn't this be:?
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.
QueryAssertneeds to know whetherhasCorrectResultsRegardlessOfPushdownreturnsthisfor chaining (convenience) or a differentQueryAssertstate. Without knowing it, it's impossible to judge whether returningthisis "more correct" than returninghasCorrectResultsRegardlessOfPushdown()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.
Doesn't it know? It's exposed as a public method to be used by tests, so the contract should be clear.
Regardless, I find it a bit confusing. When I read the code it's not immediately clear whether there's a bug lurking (is the result of
hasCorrectResultsRegardlessOfPushdown()eager or lazy, so is it possible it's a no-op?)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.
It would be more confusing to conditionally
return hasCorrectResultsRegardlessOfPushdown()elsereturn this.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.
How so? If it doesn't go into that block, there's nothing else to return, and no potential additional state induced by that method, so
thisis the only natural thing to return.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.
yes!
and the code needs to know (and does know) that
hasCorrectResultsRegardlessOfPushdownreturnsthis, so leverages this fact.