| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF 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. |
| */ |
| |
| package org.apache.lens.cube.parse; |
| |
| import static org.apache.lens.cube.parse.HQLParser.getString; |
| import static org.apache.lens.cube.parse.HQLParser.parseExpr; |
| import static org.apache.lens.cube.parse.HQLParser.trimHavingAst; |
| import static org.apache.lens.cube.parse.HQLParser.trimOrderByAst; |
| |
| import static org.apache.hadoop.hive.ql.parse.HiveParser.*; |
| |
| import static com.google.common.collect.Lists.newArrayList; |
| |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.HashSet; |
| import java.util.Set; |
| |
| import org.apache.lens.cube.error.LensCubeErrorCode; |
| import org.apache.lens.server.api.error.LensException; |
| |
| import org.apache.hadoop.hive.conf.HiveConf; |
| import org.apache.hadoop.hive.ql.parse.ASTNode; |
| import org.apache.hadoop.hive.ql.parse.HiveParser; |
| import org.apache.hadoop.hive.ql.parse.ParseException; |
| import org.apache.hadoop.hive.ql.session.SessionState; |
| |
| import org.testng.Assert; |
| import org.testng.annotations.DataProvider; |
| import org.testng.annotations.Test; |
| |
| import lombok.extern.slf4j.Slf4j; |
| |
| @Slf4j |
| public class TestHQLParser { |
| |
| HiveConf conf = new HiveConf(); |
| |
| { |
| conf.setBoolVar(HiveConf.ConfVars.HIVE_SUPPORT_SQL11_RESERVED_KEYWORDS, false); |
| SessionState.start(conf); |
| } |
| |
| @Test |
| public void testGroupByOrderByGetString() throws Exception { |
| String query = "SELECT a,b, sum(c) FROM tab GROUP BY a,f(b), d+e ORDER BY a, g(b), e/100"; |
| ASTNode node = HQLParser.parseHQL(query, conf); |
| |
| ASTNode groupby = HQLParser.findNodeByPath(node, TOK_INSERT, TOK_GROUPBY); |
| |
| String expected = "a, f(b), (d + e)"; |
| Assert.assertEquals(HQLParser.getString(groupby).trim(), expected); |
| |
| ASTNode orderby = HQLParser.findNodeByPath(node, TOK_INSERT, HiveParser.TOK_ORDERBY); |
| |
| String expectedOrderBy = "a asc, g(b) asc, e / 100 asc"; |
| System.out.println("###Actual order by:" + HQLParser.getString(orderby).trim()); |
| Assert.assertEquals(expectedOrderBy, HQLParser.getString(orderby).trim()); |
| } |
| |
| @Test |
| public void testLiteralCaseIsPreserved() throws Exception { |
| String literalQuery = "SELECT 'abc' AS col1, 'DEF' AS col2 FROM foo where col3='GHI' " + "AND col4 = 'JKLmno'"; |
| |
| ASTNode tree = HQLParser.parseHQL(literalQuery, conf); |
| |
| ASTNode select = HQLParser.findNodeByPath(tree, TOK_INSERT, TOK_SELECT); |
| String selectStr = HQLParser.getString(select).trim(); |
| String expectedSelect = "'abc' as `col1`, 'DEF' as `col2`"; |
| Assert.assertEquals(selectStr, expectedSelect); |
| |
| ASTNode where = HQLParser.findNodeByPath(tree, TOK_INSERT, TOK_WHERE); |
| String whereStr = HQLParser.getString(where).trim(); |
| String expectedWhere = "((col3 = 'GHI') and (col4 = 'JKLmno'))"; |
| Assert.assertEquals(whereStr, expectedWhere); |
| } |
| |
| @Test |
| public void testCaseStatementGetString() throws Exception { |
| String query = "SELECT " + "CASE (col1 * 100)/200 + 5 WHEN 'ABC' THEN 'def'WHEN 'EFG' THEN 'hij' " |
| + "ELSE 'XyZ' END AS ComplexCaseStatement FROM FOO"; |
| |
| ASTNode tree = HQLParser.parseHQL(query, conf); |
| ASTNode select = HQLParser.findNodeByPath(tree, TOK_INSERT, TOK_SELECT); |
| String selectStr = HQLParser.getString(select); |
| System.out.println("reconstructed clause "); |
| System.out.println(selectStr); |
| Assert.assertEquals(selectStr.trim(), "case (((col1 * 100) / 200) + 5) when 'ABC' then 'def' when 'EFG' " |
| + "then 'hij' else 'XyZ' end as `ComplexCaseStatement`"); |
| |
| String q2 = "SELECT " + "CASE WHEN col1 = 'abc' then 'def' when col1 = 'ghi' then 'jkl' " |
| + "else 'none' END AS Complex_Case_Statement_2" + " from FOO"; |
| |
| tree = HQLParser.parseHQL(q2, conf); |
| select = HQLParser.findNodeByPath(tree, TOK_INSERT, TOK_SELECT); |
| selectStr = HQLParser.getString(select); |
| System.out.println("reconstructed clause 2"); |
| System.out.println(selectStr); |
| |
| Assert.assertEquals(selectStr.trim(), "case when (col1 = 'abc') then 'def' when (col1 = 'ghi') then 'jkl' " |
| + "else 'none' end as `Complex_Case_Statement_2`"); |
| |
| String q3 = "SELECT " + "CASE (col1 * 100)/200 + 5 " + "WHEN 'ABC' THEN 'def' " + "WHEN 'EFG' THEN 'hij' " |
| + "END AS ComplexCaseStatement FROM FOO"; |
| |
| tree = HQLParser.parseHQL(q3, conf); |
| select = HQLParser.findNodeByPath(tree, TOK_INSERT, TOK_SELECT); |
| selectStr = HQLParser.getString(select); |
| System.out.println("reconstructed clause "); |
| System.out.println(selectStr); |
| Assert.assertEquals(selectStr.trim(), "case (((col1 * 100) / 200) + 5) when 'ABC' then 'def' when 'EFG' " |
| + "then 'hij' end as `ComplexCaseStatement`"); |
| |
| String q4 = "SELECT " + "CASE WHEN col1 = 'abc' then 'def' when col1 = 'ghi' then 'jkl' " |
| + "END AS Complex_Case_Statement_2" + " from FOO"; |
| |
| tree = HQLParser.parseHQL(q4, conf); |
| select = HQLParser.findNodeByPath(tree, TOK_INSERT, TOK_SELECT); |
| selectStr = HQLParser.getString(select); |
| System.out.println("reconstructed clause 2"); |
| System.out.println(selectStr); |
| Assert.assertEquals(selectStr.trim(), "case when (col1 = 'abc') then 'def' when (col1 = 'ghi') then 'jkl' end " |
| + "as `Complex_Case_Statement_2`"); |
| |
| } |
| |
| @Test |
| public void testIsNullCondition() throws Exception { |
| String q1 = "SELECT * FROM FOO WHERE col1 IS NULL"; |
| ASTNode where = HQLParser.findNodeByPath(HQLParser.parseHQL(q1, conf), TOK_INSERT, TOK_WHERE); |
| String whereStr = HQLParser.getString(where); |
| Assert.assertEquals(whereStr.trim(), "col1 is null"); |
| |
| String q2 = "SELECT * FROM FOO WHERE col1 IS NULL and col2 is not null"; |
| where = HQLParser.findNodeByPath(HQLParser.parseHQL(q2, conf), TOK_INSERT, TOK_WHERE); |
| whereStr = HQLParser.getString(where); |
| Assert.assertEquals(whereStr.trim(), "(col1 is null and col2 is not null)"); |
| } |
| |
| @Test |
| public void testIsNotNullCondition() throws Exception { |
| String q1 = "SELECT * FROM FOO WHERE col1 IS NOT NULL"; |
| ASTNode where = HQLParser.findNodeByPath(HQLParser.parseHQL(q1, conf), TOK_INSERT, TOK_WHERE); |
| String whereStr = HQLParser.getString(where); |
| System.out.println(whereStr); |
| Assert.assertEquals(whereStr.trim(), "col1 is not null"); |
| } |
| |
| @Test |
| public void testBetweenCondition() throws Exception { |
| String q1 = "SELECT * FROM FOO WHERE col1 BETWEEN 10 AND 100"; |
| ASTNode where = HQLParser.findNodeByPath(HQLParser.parseHQL(q1, conf), TOK_INSERT, TOK_WHERE); |
| String whereStr = HQLParser.getString(where); |
| System.out.println(whereStr); |
| Assert.assertEquals(whereStr.trim(), "col1 between 10 and 100"); |
| } |
| |
| @Test |
| public void testNotBetweenCondition() throws Exception { |
| String q1 = "SELECT * FROM FOO WHERE col1 NOT BETWEEN 10 AND 100"; |
| ASTNode where = HQLParser.findNodeByPath(HQLParser.parseHQL(q1, conf), TOK_INSERT, TOK_WHERE); |
| String whereStr = HQLParser.getString(where); |
| System.out.println(whereStr); |
| Assert.assertEquals(whereStr.trim(), "col1 not between 10 and 100"); |
| } |
| |
| @Test |
| public void testBinaryOperators() throws Exception { |
| String q1 = "SELECT * FROM FOO WHERE " + "(A <=> 10) AND (B & C = 10) AND (D | E = 10) " |
| + "AND (F ^ G = 10) AND (H % 2 = 1) AND (~I = 10)" + "AND (!J) AND (NOT K) AND TRUE AND FALSE"; |
| |
| ASTNode where = HQLParser.findNodeByPath(HQLParser.parseHQL(q1, conf), TOK_INSERT, TOK_WHERE); |
| String whereStr = HQLParser.getString(where); |
| |
| String expected = "((a <=> 10) and ((b & c) = 10) and ((d | e) = 10) and ((f ^ g) = 10) and " |
| + "((h % 2) = 1) and ( ~i = 10) and not j and not k and true and false )"; |
| Assert.assertEquals(whereStr.trim(), expected); |
| } |
| |
| @Test |
| public void testCompelxTypeOperators() throws Exception { |
| String q1 = "SELECT A[2], B['key'], C.D FROM FOO"; |
| |
| ASTNode select = HQLParser.findNodeByPath(HQLParser.parseHQL(q1, conf), TOK_INSERT, TOK_SELECT); |
| String selectStr = HQLParser.getString(select); |
| System.out.println(selectStr); |
| Assert.assertEquals(selectStr.trim(), "a[2], b['key'], (c.d)"); |
| } |
| |
| @Test |
| public void testInAndNotInOperator() throws Exception { |
| String q1 = "SELECT * FROM FOO WHERE A IN ('B', 'C', 'D', 'E', 'F')"; |
| ASTNode where = HQLParser.findNodeByPath(HQLParser.parseHQL(q1, conf), TOK_INSERT, TOK_WHERE); |
| String whereStr = HQLParser.getString(where); |
| System.out.println(whereStr); |
| Assert.assertEquals(whereStr.trim(), "a in ('B' , 'C' , 'D' , 'E' , 'F')"); |
| |
| q1 = "SELECT * FROM FOO WHERE A NOT IN ('B', 'C', 'D', 'E', 'F')"; |
| where = HQLParser.findNodeByPath(HQLParser.parseHQL(q1, conf), TOK_INSERT, TOK_WHERE); |
| whereStr = HQLParser.getString(where); |
| System.out.println(whereStr); |
| Assert.assertEquals(whereStr.trim(), "a not in ('B' , 'C' , 'D' , 'E' , 'F')"); |
| } |
| |
| @Test |
| public void testLiteralWithSpaces() throws Exception { |
| String q1 = "SELECT * FROM FOO WHERE A IN ('B X', 'C Y', 'D Z', 'E', 'F')"; |
| ASTNode where = HQLParser.findNodeByPath(HQLParser.parseHQL(q1, conf), TOK_INSERT, TOK_WHERE); |
| String whereStr = HQLParser.getString(where); |
| System.out.println(whereStr); |
| System.out.println("HQLParser.parseHQL(q1, conf)" + HQLParser.parseHQL(q1, conf).dump()); |
| System.out.println("where dump:" + where.dump()); |
| Assert.assertEquals(whereStr.trim(), "a in ('B X' , 'C Y' , 'D Z' , 'E' , 'F')"); |
| } |
| |
| @Test |
| public void testOrderbyBrackets() throws Exception { |
| String query = "SELECT id from citytable order by (citytable.id) asc"; |
| // String hql = rewrite(driver, query); |
| ASTNode tree = HQLParser.parseHQL(query, conf); |
| ASTNode orderByTree = HQLParser.findNodeByPath(tree, TOK_INSERT, HiveParser.TOK_ORDERBY); |
| String reconstructed = HQLParser.getString(orderByTree); |
| System.out.println("RECONSTRUCTED0:" + reconstructed); |
| Assert.assertEquals(reconstructed, "citytable.id asc"); |
| String query3 = "SELECT id, name from citytable order by citytable.id asc, citytable.name desc"; |
| tree = HQLParser.parseHQL(query3, conf); |
| orderByTree = HQLParser.findNodeByPath(tree, TOK_INSERT, HiveParser.TOK_ORDERBY); |
| reconstructed = HQLParser.getString(orderByTree); |
| System.out.println("RECONSTRUCTED2:" + reconstructed); |
| Assert.assertEquals(reconstructed, "citytable.id asc, citytable.name desc"); |
| } |
| |
| @Test |
| public void testInnerJoin() throws Exception { |
| String query |
| = "select tab1.a, tab2.b from table1 tab1 inner join table tab2 on tab1.id = tab2.id where tab1.a > 123"; |
| ASTNode node = HQLParser.parseHQL(query, conf); |
| ASTNode temp = HQLParser.findNodeByPath(node, TOK_FROM, TOK_JOIN); |
| String expected = "table1tab1tabletab2((tab1.id) = (tab2.id))"; |
| Assert.assertEquals(HQLParser.getString(temp), expected); |
| } |
| |
| @Test |
| public void testAliasWithSpaces() throws Exception { |
| String query = "select id as `an id` from sample_dim"; |
| try { |
| ASTNode tree = HQLParser.parseHQL(query, conf); |
| Assert.assertNotNull(tree); |
| } catch (NullPointerException exc) { |
| log.error("should not have thrown npe", exc); |
| Assert.fail("should not have thrown npe"); |
| } |
| } |
| |
| @Test |
| public void testAliasShouldBeQuoted() throws Exception { |
| Assert.assertEquals(getSelectStrForQuery("select id as identity from sample_dim"), "id as `identity`"); |
| Assert.assertEquals(getSelectStrForQuery("select id as `column identity` from sample_dim"), |
| "id as `column identity`"); |
| Assert.assertEquals(getSelectStrForQuery("select id identity from sample_dim"), "id as `identity`"); |
| Assert.assertEquals(getSelectStrForQuery("select id `column identity` from sample_dim"), |
| "id as `column identity`"); |
| } |
| |
| private String getSelectStrForQuery(String query) throws Exception { |
| ASTNode tree = HQLParser.parseHQL(query, conf); |
| ASTNode select = HQLParser.findNodeByPath(tree, TOK_INSERT, TOK_SELECT); |
| return HQLParser.getString(select).trim(); |
| } |
| |
| @Test |
| public void testAllColumns() throws Exception { |
| String query = "select * from tab"; |
| ASTNode select = HQLParser.findNodeByPath(HQLParser.parseHQL(query, conf), TOK_INSERT, TOK_SELECT); |
| String selectStr = HQLParser.getString(select); |
| System.out.println(selectStr); |
| Assert.assertEquals(selectStr, "*"); |
| |
| query = "select tab.*, tab2.a, tab2.b from tab"; |
| ASTNode ast = HQLParser.parseHQL(query, conf); |
| select = HQLParser.findNodeByPath(ast, TOK_INSERT, TOK_SELECT); |
| selectStr = HQLParser.getString(select); |
| System.out.println(selectStr); |
| Assert.assertEquals(selectStr, "tab.*, (tab2.a), (tab2.b)"); |
| |
| query = "select count(*) from tab"; |
| ast = HQLParser.parseHQL(query, conf); |
| select = HQLParser.findNodeByPath(ast, TOK_INSERT, TOK_SELECT); |
| selectStr = HQLParser.getString(select); |
| System.out.println(selectStr); |
| Assert.assertEquals("count(*)", selectStr); |
| |
| query = "select count(tab.*) from tab"; |
| ast = HQLParser.parseHQL(query, conf); |
| select = HQLParser.findNodeByPath(ast, TOK_INSERT, TOK_SELECT); |
| selectStr = HQLParser.getString(select); |
| System.out.println(selectStr); |
| Assert.assertEquals("count(tab.*)", selectStr); |
| } |
| |
| @Test |
| public void testNegativeLiteral() throws Exception { |
| String query1 = "select 2-1 as col1,col2 from table1"; |
| ASTNode tree = HQLParser.parseHQL(query1, conf); |
| ASTNode selectAST = HQLParser.findNodeByPath(tree, TOK_INSERT, TOK_SELECT); |
| HQLParser.printAST(selectAST); |
| String genQuery = HQLParser.getString(selectAST); |
| System.out.println("genQuery1: " + genQuery); |
| |
| String query2 = "select -1 as col1,col2 from table1"; |
| tree = HQLParser.parseHQL(query2, conf); |
| selectAST = HQLParser.findNodeByPath(tree, TOK_INSERT, TOK_SELECT); |
| HQLParser.printAST(selectAST); |
| String genQuery2 = HQLParser.getString(selectAST); |
| System.out.println("genQuery2: " + genQuery2); |
| |
| Assert.assertFalse(genQuery2.contains("1 -")); |
| Assert.assertTrue(genQuery2.contains("-1")); |
| |
| // Validate returned string is parseable |
| HQLParser.printAST(HQLParser.findNodeByPath(HQLParser.parseHQL("SELECT " + genQuery2 + " FROM table1", conf), |
| TOK_INSERT, |
| TOK_SELECT)); |
| } |
| |
| @Test |
| public void testEqualsAST() throws Exception { |
| ASTNode expr1 = parseExpr("T1.a + T2.b - T2.c"); |
| ASTNode expr2 = parseExpr("t1.A + t2.B - t2.C"); |
| |
| Assert.assertTrue(HQLParser.equalsAST(expr1, expr2)); |
| |
| ASTNode literalExpr1 = parseExpr("A = 'FooBar'"); |
| ASTNode literalExpr2 = parseExpr("a = 'FooBar'"); |
| Assert.assertTrue(HQLParser.equalsAST(literalExpr1, literalExpr2)); |
| |
| ASTNode literalExpr3 = parseExpr("A = 'fOObAR'"); |
| Assert.assertFalse(HQLParser.equalsAST(literalExpr1, literalExpr3)); |
| |
| ASTNode literalExpr4 = parseExpr("A <> 'FooBar'"); |
| Assert.assertFalse(HQLParser.equalsAST(literalExpr1, literalExpr4)); |
| } |
| |
| @Test |
| public void testCastStatement() throws ParseException, LensException { |
| String castSelect = "cast(( a + b ) as tinyint), cast(( a + b ) as smallint), cast(( a + b ) as int)," |
| + " cast(( a + b ) as bigint), cast(( a + b ) as float), cast(( a + b ) as double)," |
| + " cast(( a + b ) as boolean), cast( a as date), cast( b as datetime), cast( a as timestamp)," |
| + " cast(( a + b ) as string), cast(( a + b ) as binary), cast(( a + b ) as decimal(3,6))," |
| + " cast(( a + b ) as decimal(5)), cast(( a + b ) as varchar(10)), cast(( a + b ) as char(20))," |
| + " cast( '17.29' as decimal(4,2))"; |
| castSelect = "3.1415926BD"; |
| String query = "select " + castSelect + " from table limit 1"; |
| ASTNode tree = HQLParser.parseHQL(query, conf); |
| System.out.println(tree.dump()); |
| ASTNode selectAST = HQLParser.findNodeByPath(tree, TOK_INSERT, TOK_SELECT); |
| String genQuery = HQLParser.getString(selectAST); |
| Assert.assertEquals(genQuery, castSelect); |
| } |
| |
| @Test |
| public void testOtherStatements() throws ParseException, LensException { |
| String select = "3.1415926BD"; |
| String query = "select " + select + " from table limit 1"; |
| ASTNode tree = HQLParser.parseHQL(query, conf); |
| ASTNode selectAST = HQLParser.findNodeByPath(tree, TOK_INSERT, TOK_SELECT); |
| String genQuery = HQLParser.getString(selectAST); |
| Assert.assertEquals(genQuery, select); |
| } |
| |
| @DataProvider |
| public Object[][] nAryFlatteningDataProvider() { |
| return new Object[][]{ |
| {"a", "a"}, |
| {"a or b", "a or b"}, |
| {"a or b or c or d", "a or b or c or d"}, |
| {"a and b and c and d", "a and b and c and d"}, |
| {"a and (b or c)", "a and (b or c)"}, |
| {"a and (b or c or d) and (e or f) and (g and h)", "a and (b or c or d) and (e or f) and g and h"}, |
| // ambiguous, but uniquely understood, and > or. |
| {"a and b or c or d and e or f and g and h", "(a and b) or c or (d and e) or (f and g and h)"}, |
| }; |
| } |
| |
| @Test(dataProvider = "nAryFlatteningDataProvider") |
| public void testNAryOperatorFlattening(String input, String expected) throws LensException { |
| ASTNode tree = parseExpr(input); |
| String infixString = HQLParser.getString(tree); |
| Assert.assertEquals(infixString, expected); |
| } |
| |
| @DataProvider |
| public Object[][] colsInExpr() { |
| return new Object[][]{ |
| {" t1.c1", new String[]{}}, // simple selection |
| {" cie.c5", new String[]{"c5"}}, // simple selection |
| {" fun1(cie.c4)", new String[]{"c4"}}, // simple selection |
| {" t1.c1 + cie.c5+ t2.c3", new String[]{"c5"}}, // simple selection |
| {" t1.c1=x and cie.c2=y", new String[]{"c2"}}, //filter expression |
| {"case when t1.c1 then 1 when cie.c3 then 2 when cie.c4 then 3 when t2.c2 then 4 else cie.c6 end", |
| new String[]{"c3", "c4", "c6", }, }, // case when statement |
| {"complexfunc(round(t1.c1), myfunc(t2.c2), myfunc2(cie.c4, cie.c5, t2.c6))", new String[]{"c4", "c5"}}, |
| }; |
| } |
| |
| @Test(dataProvider = "colsInExpr") |
| public void testColsInExpr(String input, String[] expected) throws Exception { |
| String tableAlias = "cie"; |
| ASTNode inputAST = parseExpr(input); |
| Set<String> actual = HQLParser.getColsInExpr(tableAlias, inputAST); |
| Set<String> expectedSet = new HashSet<>(Arrays.asList(expected)); |
| Assert.assertEquals(actual, expectedSet, "Received " + actual + " for input:" + input); |
| } |
| |
| @Test |
| public void testGetDotAST() { |
| Assert.assertEquals(HQLParser.getString(HQLParser.getDotAST("tbl1", "col1")), "(tbl1.col1)"); |
| } |
| |
| @DataProvider |
| public Object[][] primitiveBool() { |
| return new Object[][]{ |
| {" t1.c1", false}, |
| {" t1.c1 = 24", true}, |
| {" t1.c1 >= 24", true}, |
| {" t1.c1 <= 24", true}, |
| {" t1.c1 <=> 24", true}, |
| {" t1.c1 != 24", true}, |
| {" t1.c1 < 24", true}, |
| {" t1.c1 > 24", true}, |
| {" fun1(cie.c4)", false}, |
| {" arraycontains(arr1, v1)", false}, |
| {" t1.c1=x and cie.c2=y", false}, |
| {" t1.col1 in ('x', 'y', 'z')", false}, |
| }; |
| } |
| |
| @Test(dataProvider = "primitiveBool") |
| public void testIsPrimitiveBooleanExpr(String input, boolean expected) throws Exception { |
| ASTNode inputAST = parseExpr(input); |
| boolean actual = HQLParser.isPrimitiveBooleanExpression(inputAST); |
| Assert.assertEquals(actual, expected, "Received " + actual + " for input:" + input + ":" + inputAST.dump()); |
| } |
| |
| @DataProvider |
| public Object[][] primitiveBoolFunc() { |
| return new Object[][]{ |
| {" t1.c1", false}, |
| {" t1.c1 = 24", false}, |
| {" t1.c1 >= 24", false}, |
| {" t1.c1 <= 24", false}, |
| {" t1.c1 <=> 24", false}, |
| {" t1.c1 != 24", false}, |
| {" t1.c1 < 24", false}, |
| {" t1.c1 > 24", false}, |
| {" fun1(cie.c4)", false}, |
| {" arraycontains(arr1, v1)", false}, |
| {" t1.c1=x and cie.c2=y", false}, |
| {" t1.col1 in ('x', 'y', 'z')", true}, |
| }; |
| } |
| |
| @Test(dataProvider = "primitiveBoolFunc") |
| public void testIsPrimitiveBooleanFunction(String input, boolean expected) throws Exception { |
| ASTNode inputAST = parseExpr(input); |
| boolean actual = HQLParser.isPrimitiveBooleanFunction(inputAST); |
| Assert.assertEquals(actual, expected, "Received " + actual + " for input:" + input); |
| } |
| |
| @DataProvider |
| public Object[][] dirDataProvider() { |
| return new Object[][]{ |
| {"directory 'a'"}, |
| {"local directory 'a'"}, |
| }; |
| } |
| |
| @Test(dataProvider = "dirDataProvider") |
| public void testLocalDirectory(String dirString) throws LensException { |
| String expr = "insert overwrite " + dirString + " select * from table"; |
| ASTNode tree = HQLParser.parseHQL(expr, conf); |
| Assert.assertEquals(HQLParser.getString((ASTNode) tree.getChild(1).getChild(0)), dirString); |
| } |
| |
| @DataProvider |
| public Object[][] exprDataProvider() { |
| return new Object[][] { |
| {"a.b", null, true}, |
| {"a.date", null, false}, |
| {"a.date", conf, true}, |
| }; |
| } |
| |
| @Test(dataProvider = "exprDataProvider") |
| public void testParseExpr(String expr, HiveConf conf, boolean success) { |
| try { |
| parseExpr(expr, conf); |
| Assert.assertTrue(success); |
| } catch (LensException e) { |
| Assert.assertFalse(success); |
| Assert.assertTrue(e.getMessage().contains(expr)); |
| Assert.assertTrue(e.getMessage().contains(LensCubeErrorCode.COULD_NOT_PARSE_EXPRESSION.name())); |
| } |
| } |
| @DataProvider |
| public Object[][] havingTrimDataProvider() { |
| return new Object[][] { |
| {"((sum((testcube.segmsr1)) > 1) and (sum((testcube.msr2)) > 2))", newArrayList("segmsr1"), |
| "(sum((testcube.segmsr1)) > 1)", }, |
| {"(sum((testcube.msr2)) > 2)", newArrayList("segmsr1"), null, }, |
| {"(sum((testcube.segmsr1)) > 1)", newArrayList("segmsr1"), "(sum((testcube.segmsr1)) > 1)", }, |
| }; |
| } |
| |
| @Test(dataProvider = "havingTrimDataProvider") |
| public void testHavingTrim(String expr, Collection<String> columns, String expected) throws LensException { |
| ASTNode actualAst = trimHavingAst(parseExpr(expr), columns); |
| ASTNode expectedAst = expected == null ? null : parseExpr(expected); |
| if (!HQLParser.equalsAST(actualAst, expectedAst)) { |
| Assert.assertEquals(getString(actualAst), expected); |
| } |
| } |
| @DataProvider |
| public Object[][] orderByTrimDataProvider() { |
| return new Object[][] { |
| {"testcube.segmsr1 asc", newArrayList("segmsr1"), "testcube.segmsr1 asc", }, |
| {"testcube.segmsr1 desc, testcube.msr2", newArrayList("segmsr1"), "testcube.segmsr1 desc", }, |
| {"testcube.segmsr1, testcube.msr2 desc", newArrayList("segmsr1"), "testcube.segmsr1 asc", }, |
| {"testcube.msr2 desc", newArrayList("segmsr1"), "", }, |
| }; |
| } |
| |
| @Test(dataProvider = "orderByTrimDataProvider") |
| public void testOrderByTrim(String expr, Collection<String> columns, String expected) throws LensException { |
| String query = "select * from testcube order by " + expr; |
| ASTNode queryAst = HQLParser.parseHQL(query, conf); |
| ASTNode orderByAST = HQLParser.findNodeByPath(queryAst, TOK_INSERT, TOK_ORDERBY); |
| ASTNode actualAst = trimOrderByAst(orderByAST, columns); |
| Assert.assertEquals(getString(actualAst), expected); |
| } |
| } |