blob: 57d28f3227ab4a36134084b772e0dad73ee9aa2f [file] [log] [blame]
/**
* 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);
}
}