// 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 { UdfArgument } from '../../sql/reference/types'; import { Connector } from '../../config/types'; import { getArgumentDetailsForUdf } from './sqlUdfRepository'; import sqlReferenceRepository from './sqlReferenceRepository'; import * as apiUtils from '../../sql/reference/apiUtils'; describe('sqlUdfRepository.ts', () => { const createTestConnector = (dialect: string, id: string): Connector => ({ dialect: dialect, id: id, buttonName: '', displayName: '', page: '', tooltip: '', type: '' }); const hiveConn: Connector = createTestConnector('hive', 'hive'); const impalaConn = createTestConnector('impala', 'impala'); jest.mock('sql/reference/impala/udfReference', () => ({ UDF_CATEGORIES: [ { functions: { cos: { returnTypes: ['DOUBLE'], arguments: [[{ type: 'DOUBLE' }]], signature: 'cos(DOUBLE a)', draggable: 'cos()', description: '' }, concat: { returnTypes: ['STRING'], arguments: [[{ type: 'STRING' }], [{ type: 'STRING', multiple: true }]], signature: 'concat(STRING a, STRING b...)', draggable: 'concat()', description: '' }, strleft: { returnTypes: ['STRING'], arguments: [[{ type: 'STRING' }], [{ type: 'INT' }]], signature: 'strleft(STRING a, INT num_chars)', draggable: 'strleft()', description: '' } } } ] })); jest.mock('sql/reference/hive/udfReference', () => ({ UDF_CATEGORIES: [ { functions: { cos: { returnTypes: ['DOUBLE'], arguments: [[{ type: 'DECIMAL' }, { type: 'DOUBLE' }]], signature: 'cos(DECIMAL|DOUBLE a)', draggable: 'cos()', description: '' }, concat: { returnTypes: ['STRING'], arguments: [ [ { type: 'STRING', multiple: true }, { type: 'BINARY', multiple: true } ] ], signature: 'concat(STRING|BINARY a, STRING|BINARY b...)', draggable: 'concat()', description: '' }, reflect: { returnTypes: ['T'], arguments: [ [{ type: 'STRING' }], [{ type: 'STRING' }], [{ type: 'T', multiple: true, optional: true }] ], signature: 'reflect(class, method[, arg1[, arg2..]])', draggable: 'reflect()', description: '' } } } ] })); jest.spyOn(apiUtils, 'fetchUdfs').mockImplementation(() => Promise.resolve([])); const extractType = (details: UdfArgument): string => details.type; it('should give the expected argument types at a specific position', async () => { expect( (await getArgumentDetailsForUdf(sqlReferenceRepository, hiveConn, 'cos', 1)).map(extractType) ).toEqual(['DECIMAL', 'DOUBLE']); expect( (await getArgumentDetailsForUdf(sqlReferenceRepository, hiveConn, 'cos', 2)).map(extractType) ).toEqual([]); expect( (await getArgumentDetailsForUdf(sqlReferenceRepository, impalaConn, 'cos', 1)).map( extractType ) ).toEqual(['DOUBLE']); expect( (await getArgumentDetailsForUdf(sqlReferenceRepository, impalaConn, 'cos', 2)).map( extractType ) ).toEqual([]); expect( (await getArgumentDetailsForUdf(sqlReferenceRepository, hiveConn, 'concat', 10)).map( extractType ) ).toEqual(['STRING', 'BINARY']); expect( (await getArgumentDetailsForUdf(sqlReferenceRepository, impalaConn, 'concat', 10)).map( extractType ) ).toEqual(['STRING']); }); it('should handle functions with different type of arguments', async () => { expect( (await getArgumentDetailsForUdf(sqlReferenceRepository, hiveConn, 'reflect', 1)).map( extractType ) ).toEqual(['STRING']); expect( (await getArgumentDetailsForUdf(sqlReferenceRepository, hiveConn, 'reflect', 2)).map( extractType ) ).toEqual(['STRING']); expect( (await getArgumentDetailsForUdf(sqlReferenceRepository, hiveConn, 'reflect', 3)).map( extractType ) ).toEqual(['T']); expect( (await getArgumentDetailsForUdf(sqlReferenceRepository, hiveConn, 'reflect', 200)).map( extractType ) ).toEqual(['T']); }); it('should handle functions with an infinite amount of arguments', async () => { expect( (await getArgumentDetailsForUdf(sqlReferenceRepository, impalaConn, 'greatest', 1)).map( extractType ) ).toEqual(['T']); expect( (await getArgumentDetailsForUdf(sqlReferenceRepository, impalaConn, 'greatest', 200)).map( extractType ) ).toEqual(['T']); expect( (await getArgumentDetailsForUdf(sqlReferenceRepository, hiveConn, 'strleft', 1)).map( extractType ) ).toEqual(['T']); expect( (await getArgumentDetailsForUdf(sqlReferenceRepository, hiveConn, 'strleft', 2)).map( extractType ) ).toEqual(['T']); expect( (await getArgumentDetailsForUdf(sqlReferenceRepository, hiveConn, 'strleft', 3)).map( extractType ) ).toEqual(['T']); expect( (await getArgumentDetailsForUdf(sqlReferenceRepository, hiveConn, 'strleft', 200)).map( extractType ) ).toEqual(['T']); }); it('should not return types for arguments out of bounds', async () => { expect( (await getArgumentDetailsForUdf(sqlReferenceRepository, impalaConn, 'strleft', 1)).map( extractType ) ).toEqual(['STRING']); expect( (await getArgumentDetailsForUdf(sqlReferenceRepository, impalaConn, 'strleft', 2)).map( extractType ) ).toEqual(['INT']); expect( (await getArgumentDetailsForUdf(sqlReferenceRepository, impalaConn, 'strleft', 3)).map( extractType ) ).toEqual([]); expect( (await getArgumentDetailsForUdf(sqlReferenceRepository, impalaConn, 'strleft', 200)).map( extractType ) ).toEqual([]); }); it("should return T for any argument if the udf isn't found", async () => { expect( (await getArgumentDetailsForUdf(sqlReferenceRepository, hiveConn, 'blabla', 2)).map( extractType ) ).toEqual(['T']); expect( (await getArgumentDetailsForUdf(sqlReferenceRepository, hiveConn, 'blabla', 200)).map( extractType ) ).toEqual(['T']); expect( (await getArgumentDetailsForUdf(sqlReferenceRepository, impalaConn, 'blabla', 2)).map( extractType ) ).toEqual(['T']); expect( (await getArgumentDetailsForUdf(sqlReferenceRepository, impalaConn, 'blabla', 200)).map( extractType ) ).toEqual(['T']); }); });