-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Implement more connector expression pushdowns in SQL Server #14570
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 |
|---|---|---|
|
|
@@ -90,6 +90,7 @@ | |
| import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_JOIN_PUSHDOWN_WITH_VARCHAR_EQUALITY; | ||
| import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_JOIN_PUSHDOWN_WITH_VARCHAR_INEQUALITY; | ||
| import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_LIMIT_PUSHDOWN; | ||
| import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_PREDICATE_ARITHMETIC_EXPRESSION_PUSHDOWN; | ||
| import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_PREDICATE_EXPRESSION_PUSHDOWN_WITH_LIKE; | ||
| import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_PREDICATE_PUSHDOWN; | ||
| import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_PREDICATE_PUSHDOWN_WITH_VARCHAR_EQUALITY; | ||
|
|
@@ -1007,6 +1008,34 @@ public void testNullSensitiveTopNPushdown() | |
| } | ||
| } | ||
|
|
||
| @Test | ||
| public void testArithmeticPredicatePushdown() | ||
| { | ||
| if (!hasBehavior(SUPPORTS_PREDICATE_ARITHMETIC_EXPRESSION_PUSHDOWN)) { | ||
hashhar marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| assertThat(query("SELECT shippriority FROM orders WHERE shippriority % 4 = 0")).isNotFullyPushedDown(FilterNode.class); | ||
| return; | ||
| } | ||
| assertThat(query("SELECT shippriority FROM orders WHERE shippriority % 4 = 0")).isFullyPushedDown(); | ||
hashhar marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| assertThat(query("SELECT nationkey, name, regionkey FROM nation WHERE nationkey > 0 AND (nationkey - regionkey) % nationkey = 2")) | ||
| .isFullyPushedDown() | ||
| .matches("VALUES (BIGINT '3', CAST('CANADA' AS varchar(25)), BIGINT '1')"); | ||
|
|
||
| // some databases calculate remainder instead of modulus when one of the values is negative | ||
| assertThat(query("SELECT nationkey, name, regionkey FROM nation WHERE nationkey > 0 AND (nationkey - regionkey) % -nationkey = 2")) | ||
| .isFullyPushedDown() | ||
| .matches("VALUES (BIGINT '3', CAST('CANADA' AS varchar(25)), BIGINT '1')"); | ||
|
|
||
| assertThatThrownBy(() -> query("SELECT nationkey, name, regionkey FROM nation WHERE nationkey > 0 AND (nationkey - regionkey) % 0 = 2")) | ||
| .hasMessageContaining("by zero"); | ||
|
|
||
| // Expression that evaluates to 0 for some rows on RHS of modulus | ||
| assertThatThrownBy(() -> query("SELECT nationkey, name, regionkey FROM nation WHERE nationkey > 0 AND (nationkey - regionkey) % (regionkey - 1) = 2")) | ||
| .hasMessageContaining("by zero"); | ||
|
||
|
|
||
| // TODO add coverage for other arithmetic pushdowns https://github.com/trinodb/trino/issues/14808 | ||
| } | ||
|
|
||
| @Test | ||
| public void testCaseSensitiveTopNPushdown() | ||
| { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| /* | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package io.trino.plugin.sqlserver; | ||
|
|
||
| import com.google.common.base.CharMatcher; | ||
| import io.airlift.slice.Slice; | ||
| import io.trino.matching.Captures; | ||
| import io.trino.matching.Pattern; | ||
| import io.trino.plugin.base.expression.ConnectorExpressionRule; | ||
| import io.trino.spi.expression.Constant; | ||
| import io.trino.spi.type.VarcharType; | ||
|
|
||
| import java.util.Optional; | ||
|
|
||
| import static io.trino.plugin.base.expression.ConnectorExpressionPatterns.constant; | ||
| import static io.trino.plugin.base.expression.ConnectorExpressionPatterns.type; | ||
|
|
||
| public class RewriteUnicodeVarcharConstant | ||
| implements ConnectorExpressionRule<Constant, String> | ||
| { | ||
| private static final Pattern<Constant> PATTERN = constant().with(type().matching(VarcharType.class::isInstance)); | ||
| private static final CharMatcher UNICODE_CHARACTER_MATCHER = CharMatcher.ascii().negate().precomputed(); | ||
hashhar marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| @Override | ||
| public Pattern<Constant> getPattern() | ||
| { | ||
| return PATTERN; | ||
| } | ||
|
|
||
| @Override | ||
| public Optional<String> rewrite(Constant constant, Captures captures, RewriteContext<String> context) | ||
| { | ||
| if (constant.getValue() == null) { | ||
| return Optional.empty(); | ||
| } | ||
| Slice slice = (Slice) constant.getValue(); | ||
| if (slice == null) { | ||
| return Optional.empty(); | ||
| } | ||
|
||
|
|
||
| String sliceUtf8String = slice.toStringUtf8(); | ||
| boolean isUnicodeString = UNICODE_CHARACTER_MATCHER.matchesAnyOf(sliceUtf8String); | ||
|
|
||
| if (isUnicodeString) { | ||
| return Optional.of("N'" + sliceUtf8String.replace("'", "''") + "'"); | ||
| } | ||
|
|
||
| return Optional.of("'" + sliceUtf8String.replace("'", "''") + "'"); | ||
hashhar marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
Comment on lines
+55
to
+59
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. what happens if we unconditionally use |
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -47,7 +47,6 @@ | |
| import static java.util.stream.Collectors.joining; | ||
| import static java.util.stream.IntStream.range; | ||
| import static org.assertj.core.api.Assertions.assertThat; | ||
| import static org.assertj.core.api.Assertions.assertThatThrownBy; | ||
| import static org.testng.Assert.assertEquals; | ||
| import static org.testng.Assert.assertTrue; | ||
|
|
||
|
|
@@ -63,6 +62,7 @@ protected boolean hasBehavior(TestingConnectorBehavior connectorBehavior) | |
| case SUPPORTS_PREDICATE_PUSHDOWN_WITH_VARCHAR_INEQUALITY: | ||
| return false; | ||
|
|
||
| case SUPPORTS_PREDICATE_EXPRESSION_PUSHDOWN: | ||
| case SUPPORTS_AGGREGATION_PUSHDOWN_STDDEV: | ||
| case SUPPORTS_AGGREGATION_PUSHDOWN_VARIANCE: | ||
| return true; | ||
|
|
@@ -406,13 +406,6 @@ public void testShowCreateTable() | |
| ")"); | ||
| } | ||
|
|
||
| @Override | ||
| public void testDeleteWithLike() | ||
|
||
| { | ||
| assertThatThrownBy(super::testDeleteWithLike) | ||
| .hasStackTraceContaining("TrinoException: Unsupported delete"); | ||
| } | ||
|
|
||
| @Test(dataProvider = "dataCompression") | ||
| public void testCreateWithDataCompression(DataCompression dataCompression) | ||
| { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.