소스 검색

HUE-7738 [editor] Extract type conversion tables from SqlFunctions to one per dialect

Johan Ahlen 5 년 전
부모
커밋
8c9648fbb6

+ 4 - 12
desktop/core/src/desktop/js/parse/sql/calcite/sqlParseSupport.js

@@ -15,6 +15,7 @@
 // limitations under the License.
 
 import { SqlFunctions } from 'sql/sqlFunctions';
+import { matchesType } from 'sql/reference/typeUtils';
 import stringDistance from 'sql/stringDistance';
 
 const identifierEquals = (a, b) =>
@@ -212,22 +213,13 @@ const initSqlParser = function(parser) {
         }
       };
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['BOOLEAN'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['BOOLEAN'], types)) {
       keywords = keywords.concat(['AND', 'OR']);
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['NUMBER'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['NUMBER'], types)) {
       keywords = keywords.concat(['+', '-', '*', '/', '%', 'DIV']);
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['STRING'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['STRING'], types)) {
       keywords = keywords.concat(['LIKE', 'NOT LIKE', 'REGEXP', 'RLIKE']);
     }
     return { suggestKeywords: keywords };

+ 4 - 12
desktop/core/src/desktop/js/parse/sql/druid/sqlParseSupport.js

@@ -15,6 +15,7 @@
 // limitations under the License.
 
 import { SqlFunctions } from 'sql/sqlFunctions';
+import { matchesType } from 'sql/reference/typeUtils';
 import stringDistance from 'sql/stringDistance';
 
 const identifierEquals = (a, b) =>
@@ -212,22 +213,13 @@ const initSqlParser = function(parser) {
         }
       };
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['BOOLEAN'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['BOOLEAN'], types)) {
       keywords = keywords.concat(['AND', 'OR']);
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['NUMBER'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['NUMBER'], types)) {
       keywords = keywords.concat(['+', '-', '*', '/', '%', 'DIV']);
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['STRING'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['STRING'], types)) {
       keywords = keywords.concat(['LIKE', 'NOT LIKE', 'REGEXP', 'RLIKE']);
     }
     return { suggestKeywords: keywords };

+ 4 - 12
desktop/core/src/desktop/js/parse/sql/elasticsearch/sqlParseSupport.js

@@ -15,6 +15,7 @@
 // limitations under the License.
 
 import { SqlFunctions } from 'sql/sqlFunctions';
+import { matchesType } from 'sql/reference/typeUtils';
 import stringDistance from 'sql/stringDistance';
 
 const identifierEquals = (a, b) =>
@@ -212,22 +213,13 @@ const initSqlParser = function(parser) {
         }
       };
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['BOOLEAN'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['BOOLEAN'], types)) {
       keywords = keywords.concat(['AND', 'OR']);
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['NUMBER'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['NUMBER'], types)) {
       keywords = keywords.concat(['+', '-', '*', '/', '%', 'DIV']);
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['STRING'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['STRING'], types)) {
       keywords = keywords.concat(['LIKE', 'NOT LIKE', 'REGEXP', 'RLIKE']);
     }
     return { suggestKeywords: keywords };

+ 4 - 12
desktop/core/src/desktop/js/parse/sql/flink/sqlParseSupport.js

@@ -15,6 +15,7 @@
 // limitations under the License.
 
 import { SqlFunctions } from 'sql/sqlFunctions';
+import { matchesType } from 'sql/reference/typeUtils';
 import stringDistance from 'sql/stringDistance';
 
 const identifierEquals = (a, b) =>
@@ -212,22 +213,13 @@ const initSqlParser = function(parser) {
         }
       };
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['BOOLEAN'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['BOOLEAN'], types)) {
       keywords = keywords.concat(['AND', 'OR']);
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['NUMBER'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['NUMBER'], types)) {
       keywords = keywords.concat(['+', '-', '*', '/', '%', 'DIV']);
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['STRING'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['STRING'], types)) {
       keywords = keywords.concat(['LIKE', 'NOT LIKE', 'REGEXP', 'RLIKE']);
     }
     return { suggestKeywords: keywords };

+ 4 - 12
desktop/core/src/desktop/js/parse/sql/generic/sqlParseSupport.js

@@ -15,6 +15,7 @@
 // limitations under the License.
 
 import { SqlFunctions } from 'sql/sqlFunctions';
+import { matchesType } from 'sql/reference/typeUtils';
 import stringDistance from 'sql/stringDistance';
 
 const identifierEquals = (a, b) =>
@@ -212,22 +213,13 @@ const initSqlParser = function(parser) {
         }
       };
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['BOOLEAN'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['BOOLEAN'], types)) {
       keywords = keywords.concat(['AND', 'OR']);
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['NUMBER'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['NUMBER'], types)) {
       keywords = keywords.concat(['+', '-', '*', '/', '%', 'DIV']);
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['STRING'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['STRING'], types)) {
       keywords = keywords.concat(['LIKE', 'NOT LIKE', 'REGEXP', 'RLIKE']);
     }
     return { suggestKeywords: keywords };

+ 4 - 12
desktop/core/src/desktop/js/parse/sql/hive/sqlParseSupport.js

@@ -15,6 +15,7 @@
 // limitations under the License.
 
 import { SqlFunctions } from 'sql/sqlFunctions';
+import { matchesType } from 'sql/reference/typeUtils';
 import stringDistance from 'sql/stringDistance';
 
 const identifierEquals = (a, b) =>
@@ -216,22 +217,13 @@ const initSqlParser = function(parser) {
         }
       };
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['BOOLEAN'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['BOOLEAN'], types)) {
       keywords = keywords.concat(['AND', 'OR']);
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['NUMBER'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['NUMBER'], types)) {
       keywords = keywords.concat(['+', '-', '*', '/', '%', 'DIV']);
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['STRING'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['STRING'], types)) {
       keywords = keywords.concat(['LIKE', 'NOT LIKE', 'REGEXP', 'RLIKE']);
     }
     return { suggestKeywords: keywords };

+ 4 - 12
desktop/core/src/desktop/js/parse/sql/impala/sqlParseSupport.js

@@ -15,6 +15,7 @@
 // limitations under the License.
 
 import { SqlFunctions } from 'sql/sqlFunctions';
+import { matchesType } from 'sql/reference/typeUtils';
 import stringDistance from 'sql/stringDistance';
 
 const identifierEquals = (a, b) =>
