// 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 { TypeConversion } from '../../sql/reference/types'; import { TYPE_CONVERSION as GENERIC_TYPE_CONVERSION } from './generic/typeConversion'; import { TYPE_CONVERSION as HIVE_TYPE_CONVERSION } from './hive/typeConversion'; import { TYPE_CONVERSION as IMPALA_TYPE_CONVERSION } from './impala/typeConversion'; import { TYPE_CONVERSION as SPARKSQL_TYPE_CONVERSION } from './sparksql/typeConversion'; const stripPrecision = (types: string[]): string[] => { const result: string[] = []; types.forEach(type => { if (type.includes('(')) { result.push(type.substring(0, type.indexOf('('))); } else { result.push(type); } }); return result; }; const getTypeConversion = (dialect: string): TypeConversion => { switch (dialect) { case 'hive': return HIVE_TYPE_CONVERSION; case 'impala': return IMPALA_TYPE_CONVERSION; case 'sparksql': return SPARKSQL_TYPE_CONVERSION; default: 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. */ export const matchesType = ( dialect: string, expectedTypes: string[], actualRawTypes: string[] ): boolean => { if (expectedTypes.length === 1 && expectedTypes[0] === 'T') { return true; } const actualTypes = stripPrecision(actualRawTypes); if (['ARRAY', 'MAP', 'STRUCT'].some(type => actualTypes.includes(type))) { 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; };