/**
* 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.hadoop.hive.ql.parse;
import java.io.IOException;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.hive.ql.Context;
import org.apache.hadoop.hive.ql.session.SessionState;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
/**
* various Parser tests for INSERT/UPDATE/DELETE
*/
public class TestIUD {
private static HiveConf conf;
private ParseDriver pd;
@BeforeClass
public static void initialize() {
conf = new HiveConf(SemanticAnalyzer.class);
SessionState.start(conf);
}
@Before
public void setup() throws SemanticException, IOException {
pd = new ParseDriver();
}
ASTNode parse(String query) throws ParseException {
return parse(query, pd, conf);
}
static ASTNode parse(String query, ParseDriver pd, HiveConf conf) throws ParseException {
ASTNode nd = null;
try {
nd = pd.parse(query, new Context(conf));
} catch (IOException e) {
e.printStackTrace();
}
return (ASTNode) nd.getChild(0);
}
@Test
public void testDeleteNoWhere() throws ParseException {
ASTNode ast = parse("DELETE FROM src");
Assert.assertEquals("AST doesn't match",
"(tok_delete_from " +
"(tok_tabname src))", ast.toStringTree());
}
@Test
public void testDeleteWithWhere() throws ParseException {
ASTNode ast = parse("DELETE FROM src WHERE key IS NOT NULL AND src.value < 0");
Assert.assertEquals("AST doesn't match",
"(tok_delete_from " +
"(tok_tabname src) " +
"(tok_where " +
"(and " +
"(tok_function isnotnull (tok_table_or_col key)) " +
"(< (. (tok_table_or_col src) value) 0))))",
ast.toStringTree());
}
@Test
public void testUpdateNoWhereSingleSet() throws ParseException {
ASTNode ast = parse("UPDATE src set key = 3");
Assert.assertEquals("AST doesn't match",
"(tok_update_table " +
"(tok_tabname src) " +
"(tok_set_columns_clause " +
"(= " +
"(tok_table_or_col key) 3)))",
ast.toStringTree());
}
@Test
public void testUpdateNoWhereMultiSet() throws ParseException {
ASTNode ast = parse("UPDATE src set key = 3, value = 8");
Assert.assertEquals("AST doesn't match",
"(tok_update_table " +
"(tok_tabname src) " +
"(tok_set_columns_clause " +
"(= " +
"(tok_table_or_col key) 3) " +
"(= " +
"(tok_table_or_col value) 8)))",
ast.toStringTree());
}
@Test
public void testUpdateWithWhereSingleSet() throws ParseException {
ASTNode ast = parse("UPDATE src SET key = 3 WHERE value IS NULL");
Assert.assertEquals("AST doesn't match",
"(tok_update_table " +
"(tok_tabname src) " +
"(tok_set_columns_clause " +
"(= " +
"(tok_table_or_col key) 3)) " +
"(tok_where (tok_function isnull (tok_table_or_col value))))",
ast.toStringTree());
}
@Test
public void testUpdateWithWhereSingleSetExpr() throws ParseException {
ASTNode ast = parse("UPDATE src SET key = -3+(5*9)%8, val = cast(6.1 + c as INT), d = d - 1 WHERE value IS NULL");
Assert.assertEquals("AST doesn't match",
"(tok_update_table (tok_tabname src) " +
"(tok_set_columns_clause " +
"(= (tok_table_or_col key) (+ (- 3) (% (* 5 9) 8))) " +
"(= (tok_table_or_col val) (tok_function tok_int (+ 6.1 (tok_table_or_col c)))) " +
"(= (tok_table_or_col d) (- (tok_table_or_col d) 1))) " +
"(tok_where (tok_function isnull (tok_table_or_col value))))",
ast.toStringTree());
}
@Test
public void testUpdateWithWhereMultiSet() throws ParseException {
ASTNode ast = parse("UPDATE src SET key = 3, value = 8 WHERE VALUE = 1230997");
Assert.assertEquals("AST doesn't match",
"(tok_update_table " +
"(tok_tabname src) " +
"(tok_set_columns_clause " +
"(= " +
"(tok_table_or_col key) 3) " +
"(= " +
"(tok_table_or_col value) 8)) " +
"(tok_where (= (tok_table_or_col value) 1230997)))",
ast.toStringTree());
}
@Test
public void testStandardInsertIntoTable() throws ParseException {
ASTNode ast = parse("INSERT into TABLE page_view SELECT pvs.viewTime, pvs.userid from page_view_stg pvs where pvs.userid is null");
Assert.assertEquals("AST doesn't match",
"(tok_query " +
"(tok_from " +
"(tok_tabref (tok_tabname page_view_stg) pvs)) " +
"(tok_insert (tok_insert_into (tok_tab (tok_tabname page_view))) " +
"(tok_select " +
"(tok_selexpr (. (tok_table_or_col pvs) viewtime)) " +
"(tok_selexpr (. (tok_table_or_col pvs) userid))) " +
"(tok_where (tok_function isnull (. (tok_table_or_col pvs) userid)))))",
ast.toStringTree());
}
@Test
public void testSelectStarFromAnonymousVirtTable1Row() throws ParseException {
try {
parse("select * from `values` (3,4)");
Assert.assertFalse("Expected ParseException", true);
}
catch(ParseException ex) {
Assert.assertEquals("Failure didn't match.",
"line 1:24 cannot recognize input near 'values' '(' '3' in joinSource",
ex.getMessage());
}
}
@Test
public void testSelectStarFromVirtTable1Row() throws ParseException {
ASTNode ast = parse("select * from (values (3,4)) as vc(a,b)");
Assert.assertEquals("AST doesn't match",
"(tok_query " +
"(tok_from " +
"(tok_virtual_table " +
"(tok_virtual_tabref (tok_tabname vc) (tok_col_name a b)) " +
"(tok_values_table (tok_value_row 3 4)))) " +
"(tok_insert (tok_destination (tok_dir tok_tmp_file)) (tok_select (tok_selexpr tok_allcolref))))",
ast.toStringTree());
}
@Test
public void testSelectStarFromVirtTable2Row() throws ParseException {
ASTNode ast = parse("select * from (values (1,2),(3,4)) as vc(a,b)");
Assert.assertEquals("AST doesn't match",
"(tok_query " +
"(tok_from " +
"(tok_virtual_table " +
"(tok_virtual_tabref (tok_tabname vc) (tok_col_name a b)) " +
"(tok_values_table (tok_value_row 1 2) (tok_value_row 3 4)))) " +
"(tok_insert (tok_destination (tok_dir tok_tmp_file)) (tok_select (tok_selexpr tok_allcolref))))",
ast.toStringTree());
}
@Test
public void testSelectStarFromVirtTable2RowNamedProjections() throws ParseException {
ASTNode ast = parse("select a as c, b as d from (values (1,2),(3,4)) as vc(a,b)");
Assert.assertEquals("AST doesn't match",
"(tok_query " +
"(tok_from " +
"(tok_virtual_table " +
"(tok_virtual_tabref (tok_tabname vc) (tok_col_name a b)) " +
"(tok_values_table (tok_value_row 1 2) (tok_value_row 3 4)))) " +
"(tok_insert (tok_destination (tok_dir tok_tmp_file)) " +
"(tok_select (tok_selexpr (tok_table_or_col a) c) (tok_selexpr (tok_table_or_col b) d))))",
ast.toStringTree());
}
@Test
public void testInsertIntoTableAsSelectFromNamedVirtTable() throws ParseException {
ASTNode ast = parse("insert into page_view select a,b as c from (values (1,2),(3,4)) as vc(a,b) where b = 9");
Assert.assertEquals("AST doesn't match",
"(tok_query " +
"(tok_from " +
"(tok_virtual_table " +
"(tok_virtual_tabref (tok_tabname vc) (tok_col_name a b)) " +
"(tok_values_table (tok_value_row 1 2) (tok_value_row 3 4)))) " +
"(tok_insert (tok_insert_into (tok_tab (tok_tabname page_view))) " +
"(tok_select " +
"(tok_selexpr (tok_table_or_col a)) " +
"(tok_selexpr (tok_table_or_col b) c)) " +
"(tok_where (= (tok_table_or_col b) 9))))",
ast.toStringTree());
}
/**
* same as testInsertIntoTableAsSelectFromNamedVirtTable but with column list on target table
* @throws ParseException
*/
@Test
public void testInsertIntoTableAsSelectFromNamedVirtTableNamedCol() throws ParseException {
ASTNode ast = parse("insert into page_view(c1,c2) select a,b as c from (values (1,2),(3,4)) as vc(a,b) where b = 9");
Assert.assertEquals("AST doesn't match",
"(tok_query " +
"(tok_from " +
"(tok_virtual_table " +
"(tok_virtual_tabref (tok_tabname vc) (tok_col_name a b)) " +
"(tok_values_table (tok_value_row 1 2) (tok_value_row 3 4)))) " +
"(tok_insert (tok_insert_into (tok_tab (tok_tabname page_view)) (tok_tabcolname c1 c2)) " +
"(tok_select " +
"(tok_selexpr (tok_table_or_col a)) " +
"(tok_selexpr (tok_table_or_col b) c)) " +
"(tok_where (= (tok_table_or_col b) 9))))",
ast.toStringTree());
}
@Test
public void testInsertIntoTableFromAnonymousTable1Row() throws ParseException {
ASTNode ast = parse("insert into page_view values(1,2)");
Assert.assertEquals("AST doesn't match",
"(tok_query " +
"(tok_from " +
"(tok_virtual_table " +
"(tok_virtual_tabref tok_anonymous) " +
"(tok_values_table (tok_value_row 1 2)))) " +
"(tok_insert (tok_insert_into (tok_tab (tok_tabname page_view))) " +
"(tok_select (tok_selexpr tok_allcolref))))",
ast.toStringTree());
}
/**
* Same as testInsertIntoTableFromAnonymousTable1Row but with column list on target table
* @throws ParseException
*/
@Test
public void testInsertIntoTableFromAnonymousTable1RowNamedCol() throws ParseException {
ASTNode ast = parse("insert into page_view(a,b) values(1,2)");
Assert.assertEquals("AST doesn't match",
"(tok_query " +
"(tok_from " +
"(tok_virtual_table " +
"(tok_virtual_tabref tok_anonymous) " +
"(tok_values_table (tok_value_row 1 2))" +
")" +
") " +
"(tok_insert " +
"(tok_insert_into " +
"(tok_tab (tok_tabname page_view)) " +
"(tok_tabcolname a b)" +//this is "extra" piece we get vs previous query
") " +
"(tok_select " +
"(tok_selexpr tok_allcolref)" +
")" +
")" +
")", ast.toStringTree());
}
@Test
public void testInsertIntoTableFromAnonymousTable() throws ParseException {
ASTNode ast = parse("insert into table page_view values(-1,2),(3,+4)");
Assert.assertEquals("AST doesn't match",
"(tok_query " +
"(tok_from " +
"(tok_virtual_table " +
"(tok_virtual_tabref tok_anonymous) " +
"(tok_values_table (tok_value_row (- 1) 2) (tok_value_row 3 (+ 4))))) " +
"(tok_insert (tok_insert_into (tok_tab (tok_tabname page_view))) " +
"(tok_select (tok_selexpr tok_allcolref))))",
ast.toStringTree());
//same query as above less the "table" keyword KW_table
ast = parse("insert into page_view values(-1,2),(3,+4)");
Assert.assertEquals("AST doesn't match",
"(tok_query " +
"(tok_from " +
"(tok_virtual_table " +
"(tok_virtual_tabref tok_anonymous) " +
"(tok_values_table (tok_value_row (- 1) 2) (tok_value_row 3 (+ 4))))) " +
"(tok_insert (tok_insert_into (tok_tab (tok_tabname page_view))) " +
"(tok_select (tok_selexpr tok_allcolref))))",
ast.toStringTree());
}
@Test
public void testMultiInsert() throws ParseException {
ASTNode ast = parse("from S insert into T1 select a, b insert into T2 select c, d");
Assert.assertEquals("AST doesn't match", "(tok_query (tok_from (tok_tabref (tok_tabname s))) " +
"(tok_insert (tok_insert_into (tok_tab (tok_tabname t1))) (tok_select (tok_selexpr (tok_table_or_col a)) (tok_selexpr (tok_table_or_col b)))) " +
"(tok_insert (tok_insert_into (tok_tab (tok_tabname t2))) (tok_select (tok_selexpr (tok_table_or_col c)) (tok_selexpr (tok_table_or_col d)))))", ast.toStringTree());
}
}