From ced15eb5c627ce448e41edaf8e61540223ec5eff Mon Sep 17 00:00:00 2001 From: shawkins Date: Mon, 9 Oct 2017 18:25:13 -0400 Subject: [PATCH] TEIID-4711 adding pushdown and operators as functions --- .../hive/BaseHiveExecutionFactory.java | 9 ++++++ .../hive/HiveSQLConversionVisitor.java | 31 +++++++++++++++++++ .../hive/ImpalaExecutionFactory.java | 17 ++++++++++ .../hive/TestImpalaExecutionFactory.java | 16 ++++++++++ 4 files changed, 73 insertions(+) diff --git a/connectors/jdbc/translator-hive/src/main/java/org/teiid/translator/hive/BaseHiveExecutionFactory.java b/connectors/jdbc/translator-hive/src/main/java/org/teiid/translator/hive/BaseHiveExecutionFactory.java index ce1bd78760..a0aefcc0df 100644 --- a/connectors/jdbc/translator-hive/src/main/java/org/teiid/translator/hive/BaseHiveExecutionFactory.java +++ b/connectors/jdbc/translator-hive/src/main/java/org/teiid/translator/hive/BaseHiveExecutionFactory.java @@ -324,4 +324,13 @@ public boolean requiresLeftLinearJoin() { public boolean supportsOrderByUnrelated() { return false; } + + @Override + public boolean supportsLikeRegex() { + return true; + } + + public boolean rewriteBooleanFunctions() { + return false; + } } diff --git a/connectors/jdbc/translator-hive/src/main/java/org/teiid/translator/hive/HiveSQLConversionVisitor.java b/connectors/jdbc/translator-hive/src/main/java/org/teiid/translator/hive/HiveSQLConversionVisitor.java index fcdf1de63d..aafb5db1a3 100644 --- a/connectors/jdbc/translator-hive/src/main/java/org/teiid/translator/hive/HiveSQLConversionVisitor.java +++ b/connectors/jdbc/translator-hive/src/main/java/org/teiid/translator/hive/HiveSQLConversionVisitor.java @@ -23,6 +23,7 @@ import org.teiid.core.util.StringUtil; import org.teiid.language.*; +import org.teiid.language.Comparison.Operator; import org.teiid.language.Join.JoinType; import org.teiid.language.SQLConstants.Tokens; import org.teiid.translator.TypeFacility; @@ -164,6 +165,11 @@ public void visit(SetQuery obj) { endInlineView(obj); } + + @Override + protected String getLikeRegexString() { + return "REGEXP"; //$NON-NLS-1$ + } private void endInlineView(QueryExpression obj) { buffer.append(Tokens.RPAREN); @@ -275,4 +281,29 @@ protected void translateSQLType(Class type, Object obj, super.translateSQLType(type, obj, valuesbuffer); } } + + @Override + public void visit(Comparison obj) { + if (baseHiveExecutionFactory.rewriteBooleanFunctions() && obj.getLeftExpression() instanceof Function + && obj.getRightExpression() instanceof Literal + && obj.getLeftExpression().getType() == TypeFacility.RUNTIME_TYPES.BOOLEAN) { + Literal l = (Literal) obj.getRightExpression(); + Boolean val = (Boolean)l.getValue(); + Function leftExpression = (Function)obj.getLeftExpression(); + if ((Boolean.FALSE.equals(val) && obj.getOperator() == Operator.EQ) || + (Boolean.TRUE.equals(val) && obj.getOperator() == Operator.NE)) { + buffer.append(SQLConstants.Reserved.NOT); + buffer.append(SQLConstants.Tokens.LPAREN); + visit(leftExpression); + buffer.append(SQLConstants.Tokens.RPAREN); + return; + } else if ((Boolean.TRUE.equals(val) && obj.getOperator() == Operator.EQ) || + (Boolean.FALSE.equals(val) && obj.getOperator() == Operator.NE)) { + visit(leftExpression); + return; + } + } + super.visit(obj); + } + } diff --git a/connectors/jdbc/translator-hive/src/main/java/org/teiid/translator/hive/ImpalaExecutionFactory.java b/connectors/jdbc/translator-hive/src/main/java/org/teiid/translator/hive/ImpalaExecutionFactory.java index e2d2c59fa2..850e087829 100644 --- a/connectors/jdbc/translator-hive/src/main/java/org/teiid/translator/hive/ImpalaExecutionFactory.java +++ b/connectors/jdbc/translator-hive/src/main/java/org/teiid/translator/hive/ImpalaExecutionFactory.java @@ -28,6 +28,7 @@ import org.teiid.language.*; import org.teiid.language.Join.JoinType; import org.teiid.language.SortSpecification.Ordering; +import org.teiid.language.visitor.SQLStringVisitor; import org.teiid.metadata.AggregateAttributes; import org.teiid.translator.ExecutionContext; import org.teiid.translator.SourceSystemFunctions; @@ -44,6 +45,7 @@ public class ImpalaExecutionFactory extends BaseHiveExecutionFactory { public static final Version TWO_2 = Version.getVersion("2.2"); //$NON-NLS-1$ public static final Version TWO_0 = Version.getVersion("2.0"); //$NON-NLS-1$ public static final Version ONE_2_1 = Version.getVersion("1.2.1"); //$NON-NLS-1$ + public static final Version ONE_3_1 = Version.getVersion("1.3.1"); //$NON-NLS-1$ @Override public void start() throws TranslatorException { @@ -166,6 +168,11 @@ public void start() throws TranslatorException { addPushDownFunction(IMPALA, "initcap", STRING, STRING); //$NON-NLS-1$ addPushDownFunction(IMPALA, "instr", INTEGER, STRING, STRING); //$NON-NLS-1$ addPushDownFunction(IMPALA, "find_in_set", INTEGER, STRING, STRING); //$NON-NLS-1$ + + //standard function form of several predicates + addPushDownFunction(IMPALA, "ilike", BOOLEAN, STRING, STRING).setProperty(SQLStringVisitor.TEIID_NATIVE_QUERY, "($1 ilike $2)"); //$NON-NLS-1$ //$NON-NLS-2$ + addPushDownFunction(IMPALA, "rlike", BOOLEAN, STRING, STRING).setProperty(SQLStringVisitor.TEIID_NATIVE_QUERY, "($1 rlike $2)"); //$NON-NLS-1$ //$NON-NLS-2$ + addPushDownFunction(IMPALA, "iregexp", BOOLEAN, STRING, STRING).setProperty(SQLStringVisitor.TEIID_NATIVE_QUERY, "($1 iregexp $2)"); //$NON-NLS-1$ //$NON-NLS-2$ } @Override @@ -304,6 +311,11 @@ public org.teiid.translator.ExecutionFactory.SupportedJoinCriteria getSupportedJ public boolean requiresLeftLinearJoin() { return true; } + + @Override + public boolean supportsLikeRegex() { + return getVersion().compareTo(ONE_3_1) >= 0; + } @Override public List translateCommand(Command command, ExecutionContext context) { @@ -423,4 +435,9 @@ public boolean supportsStringAgg() { public boolean supportsIsDistinctCriteria() { return true; } + + @Override + public boolean rewriteBooleanFunctions() { + return true; + } } diff --git a/connectors/jdbc/translator-hive/src/test/java/org/teiid/translator/hive/TestImpalaExecutionFactory.java b/connectors/jdbc/translator-hive/src/test/java/org/teiid/translator/hive/TestImpalaExecutionFactory.java index 7a0b1c4ad1..03ef24b7ec 100644 --- a/connectors/jdbc/translator-hive/src/test/java/org/teiid/translator/hive/TestImpalaExecutionFactory.java +++ b/connectors/jdbc/translator-hive/src/test/java/org/teiid/translator/hive/TestImpalaExecutionFactory.java @@ -35,6 +35,7 @@ import org.teiid.translator.TypeFacility; import org.teiid.translator.jdbc.FunctionModifier; import org.teiid.translator.jdbc.SQLConversionVisitor; +import org.teiid.translator.jdbc.TranslationHelper; @SuppressWarnings("nls") public class TestImpalaExecutionFactory { @@ -133,4 +134,19 @@ private void helpTest(Expression srcExpression, String tgtType, String expectedE sqlVisitor.append(obj); assertEquals("WITH x AS (SELECT MAX(SmallA.StringNum) AS a FROM SmallA GROUP BY SmallA.StringKey) SELECT x.a FROM x", sqlVisitor.toString()); } + + @Test public void testPredicateFunctions() { + Select obj = (Select)TranslationHelper.helpTranslate("/bqt.vdb", null, impalaTranslator.getPushDownFunctions(), "select stringnum FROM bqt1.SmallA where ilike(stringkey, 'a_') and not(ilike(stringkey, '_b'))"); + SQLConversionVisitor sqlVisitor = impalaTranslator.getSQLConversionVisitor(); + sqlVisitor.append(obj); + assertEquals("SELECT SmallA.StringNum FROM SmallA WHERE (SmallA.StringKey ilike 'a_') AND NOT((SmallA.StringKey ilike '_b'))", sqlVisitor.toString()); + } + + @Test public void testLikeRegex() { + CommandBuilder commandBuilder = new CommandBuilder(RealMetadataFactory.exampleBQTCached()); + Select obj = (Select) commandBuilder.getCommand("SELECT max(StringNum) as a FROM bqt1.SmallA where stringkey like_regex '^[1-9]$'"); + SQLConversionVisitor sqlVisitor = impalaTranslator.getSQLConversionVisitor(); + sqlVisitor.append(obj); + assertEquals("SELECT MAX(SmallA.StringNum) AS a FROM SmallA WHERE SmallA.StringKey REGEXP '^[1-9]$'", sqlVisitor.toString()); + } }