@@ -218,22 +219,13 @@ const initSqlParser = function(parser) {
         }
       };
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['BOOLEAN'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['BOOLEAN'], types)) {
       keywords = keywords.concat(['AND', 'OR']);
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['NUMBER'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['NUMBER'], types)) {
       keywords = keywords.concat(['+', '-', '*', '/', '%', 'DIV']);
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['STRING'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['STRING'], types)) {
       keywords = keywords.concat(['ILIKE', 'IREGEXP', 'LIKE', 'NOT LIKE', 'REGEXP', 'RLIKE']);
     }
     return { suggestKeywords: keywords };

+ 4 - 12
desktop/core/src/desktop/js/parse/sql/ksql/sqlParseSupport.js

@@ -15,6 +15,7 @@
 // limitations under the License.
 
 import { SqlFunctions } from 'sql/sqlFunctions';
+import { matchesType } from 'sql/reference/typeUtils';
 import stringDistance from 'sql/stringDistance';
 
 const identifierEquals = (a, b) =>
@@ -212,22 +213,13 @@ const initSqlParser = function(parser) {
         }
       };
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['BOOLEAN'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['BOOLEAN'], types)) {
       keywords = keywords.concat(['AND', 'OR']);
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['NUMBER'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['NUMBER'], types)) {
       keywords = keywords.concat(['+', '-', '*', '/', '%', 'DIV']);
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['STRING'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['STRING'], types)) {
       keywords = keywords.concat(['LIKE', 'NOT LIKE', 'REGEXP', 'RLIKE']);
     }
     return { suggestKeywords: keywords };

+ 4 - 12
desktop/core/src/desktop/js/parse/sql/phoenix/sqlParseSupport.js

@@ -15,6 +15,7 @@
 // limitations under the License.
 
 import { SqlFunctions } from 'sql/sqlFunctions';
+import { matchesType } from 'sql/reference/typeUtils';
 import stringDistance from 'sql/stringDistance';
 
 const identifierEquals = (a, b) =>
@@ -212,22 +213,13 @@ const initSqlParser = function(parser) {
         }
       };
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['BOOLEAN'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['BOOLEAN'], types)) {
       keywords = keywords.concat(['AND', 'OR']);
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['NUMBER'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['NUMBER'], types)) {
       keywords = keywords.concat(['+', '-', '*', '/', '%', 'DIV']);
     }
-    if (
-      typeof SqlFunctions === 'undefined' ||
-      SqlFunctions.matchesType(parser.yy.activeDialect, ['STRING'], types)
-    ) {
+    if (matchesType(parser.yy.activeDialect, ['STRING'], types)) {
       keywords = keywords.concat(['LIKE', 'NOT LIKE', 'REGEXP', 'RLIKE']);
     }
     return { suggestKeywords: keywords };

+ 1 - 342
desktop/core/src/desktop/js/parse/sql/presto/sqlParseSupport.js

@@ -14,348 +14,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-const IMPLICIT_TYPE_CONVERSION = {
-  BOOLEAN: {
-    BOOLEAN: true,
-    TIMESTAMP: false,
-    TIME: false,
-    DATE: false,
-    VARBINARY: false,
-    TINYINT: false,
-    SMALLINT: false,
-    INTEGER: false,
-    BIGINT: false,
-    DOUBLE: false,
-    DECIMAL: false,
-    REAL: false,
-    NUMBER: false,
-    CHAR: false,
-    VARCHAR: false,
-    T: true
-  },
-  TIMESTAMP: {
-    BOOLEAN: false,
-    TIMESTAMP: true,
-    TIME: true,
-    DATE: false,
-    VARBINARY: false,
-    TINYINT: false,
-    SMALLINT: false,
-    INTEGER: false,
-    BIGINT: false,
-    DOUBLE: false,
-    DECIMAL: false,
-    REAL: false,
-    NUMBER: false,
-    CHAR: false,
-    VARCHAR: false,
-    T: true
-  },
-  TIME: {
-    BOOLEAN: false,
-    TIMESTAMP: true,
-    TIME: true,
-    DATE: false,
-    VARBINARY: false,
-    TINYINT: false,
-    SMALLINT: false,
-    INTEGER: false,
-    BIGINT: false,
-    DOUBLE: false,
-    DECIMAL: false,
-    REAL: false,
-    NUMBER: false,
-    CHAR: false,
-    VARCHAR: false,
-    T: true
-  },
-  DATE: {
-    BOOLEAN: false,
-    TIMESTAMP: false,
-    TIME: false,
-    DATE: true,
-    VARBINARY: false,
-    TINYINT: false,
-    SMALLINT: false,
-    INTEGER: false,
-    BIGINT: false,
-    DOUBLE: false,
-    DECIMAL: false,
-    REAL: false,
-    NUMBER: false,
-    CHAR: false,
-    VARCHAR: false,
-    T: true
-  },
-  VARBINARY: {
-    BOOLEAN: false,
-    TIMESTAMP: false,
-    TIME: false,
-    DATE: false,
-    VARBINARY: true,
-    TINYINT: false,
-    SMALLINT: false,
-    INTEGER: false,
-    BIGINT: false,
-    DOUBLE: false,
-    DECIMAL: false,
-    REAL: false,
-    NUMBER: false,
-    CHAR: false,
-    VARCHAR: false,
-    T: true
-  },
-  TINYINT: {
-    BOOLEAN: false,
-    TIMESTAMP: false,
-    TIME: false,
-    DATE: false,
-    VARBINARY: false,
-    TINYINT: true,
-    SMALLINT: false,
-    INTEGER: false,
-    BIGINT: false,
-    DOUBLE: false,
-    DECIMAL: false,
-    REAL: false,
-    NUMBER: true,
-    CHAR: false,
-    VARCHAR: false,
-    T: true
-  },
-  SMALLINT: {
-    BOOLEAN: false,
-    TIMESTAMP: false,
-    TIME: false,
-    DATE: false,
-    VARBINARY: false,
-    TINYINT: true,
-    SMALLINT: true,
-    INTEGER: false,
-    BIGINT: false,
-    DOUBLE: false,
-    DECIMAL: false,
-    REAL: false,
-    NUMBER: true,
-    CHAR: false,
-    VARCHAR: false,
-    T: true
-  },
-  INTEGER: {
-    BOOLEAN: false,
-    TIMESTAMP: false,
-    TIME: false,
-    DATE: false,
-    VARBINARY: false,
-    TINYINT: true,
-    SMALLINT: true,
-    INTEGER: true,
-    BIGINT: false,
-    DOUBLE: false,
-    DECIMAL: false,
-    REAL: false,
-    NUMBER: true,
-    CHAR: false,
-    VARCHAR: false,
-    T: true
-  },
-  BIGINT: {
-    BOOLEAN: false,
-    TIMESTAMP: false,
-    TIME: false,
-    DATE: false,
-    VARBINARY: false,
-    TINYINT: true,
-    SMALLINT: true,
-    INTEGER: true,
-    BIGINT: true,
-    DOUBLE: false,
-    DECIMAL: false,
-    REAL: false,
-    NUMBER: true,
-    CHAR: false,
-    VARCHAR: false,
-    T: true
-  },
-  DOUBLE: {
-    BOOLEAN: false,
-    TIMESTAMP: false,
-    TIME: false,
-    DATE: false,
-    VARBINARY: false,
-    TINYINT: true,
-    SMALLINT: true,
-    INTEGER: true,
-    BIGINT: true,
-    DOUBLE: true,
-    DECIMAL: false,
-    REAL: false,
-    NUMBER: true,
-    CHAR: true,
-    VARCHAR: true,
-    T: true
-  },
-  DECIMAL: {
-    BOOLEAN: false,
-    TIMESTAMP: false,
-    TIME: false,
-    DATE: false,
-    VARBINARY: false,
-    TINYINT: true,
-    SMALLINT: true,
-    INTEGER: true,
-    BIGINT: true,
-    DOUBLE: true,
-    DECIMAL: true,
-    REAL: true,
-    NUMBER: true,
-    CHAR: true,
-    VARCHAR: true,
-    T: true
-  },
-  REAL: {
-    BOOLEAN: false,
-    TIMESTAMP: false,
-    TIME: false,
-    DATE: false,
-    VARBINARY: false,
-    TINYINT: true,
-    SMALLINT: true,
-    INTEGER: true,
-    BIGINT: true,
-    DOUBLE: true,
-    DECIMAL: true,
-    REAL: true,
-    NUMBER: true,
-    CHAR: true,
-    VARCHAR: true,
-    T: true
-  },
-  NUMBER: {
-    BOOLEAN: false,
-    TIMESTAMP: false,
-    TIME: false,
-    DATE: false,
-    VARBINARY: false,
-    TINYINT: true,
-    SMALLINT: true,
-    INTEGER: true,
-    BIGINT: true,
-    DOUBLE: true,
-    DECIMAL: true,
-    REAL: true,
-    NUMBER: true,
-    CHAR: true,
-    VARCHAR: true,
-    T: true
-  },
-  CHAR: {
-    BOOLEAN: false,
-    TIMESTAMP: true,
-    TIME: true,
-    DATE: true,
-    VARBINARY: false,
-    TINYINT: true,
-    SMALLINT: true,
-    INTEGER: true,
-    BIGINT: true,
-    DOUBLE: true,
-    DECIMAL: true,
-    REAL: true,
-    NUMBER: true,
-    CHAR: true,
-    VARCHAR: true,
-    T: true
-  },
-  VARCHAR: {
-    BOOLEAN: false,
-    TIMESTAMP: true,
-    TIME: true,
-    DATE: true,
-    VARBINARY: false,
-    TINYINT: true,
-    SMALLINT: true,
-    INTEGER: true,
-    BIGINT: true,
-    DOUBLE: true,
-    DECIMAL: true,
-    REAL: true,
-    NUMBER: true,
-    CHAR: true,
-    VARCHAR: true,
-    T: true
-  },
-  T: {
-    BOOLEAN: true,
-    TIMESTAMP: true,
-    TIME: true,
-    DATE: true,
-    VARBINARY: true,
-    TINYINT: true,
-    SMALLINT: true,
-    INTEGER: true,
-    BIGINT: true,
-    DOUBLE: true,
-    DECIMAL: true,
-    REAL: true,
-    NUMBER: true,
-    CHAR: true,
-    VARCHAR: true,
-    T: true
-  }
-};
-
-const stripPrecision = types => {
-  const result = [];
-  types.forEach(type => {
-    if (type.indexOf('(') > -1) {
-      result.push(type.substring(0, type.indexOf('(')));
-    } else {
-      result.push(type);
-    }
-  });
-  return result;
-};
-
-/**
- * Matches types based on implicit conversion i.e. if you expect a BIGINT then INT is ok but not BOOLEAN etc.
- *
- * @param expectedTypes
- * @param actualRawTypes
- * @returns {boolean}
- */
-const matchesType = function(expectedTypes, actualRawTypes) {
-  if (expectedTypes.length === 1 && expectedTypes[0] === 'T') {
-    return true;
-  }
-  const actualTypes = stripPrecision(actualRawTypes);
-  if (
-    actualTypes.indexOf('ARRAY') !== -1 ||
-    actualTypes.indexOf('MAP') !== -1 ||
-    actualTypes.indexOf('STRUCT') !== -1 ||
-    actualTypes.indexOf('ROW') !== -1
-  ) {
-    return true;
-  }
-  for (let i = 0; i < expectedTypes.length; i++) {
-    for (let j = 0; j < actualTypes.length; j++) {
-      // To support future unknown types
-      if (
-        typeof IMPLICIT_TYPE_CONVERSION[expectedTypes[i]] === 'undefined' ||
-        typeof IMPLICIT_TYPE_CONVERSION[expectedTypes[i]][actualTypes[j]] == 'undefined'
-      ) {
-        return true;
-      }
-      if (
-        IMPLICIT_TYPE_CONVERSION[expectedTypes[i]] &&
-        IMPLICIT_TYPE_CONVERSION[expectedTypes[i]][actualTypes[j]]
-      ) {
-        return true;
-      }
-    }
-  }
-  return false;
-};
+import { matchesType } from 'sql/reference/typeUtils';
 
 /**
  * Calculates the Optimal String Alignment distance between two strings. Returns 0 when the strings are equal and the

+ 4 - 11
desktop/core/src/desktop/js/sql/autocompleteResults.js

@@ -25,6 +25,7 @@ import huePubSub from 'utils/huePubSub';
 import I18n from 'utils/i18n';
 import sqlUtils from 'sql/sqlUtils';
 import { SqlSetOptions, SqlFunctions } from 'sql/sqlFunctions';
+import { matchesType } from 'sql/reference/typeUtils';
 import { DIALECT } from 'apps/notebook2/snippet';
 import { cancelActiveRequest } from 'api/apiUtils';
 import { findBrowserConnector, getRootFilePath } from 'utils/hueConfig';
@@ -591,9 +592,7 @@ class AutocompleteResults {
       colRefDeferred.done(colRef => {
         const colRefKeywordSuggestions = [];
         Object.keys(self.parseResult.suggestColRefKeywords).forEach(typeForKeywords => {
-          if (
-            SqlFunctions.matchesType(self.dialect(), [typeForKeywords], [colRef.type.toUpperCase()])
-          ) {
+          if (matchesType(self.dialect(), [typeForKeywords], [colRef.type.toUpperCase()])) {
             self.parseResult.suggestColRefKeywords[typeForKeywords].forEach(keyword => {
               colRefKeywordSuggestions.push({
                 value: self.parseResult.lowerCase ? keyword.toLowerCase() : keyword,
@@ -1079,14 +1078,8 @@ class AutocompleteResults {
                         name += '[]';
                       }
                       if (
-                        SqlFunctions.matchesType(self.dialect(), types, [
-                          childEntry.getType().toUpperCase()
-                        ]) ||
-                        SqlFunctions.matchesType(
-                          self.dialect(),
-                          [childEntry.getType().toUpperCase()],
-                          types
-                        ) ||
+                        matchesType(self.dialect(), types, [childEntry.getType().toUpperCase()]) ||
+                        matchesType(self.dialect(), [childEntry.getType().toUpperCase()], types) ||
                         childEntry.getType === 'column' ||
                         childEntry.isComplex()
                       ) {

+ 273 - 0
desktop/core/src/desktop/js/sql/reference/generic/typeConversion.js

@@ -0,0 +1,273 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you 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.
+
+export const TYPE_CONVERSION = {
+  BOOLEAN: {
+    BOOLEAN: true,
+    TIMESTAMP: false,
+    TINYINT: false,
+    SMALLINT: false,
+    INT: false,
+    BIGINT: false,
+    DOUBLE: false,
+    REAL: false,
+    DECIMAL: false,
+    FLOAT: false,
+    NUMBER: false,
+    CHAR: false,
+    VARCHAR: false,
+    STRING: false,
+    T: true
+  },
+  TIMESTAMP: {
+    BOOLEAN: false,
+    TIMESTAMP: true,
+    TINYINT: false,
+    SMALLINT: false,
+    INT: false,
+    BIGINT: false,
+    DOUBLE: false,
+    REAL: false,
+    DECIMAL: false,
+    FLOAT: false,
+    NUMBER: false,
+    CHAR: false,
+    VARCHAR: false,
+    STRING: true,
+    T: true
+  },
+  TINYINT: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    TINYINT: true,
+    SMALLINT: false,
+    INT: false,
+    BIGINT: false,
+    DOUBLE: false,
+    REAL: false,
+    DECIMAL: false,
+    FLOAT: false,
+    NUMBER: true,
+    CHAR: false,
+    VARCHAR: false,
+    STRING: false,
+    T: true
+  },
+  SMALLINT: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: false,
+    BIGINT: false,
+    DOUBLE: false,
+    REAL: false,
+    DECIMAL: false,
+    FLOAT: false,
+    NUMBER: true,
+    CHAR: false,
+    VARCHAR: false,
+    STRING: false,
+    T: true
+  },
+  INT: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: true,
+    BIGINT: false,
+    DOUBLE: false,
+    REAL: false,
+    DECIMAL: false,
+    FLOAT: false,
+    NUMBER: true,
+    CHAR: false,
+    VARCHAR: false,
+    STRING: false,
+    T: true
+  },
+  BIGINT: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: true,
+    BIGINT: true,
+    DOUBLE: false,
+    REAL: false,
+    DECIMAL: false,
+    FLOAT: false,
+    NUMBER: true,
+    CHAR: false,
+    VARCHAR: false,
+    STRING: false,
+    T: true
+  },
+  DOUBLE: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: true,
+    BIGINT: true,
+    DOUBLE: true,
+    REAL: true,
+    DECIMAL: false,
+    FLOAT: true,
+    NUMBER: true,
+    CHAR: false,
+    VARCHAR: false,
+    STRING: false,
+    T: true
+  },
+  REAL: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: true,
+    BIGINT: true,
+    DOUBLE: true,
+    REAL: true,
+    DECIMAL: false,
+    FLOAT: true,
+    NUMBER: true,
+    CHAR: false,
+    VARCHAR: false,
+    STRING: false,
+    T: true
+  },
+  DECIMAL: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: true,
+    BIGINT: true,
+    DOUBLE: true,
+    REAL: true,
+    DECIMAL: true,
+    FLOAT: true,
+    NUMBER: true,
+    CHAR: false,
+    VARCHAR: false,
+    STRING: false,
+    T: true
+  },
+  FLOAT: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: true,
+    BIGINT: true,
+    DOUBLE: false,
+    REAL: false,
+    DECIMAL: false,
+    FLOAT: true,
+    NUMBER: true,
+    CHAR: false,
+    VARCHAR: false,
+    STRING: false,
+    T: true
+  },
+  NUMBER: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: true,
+    BIGINT: true,
+    DOUBLE: true,
+    REAL: true,
+    DECIMAL: true,
+    FLOAT: true,
+    NUMBER: true,
+    CHAR: false,
+    VARCHAR: false,
+    STRING: false,
+    T: true
+  },
+  CHAR: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    TINYINT: false,
+    SMALLINT: false,
+    INT: false,
+    BIGINT: false,
+    DOUBLE: false,
+    REAL: false,
+    DECIMAL: false,
+    FLOAT: false,
+    NUMBER: false,
+    CHAR: true,
+    VARCHAR: false,
+    STRING: false,
+    T: true
+  },
+  VARCHAR: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    TINYINT: false,
+    SMALLINT: false,
+    INT: false,
+    BIGINT: false,
+    DOUBLE: false,
+    REAL: false,
+    DECIMAL: false,
+    FLOAT: false,
+    NUMBER: false,
+    CHAR: true,
+    VARCHAR: true,
+    STRING: false,
+    T: true
+  },
+  STRING: {
+    BOOLEAN: false,
+    TIMESTAMP: true,
+    TINYINT: false,
+    SMALLINT: false,
+    INT: false,
+    BIGINT: false,
+    DOUBLE: false,
+    REAL: false,
+    DECIMAL: false,
+    FLOAT: false,
+    NUMBER: false,
+    CHAR: true,
+    VARCHAR: false,
+    STRING: true,
+    T: true
+  },
+  T: {
+    BOOLEAN: true,
+    TIMESTAMP: true,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: true,
+    BIGINT: true,
+    DOUBLE: true,
+    REAL: true,
+    DECIMAL: true,
+    FLOAT: true,
+    NUMBER: true,
+    CHAR: true,
+    VARCHAR: true,
+    STRING: true,
+    T: true
+  }
+};

+ 322 - 0
desktop/core/src/desktop/js/sql/reference/hive/typeConversion.js

@@ -0,0 +1,322 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you 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.
+
+export const TYPE_CONVERSION = {
+  BOOLEAN: {
+    BOOLEAN: true,
+    TIMESTAMP: false,
+    DATE: false,
+    BINARY: false,
+    TINYINT: false,
+    SMALLINT: false,
+    INT: false,
+    INTEGER: false,
+    BIGINT: false,
+    FLOAT: false,
+    DOUBLE: false,
+    DECIMAL: false,
+    NUMBER: false,
+    STRING: false,
+    CHAR: false,
+    VARCHAR: false,
+    T: true
+  },
+  TIMESTAMP: {
+    BOOLEAN: false,
+    TIMESTAMP: true,
+    DATE: false,
+    BINARY: false,
+    TINYINT: false,
+    SMALLINT: false,
+    INT: false,
+    INTEGER: false,
+    BIGINT: false,
+    FLOAT: false,
+    DOUBLE: false,
+    DECIMAL: false,
+    NUMBER: false,
+    STRING: false,
+    CHAR: false,
+    VARCHAR: false,
+    T: true
+  },
+  DATE: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    DATE: true,
+    BINARY: false,
+    TINYINT: false,
+    SMALLINT: false,
+    INT: false,
+    INTEGER: false,
+    BIGINT: false,
+    FLOAT: false,
+    DOUBLE: false,
+    DECIMAL: false,
+    NUMBER: false,
+    STRING: false,
+    CHAR: false,
+    VARCHAR: false,
+    T: true
+  },
+  BINARY: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    DATE: false,
+    BINARY: true,
+    TINYINT: false,
+    SMALLINT: false,
+    INT: false,
+    INTEGER: false,
+    BIGINT: false,
+    FLOAT: false,
+    DOUBLE: false,
+    DECIMAL: false,
+    NUMBER: false,
+    STRING: false,
+    CHAR: false,
+    VARCHAR: false,
+    T: true
+  },
+  TINYINT: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    DATE: false,
+    BINARY: false,
+    TINYINT: true,
+    SMALLINT: false,
+    INT: false,
+    INTEGER: false,
+    BIGINT: false,
+    FLOAT: false,
+    DOUBLE: false,
+    DECIMAL: false,
+    NUMBER: true,
+    STRING: false,
+    CHAR: false,
+    VARCHAR: false,
+    T: true
+  },
+  SMALLINT: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    DATE: false,
+    BINARY: false,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: false,
+    INTEGER: false,
+    BIGINT: false,
+    FLOAT: false,
+    DOUBLE: false,
+    DECIMAL: false,
+    NUMBER: true,
+    STRING: false,
+    CHAR: false,
+    VARCHAR: false,
+    T: true
+  },
+  INT: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    DATE: false,
+    BINARY: false,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: true,
+    INTEGER: true,
+    BIGINT: false,
+    FLOAT: false,
+    DOUBLE: false,
+    DECIMAL: false,
+    NUMBER: true,
+    STRING: false,
+    CHAR: false,
+    VARCHAR: false,
+    T: true
+  },
+  BIGINT: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    DATE: false,
+    BINARY: false,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: true,
+    INTEGER: true,
+    BIGINT: true,
+    FLOAT: false,
+    DOUBLE: false,
+    DECIMAL: false,
+    NUMBER: true,
+    STRING: false,
+    CHAR: false,
+    VARCHAR: false,
+    T: true
+  },
+  FLOAT: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    DATE: false,
+    BINARY: false,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: true,
+    INTEGER: true,
+    BIGINT: true,
+    FLOAT: true,
+    DOUBLE: false,
+    DECIMAL: false,
+    NUMBER: true,
+    STRING: false,
+    CHAR: false,
+    VARCHAR: false,
+    T: true
+  },
+  DOUBLE: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    DATE: false,
+    BINARY: false,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: true,
+    INTEGER: true,
+    BIGINT: true,
+    FLOAT: true,
+    DOUBLE: true,
+    DECIMAL: false,
+    NUMBER: true,
+    STRING: true,
+    CHAR: true,
+    VARCHAR: true,
+    T: true
+  },
+  DECIMAL: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    DATE: false,
+    BINARY: false,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: true,
+    INTEGER: true,
+    BIGINT: true,
+    FLOAT: true,
+    DOUBLE: true,
+    DECIMAL: true,
+    NUMBER: true,
+    STRING: true,
+    CHAR: true,
+    VARCHAR: true,
+    T: true
+  },
+  NUMBER: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    DATE: false,
+    BINARY: false,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: true,
+    INTEGER: true,
+    BIGINT: true,
+    FLOAT: true,
+    DOUBLE: true,
+    DECIMAL: true,
+    NUMBER: true,
+    STRING: true,
+    CHAR: true,
+    VARCHAR: true,
+    T: true
+  },
+  STRING: {
+    BOOLEAN: false,
+    TIMESTAMP: true,
+    DATE: true,
+    BINARY: false,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: true,
+    INTEGER: true,
+    BIGINT: true,
+    FLOAT: true,
+    DOUBLE: true,
+    DECIMAL: true,
+    NUMBER: true,
+    STRING: true,
+    CHAR: true,
+    VARCHAR: true,
+    T: true
+  },
+  CHAR: {
+    BOOLEAN: false,
+    TIMESTAMP: true,
+    DATE: true,
+    BINARY: false,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: true,
+    INTEGER: true,
+    BIGINT: true,
+    FLOAT: true,
+    DOUBLE: true,
+    DECIMAL: true,
+    NUMBER: true,
+    STRING: true,
+    CHAR: true,
+    VARCHAR: true,
+    T: true
+  },
+  VARCHAR: {
+    BOOLEAN: false,
+    TIMESTAMP: true,
+    DATE: true,
+    BINARY: false,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: true,
+    INTEGER: true,
+    BIGINT: true,
+    FLOAT: true,
+    DOUBLE: true,
+    DECIMAL: true,
+    NUMBER: true,
+    STRING: true,
+    CHAR: true,
+    VARCHAR: true,
+    T: true
+  },
+  T: {
+    BOOLEAN: true,
+    TIMESTAMP: true,
+    DATE: true,
+    BINARY: true,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: true,
+    INTEGER: true,
+    BIGINT: true,
+    FLOAT: true,
+    DOUBLE: true,
+    DECIMAL: true,
+    NUMBER: true,
+    STRING: true,
+    CHAR: true,
+    VARCHAR: true,
+    T: true
+  }
+};

+ 273 - 0
desktop/core/src/desktop/js/sql/reference/impala/typeConversion.js

@@ -0,0 +1,273 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you 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.
+
+export const TYPE_CONVERSION = {
+  BOOLEAN: {
+    BOOLEAN: true,
+    TIMESTAMP: false,
+    TINYINT: false,
+    SMALLINT: false,
+    INT: false,
+    BIGINT: false,
+    DOUBLE: false,
+    REAL: false,
+    DECIMAL: false,
+    FLOAT: false,
+    NUMBER: false,
+    CHAR: false,
+    VARCHAR: false,
+    STRING: false,
+    T: true
+  },
+  TIMESTAMP: {
+    BOOLEAN: false,
+    TIMESTAMP: true,
+    TINYINT: false,
+    SMALLINT: false,
+    INT: false,
+    BIGINT: false,
+    DOUBLE: false,
+    REAL: false,
+    DECIMAL: false,
+    FLOAT: false,
+    NUMBER: false,
+    CHAR: false,
+    VARCHAR: false,
+    STRING: true,
+    T: true
+  },
+  TINYINT: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    TINYINT: true,
+    SMALLINT: false,
+    INT: false,
+    BIGINT: false,
+    DOUBLE: false,
+    REAL: false,
+    DECIMAL: false,
+    FLOAT: false,
+    NUMBER: true,
+    CHAR: false,
+    VARCHAR: false,
+    STRING: false,
+    T: true
+  },
+  SMALLINT: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: false,
+    BIGINT: false,
+    DOUBLE: false,
+    REAL: false,
+    DECIMAL: false,
+    FLOAT: false,
+    NUMBER: true,
+    CHAR: false,
+    VARCHAR: false,
+    STRING: false,
+    T: true
+  },
+  INT: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: true,
+    BIGINT: false,
+    DOUBLE: false,
+    REAL: false,
+    DECIMAL: false,
+    FLOAT: false,
+    NUMBER: true,
+    CHAR: false,
+    VARCHAR: false,
+    STRING: false,
+    T: true
+  },
+  BIGINT: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: true,
+    BIGINT: true,
+    DOUBLE: false,
+    REAL: false,
+    DECIMAL: false,
+    FLOAT: false,
+    NUMBER: true,
+    CHAR: false,
+    VARCHAR: false,
+    STRING: false,
+    T: true
+  },
+  DOUBLE: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: true,
+    BIGINT: true,
+    DOUBLE: true,
+    REAL: true,
+    DECIMAL: false,
+    FLOAT: true,
+    NUMBER: true,
+    CHAR: false,
+    VARCHAR: false,
+    STRING: false,
+    T: true
+  },
+  REAL: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: true,
+    BIGINT: true,
+    DOUBLE: true,
+    REAL: true,
+    DECIMAL: false,
+    FLOAT: true,
+    NUMBER: true,
+    CHAR: false,
+    VARCHAR: false,
+    STRING: false,
+    T: true
+  },
+  DECIMAL: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: true,
+    BIGINT: true,
+    DOUBLE: true,
+    REAL: true,
+    DECIMAL: true,
+    FLOAT: true,
+    NUMBER: true,
+    CHAR: false,
+    VARCHAR: false,
+    STRING: false,
+    T: true
+  },
+  FLOAT: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: true,
+    BIGINT: true,
+    DOUBLE: false,
+    REAL: false,
+    DECIMAL: false,
+    FLOAT: true,
+    NUMBER: true,
+    CHAR: false,
+    VARCHAR: false,
+    STRING: false,
+    T: true
+  },
+  NUMBER: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: true,
+    BIGINT: true,
+    DOUBLE: true,
+    REAL: true,
+    DECIMAL: true,
+    FLOAT: true,
+    NUMBER: true,
+    CHAR: false,
+    VARCHAR: false,
+    STRING: false,
+    T: true
+  },
+  CHAR: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    TINYINT: false,
+    SMALLINT: false,
+    INT: false,
+    BIGINT: false,
+    DOUBLE: false,
+    REAL: false,
+    DECIMAL: false,
+    FLOAT: false,
+    NUMBER: false,
+    CHAR: true,
+    VARCHAR: false,
+    STRING: false,
+    T: true
+  },
+  VARCHAR: {
+    BOOLEAN: false,
+    TIMESTAMP: false,
+    TINYINT: false,
+    SMALLINT: false,
+    INT: false,
+    BIGINT: false,
+    DOUBLE: false,
+    REAL: false,
+    DECIMAL: false,
+    FLOAT: false,
+    NUMBER: false,
+    CHAR: true,
+    VARCHAR: true,
+    STRING: false,
+    T: true
+  },
+  STRING: {
+    BOOLEAN: false,
+    TIMESTAMP: true,
+    TINYINT: false,
+    SMALLINT: false,
+    INT: false,
+    BIGINT: false,
+    DOUBLE: false,
+    REAL: false,
+    DECIMAL: false,
+    FLOAT: false,
+    NUMBER: false,
+    CHAR: true,
+    VARCHAR: false,
+    STRING: true,
+    T: true
+  },
+  T: {
+    BOOLEAN: true,
+    TIMESTAMP: true,
+    TINYINT: true,
+    SMALLINT: true,
+    INT: true,
+    BIGINT: true,
+    DOUBLE: true,
+    REAL: true,
+    DECIMAL: true,
+    FLOAT: true,
+    NUMBER: true,
+    CHAR: true,
+    VARCHAR: true,
+    STRING: true,
+    T: true
+  }
+};

+ 79 - 0
desktop/core/src/desktop/js/sql/reference/typeUtils.js

@@ -0,0 +1,79 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you 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.
+
+import { TYPE_CONVERSION as HIVE_TYPE_CONVERSION } from './hive/typeConversion';
+import { TYPE_CONVERSION as IMPALA_TYPE_CONVERSION } from './impala/typeConversion';
+import { TYPE_CONVERSION as GENERIC_TYPE_CONVERSION } from './generic/typeConversion';
+
+const stripPrecision = function(types) {
+  const result = [];
+  types.forEach(type => {
+    if (type.indexOf('(') > -1) {
+      result.push(type.substring(0, type.indexOf('(')));
+    } else {
+      result.push(type);
+    }
+  });
+  return result;
+};
+
+const getTypeConversion = dialect => {
+  if (dialect === 'impala') {
+    return IMPALA_TYPE_CONVERSION;
+  }
+  if (dialect === 'hive') {
+    return HIVE_TYPE_CONVERSION;
+  }
+  return GENERIC_TYPE_CONVERSION;
+};
+
+/**
+ * Matches types based on implicit conversion i.e. if you expect a BIGINT then INT is ok but not BOOLEAN etc.
+ *
+ * @param dialect
+ * @param expectedTypes
+ * @param actualRawTypes
+ * @returns {boolean}
+ */
+export const matchesType = function(dialect, expectedTypes, actualRawTypes) {
+  if (expectedTypes.length === 1 && expectedTypes[0] === 'T') {
+    return true;
+  }
+  const actualTypes = stripPrecision(actualRawTypes);
+  if (
+    actualTypes.indexOf('ARRAY') !== -1 ||
+    actualTypes.indexOf('MAP') !== -1 ||
+    actualTypes.indexOf('STRUCT') !== -1
+  ) {
+    return true;
+  }
+  const conversionTable = getTypeConversion(dialect);
+  for (let i = 0; i < expectedTypes.length; i++) {
+    for (let j = 0; j < actualTypes.length; j++) {
+      // To support future unknown types
+      if (
+        typeof conversionTable[expectedTypes[i]] === 'undefined' ||
+        typeof conversionTable[expectedTypes[i]][actualTypes[j]] == 'undefined'
+      ) {
+        return true;
+      }
+      if (conversionTable[expectedTypes[i]] && conversionTable[expectedTypes[i]][actualTypes[j]]) {
+        return true;
+      }
+    }
+  }
+  return false;
+};

+ 60 - 0
desktop/core/src/desktop/js/sql/reference/typeUtils.test.js

@@ -0,0 +1,60 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you 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.
+
+import { matchesType } from 'sql/reference/typeUtils';
+
+describe('typeUtils.js', () => {
+  it('should matchTypes for NUMBER', () => {
+    expect(matchesType('hive', ['NUMBER'], ['INT'])).toBeTruthy();
+    expect(matchesType('hive', ['NUMBER'], ['BIGINT'])).toBeTruthy();
+    expect(matchesType('hive', ['NUMBER'], ['DOUBLE'])).toBeTruthy();
+    expect(matchesType('hive', ['NUMBER'], ['DECIMAL'])).toBeTruthy();
+    expect(matchesType('hive', ['NUMBER'], ['T'])).toBeTruthy();
+    expect(matchesType('hive', ['NUMBER'], ['STRING'])).toBeTruthy();
+    expect(matchesType('hive', ['INT'], ['NUMBER'])).toBeTruthy();
+    expect(matchesType('hive', ['BIGINT'], ['NUMBER'])).toBeTruthy();
+    expect(matchesType('hive', ['DOUBLE'], ['NUMBER'])).toBeTruthy();
+    expect(matchesType('hive', ['DECIMAL'], ['NUMBER'])).toBeTruthy();
+
+    expect(matchesType('hive', ['STRING'], ['NUMBER'])).toBeTruthy();
+    expect(matchesType('hive', ['T'], ['NUMBER'])).toBeTruthy();
+    expect(matchesType('hive', ['NUMBER'], ['BOOLEAN'])).toBeFalsy();
+    expect(matchesType('hive', ['BOOLEAN'], ['NUMBER'])).toBeFalsy();
+  });
+
+  it('should strip precision', () => {
+    expect(matchesType('hive', ['STRING'], ['VARCHAR(10)'])).toBeTruthy();
+    expect(matchesType('hive', ['NUMBER'], ['DECIMAL(10,1)'])).toBeTruthy();
+    expect(matchesType('hive', ['T'], ['CHAR(1)'])).toBeTruthy();
+  });
+
+  it('should matchTypes for BIGINT', () => {
+    expect(matchesType('hive', ['BIGINT'], ['BIGINT'])).toBeTruthy();
+    expect(matchesType('hive', ['BIGINT'], ['INT'])).toBeTruthy();
+    expect(matchesType('hive', ['BIGINT'], ['SMALLINT'])).toBeTruthy();
+    expect(matchesType('hive', ['BIGINT'], ['TINYINT'])).toBeTruthy();
+    expect(matchesType('hive', ['BIGINT'], ['T'])).toBeTruthy();
+    expect(matchesType('hive', ['BIGINT'], ['BOOLEAN'])).toBeFalsy();
+    expect(matchesType('hive', ['BIGINT'], ['STRING'])).toBeFalsy();
+    expect(matchesType('hive', ['INT'], ['BIGINT'])).toBeFalsy();
+    expect(matchesType('hive', ['SMALLINT'], ['BIGINT'])).toBeFalsy();
+    expect(matchesType('hive', ['TINYINT'], ['BIGINT'])).toBeFalsy();
+    expect(matchesType('hive', ['DECIMAL'], ['BIGINT'])).toBeTruthy();
+    expect(matchesType('hive', ['T'], ['BIGINT'])).toBeTruthy();
+    expect(matchesType('hive', ['BOOLEAN'], ['BIGINT'])).toBeFalsy();
+    expect(matchesType('hive', ['STRING'], ['BIGINT'])).toBeTruthy();
+  });
+});

+ 6 - 46
desktop/core/src/desktop/js/sql/sqlFunctions.test.js

@@ -15,6 +15,7 @@
 // limitations under the License.
 
 import { SqlFunctions } from './sqlFunctions';
+import { matchesType } from 'sql/reference/typeUtils';
 
 describe('sqlFunctions.js', () => {
   it('should suggest only BOOLEAN functions when return type is set to BOOLEAN for Hive', () => {
@@ -44,9 +45,9 @@ describe('sqlFunctions.js', () => {
 
     expect(completions.length).not.toEqual(0);
 
-    const completionsWithCorrectType = completions.filter(completion => {
-      return SqlFunctions.matchesType('hive', ['STRING'], [completion.meta]);
-    });
+    const completionsWithCorrectType = completions.filter(completion =>
+      matchesType('hive', ['STRING'], [completion.meta])
+    );
 
     expect(completionsWithCorrectType.length).toEqual(completions.length);
   });
@@ -62,7 +63,7 @@ describe('sqlFunctions.js', () => {
     const completionsWithCorrectType = completions.filter(completion => {
       atleastOneInt = atleastOneInt || completion.meta === 'INT';
       atleastOneString = atleastOneString || completion.meta === 'STRING';
-      return SqlFunctions.matchesType('hive', ['NUMBER'], [completion.meta]);
+      return matchesType('hive', ['NUMBER'], [completion.meta]);
     });
 
     expect(atleastOneInt).toBeTruthy();
@@ -81,7 +82,7 @@ describe('sqlFunctions.js', () => {
     const completionsWithCorrectType = completions.filter(completion => {
       atleastOneInt = atleastOneInt || completion.meta === 'INT';
       stringPresent = stringPresent || completion.meta === 'STRING';
-      return SqlFunctions.matchesType('hive', ['NUMBER'], [completion.meta]);
+      return matchesType('hive', ['NUMBER'], [completion.meta]);
     });
 
     expect(atleastOneInt).toBeTruthy();
@@ -89,47 +90,6 @@ describe('sqlFunctions.js', () => {
     expect(completionsWithCorrectType.length).toEqual(completions.length);
   });
 
-  it('should matchTypes for NUMBER', () => {
-    expect(SqlFunctions.matchesType('hive', ['NUMBER'], ['INT'])).toBeTruthy();
-    expect(SqlFunctions.matchesType('hive', ['NUMBER'], ['BIGINT'])).toBeTruthy();
-    expect(SqlFunctions.matchesType('hive', ['NUMBER'], ['DOUBLE'])).toBeTruthy();
-    expect(SqlFunctions.matchesType('hive', ['NUMBER'], ['DECIMAL'])).toBeTruthy();
-    expect(SqlFunctions.matchesType('hive', ['NUMBER'], ['T'])).toBeTruthy();
-    expect(SqlFunctions.matchesType('hive', ['NUMBER'], ['STRING'])).toBeTruthy();
-    expect(SqlFunctions.matchesType('hive', ['INT'], ['NUMBER'])).toBeTruthy();
-    expect(SqlFunctions.matchesType('hive', ['BIGINT'], ['NUMBER'])).toBeTruthy();
-    expect(SqlFunctions.matchesType('hive', ['DOUBLE'], ['NUMBER'])).toBeTruthy();
-    expect(SqlFunctions.matchesType('hive', ['DECIMAL'], ['NUMBER'])).toBeTruthy();
-
-    expect(SqlFunctions.matchesType('hive', ['STRING'], ['NUMBER'])).toBeTruthy();
-    expect(SqlFunctions.matchesType('hive', ['T'], ['NUMBER'])).toBeTruthy();
-    expect(SqlFunctions.matchesType('hive', ['NUMBER'], ['BOOLEAN'])).toBeFalsy();
-    expect(SqlFunctions.matchesType('hive', ['BOOLEAN'], ['NUMBER'])).toBeFalsy();
-  });
-
-  it('should strip precision', () => {
-    expect(SqlFunctions.matchesType('hive', ['STRING'], ['VARCHAR(10)'])).toBeTruthy();
-    expect(SqlFunctions.matchesType('hive', ['NUMBER'], ['DECIMAL(10,1)'])).toBeTruthy();
-    expect(SqlFunctions.matchesType('hive', ['T'], ['CHAR(1)'])).toBeTruthy();
-  });
-
-  it('should matchTypes for BIGINT', () => {
-    expect(SqlFunctions.matchesType('hive', ['BIGINT'], ['BIGINT'])).toBeTruthy();
-    expect(SqlFunctions.matchesType('hive', ['BIGINT'], ['INT'])).toBeTruthy();
-    expect(SqlFunctions.matchesType('hive', ['BIGINT'], ['SMALLINT'])).toBeTruthy();
-    expect(SqlFunctions.matchesType('hive', ['BIGINT'], ['TINYINT'])).toBeTruthy();
-    expect(SqlFunctions.matchesType('hive', ['BIGINT'], ['T'])).toBeTruthy();
-    expect(SqlFunctions.matchesType('hive', ['BIGINT'], ['BOOLEAN'])).toBeFalsy();
-    expect(SqlFunctions.matchesType('hive', ['BIGINT'], ['STRING'])).toBeFalsy();
-    expect(SqlFunctions.matchesType('hive', ['INT'], ['BIGINT'])).toBeFalsy();
-    expect(SqlFunctions.matchesType('hive', ['SMALLINT'], ['BIGINT'])).toBeFalsy();
-    expect(SqlFunctions.matchesType('hive', ['TINYINT'], ['BIGINT'])).toBeFalsy();
-    expect(SqlFunctions.matchesType('hive', ['DECIMAL'], ['BIGINT'])).toBeTruthy();
-    expect(SqlFunctions.matchesType('hive', ['T'], ['BIGINT'])).toBeTruthy();
-    expect(SqlFunctions.matchesType('hive', ['BOOLEAN'], ['BIGINT'])).toBeFalsy();
-    expect(SqlFunctions.matchesType('hive', ['STRING'], ['BIGINT'])).toBeTruthy();
-  });
-
   it('should give the expected argument types at a specific position', () => {
     expect(SqlFunctions.getArgumentTypes('hive', 'cos', 1)).toEqual(['DECIMAL', 'DOUBLE']);
     expect(SqlFunctions.getArgumentTypes('hive', 'cos', 2)).toEqual([]);