Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
AnalyzeStmtsTest.java
Go to the documentation of this file.
1 // Copyright (c) 2012 Cloudera, Inc. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 package com.cloudera.impala.analysis;
16 
17 import static org.junit.Assert.assertEquals;
18 import static org.junit.Assert.fail;
19 
20 import java.lang.reflect.Field;
21 import java.util.List;
22 
23 import junit.framework.Assert;
24 
25 import org.junit.Test;
26 
31 import com.google.common.base.Preconditions;
32 import com.google.common.collect.ImmutableList;
33 import com.google.common.collect.Lists;
34 
35 public class AnalyzeStmtsTest extends AnalyzerTest {
36 
42  private void testCollectionTableRefs(String collectionTable, String collectionField) {
43  TableName tbl = new TableName("functional", "allcomplextypes");
44 
45  // Collection table uses unqualified implicit alias of parent table.
46  TblsAnalyzeOk(String.format("select %s from $TBL, allcomplextypes.%s",
47  collectionField, collectionTable), tbl);
48  // Collection table uses fully qualified implicit alias of parent table.
49  TblsAnalyzeOk(String.format("select %s from $TBL, functional.allcomplextypes.%s",
50  collectionField, collectionTable), tbl);
51  // Collection table uses explicit alias of parent table.
52  TblsAnalyzeOk(String.format("select %s from $TBL a, a.%s",
53  collectionField, collectionTable), tbl);
54 
55  // Parent/collection/collection join.
56  TblsAnalyzeOk(String.format("select b.%s from $TBL a, a.%s b, a.int_map_col c",
57  collectionField, collectionTable), tbl);
58  TblsAnalyzeOk(String.format("select c.%s from $TBL a, a.int_array_col b, a.%s c",
59  collectionField, collectionTable), tbl);
60 
61  // Test join types. Parent/collection joins do not require an ON or USING clause.
62  for (JoinOperator joinOp: JoinOperator.values()) {
63  if (joinOp.isNullAwareLeftAntiJoin()) continue;
64  TblsAnalyzeOk(String.format("select 1 from $TBL %s allcomplextypes.%s",
65  joinOp, collectionTable), tbl);
66  TblsAnalyzeOk(String.format("select 1 from $TBL a %s a.%s",
67  joinOp, collectionTable), tbl);
68  }
69 
70  // Legal, but not a parent/collection join.
71  TblsAnalyzeOk(String.format("select %s from $TBL a, functional.allcomplextypes.%s",
72  collectionField, collectionTable), tbl);
73  TblsAnalyzeOk(String.format("select %s from $TBL.%s, functional.allcomplextypes",
74  collectionField, collectionTable), tbl);
75  TblsAnalyzeOk(String.format("select %s from functional.allcomplextypes a, $TBL.%s",
76  collectionField, collectionTable), tbl);
77  TblsAnalyzeOk(String.format("select %s from functional.allcomplextypes.%s, $TBL",
78  collectionField, collectionTable), tbl);
79  // Non parent/collection outer or semi joins require an ON or USING clause.
80  for (JoinOperator joinOp: JoinOperator.values()) {
81  if (joinOp.isNullAwareLeftAntiJoin()
82  || joinOp.isCrossJoin()
83  || joinOp.isInnerJoin()) {
84  continue;
85  }
86  AnalysisError(String.format(
87  "select 1 from functional.allcomplextypes.%s %s functional.allcomplextypes",
88  collectionTable, joinOp),
89  String.format("%s requires an ON or USING clause", joinOp));
90  }
91 
92  // Duplicate explicit alias.
93  TblsAnalysisError(String.format("select %s from $TBL a, a.%s a",
94  collectionField, collectionTable), tbl,
95  "Duplicate table alias: 'a'");
96  TblsAnalysisError(String.format("select %s from $TBL a, a.%s b, a.%s b",
97  collectionField, collectionTable, collectionTable), tbl,
98  "Duplicate table alias: 'b'");
99  // Duplicate implicit alias.
100  String[] childTblPath = collectionTable.split("\\.");
101  String childTblAlias = childTblPath[childTblPath.length - 1];
102  TblsAnalysisError(String.format("select %s from $TBL a, a.%s, a.%s",
103  collectionField, collectionTable, collectionTable), tbl,
104  String.format("Duplicate table alias: '%s'", childTblAlias));
105  TblsAnalysisError(String.format(
106  "select 1 from $TBL, allcomplextypes.%s, functional.allcomplextypes.%s",
107  collectionTable, collectionTable), tbl,
108  String.format("Duplicate table alias: '%s'", childTblAlias));
109  // Duplicate implicit/explicit alias.
110  TblsAnalysisError(String.format(
111  "select %s from $TBL, functional.allcomplextypes.%s allcomplextypes",
112  collectionField, collectionTable), tbl,
113  "Duplicate table alias: 'allcomplextypes'");
114 
115  // Parent/collection join requires the child to use an alias of the parent.
116  AnalysisError(String.format(
117  "select %s from allcomplextypes, %s", collectionField, collectionTable),
118  createAnalyzer("functional"),
119  String.format("Could not resolve table reference: '%s'", collectionTable));
120  AnalysisError(String.format(
121  "select %s from functional.allcomplextypes, %s",
122  collectionField, collectionTable),
123  String.format("Could not resolve table reference: '%s'", collectionTable));
124 
125  // Ambiguous collection table ref.
126  AnalysisError(String.format(
127  "select %s from functional.allcomplextypes, " +
128  "functional_parquet.allcomplextypes, allcomplextypes.%s",
129  collectionField, collectionTable),
130  "Unqualified table alias is ambiguous: 'allcomplextypes'");
131  }
132 
133  private boolean isCollectionTableRef(String tableName) {
134  return tableName.split("\\.").length > 0;
135  }
136 
142  private void testAllTableAliases(String[] tables, String[] columns)
143  throws AnalysisException {
144  for (String tbl: tables) {
145  TableName tblName = new TableName("functional", tbl);
146  String uqAlias = tbl.substring(tbl.lastIndexOf(".") + 1);
147  String fqAlias = "functional." + tbl;
148  // True if 'tbl' refers to a collection, false otherwise. A value of false implies
149  // the table must be a base table or view.
150  boolean isCollectionTblRef = isCollectionTableRef(tbl);
151  for (String col: columns) {
152  // Test implicit table aliases with unqualified and fully-qualified table names.
153  TblsAnalyzeOk(String.format("select %s from $TBL", col), tblName);
154  TblsAnalyzeOk(String.format("select %s.%s from $TBL", uqAlias, col), tblName);
155  // Only references to base tables/views have a fully-qualified implicit alias.
156  if (!isCollectionTblRef) {
157  TblsAnalyzeOk(String.format("select %s.%s from $TBL", fqAlias, col), tblName);
158  }
159 
160  // Explicit table alias.
161  TblsAnalyzeOk(String.format("select %s from $TBL a", col), tblName);
162  TblsAnalyzeOk(String.format("select a.%s from $TBL a", col), tblName);
163 
164  String errRefStr = "column/field reference";
165  if (col.endsWith("*")) errRefStr = "star expression";
166  // Explicit table alias must be used.
167  TblsAnalysisError(String.format("select %s.%s from $TBL a",
168  uqAlias, col, tbl), tblName,
169  String.format("Could not resolve %s: '%s.%s'",
170  errRefStr, uqAlias, col));
171  TblsAnalysisError(String.format("select %s.%s from $TBL a",
172  fqAlias, col, tbl), tblName,
173  String.format("Could not resolve %s: '%s.%s'",
174  errRefStr, fqAlias, col));
175  }
176  }
177 
178  // Test that multiple implicit fully-qualified aliases work.
179  for (String t1: tables) {
180  for (String t2: tables) {
181  if (t1.equals(t2)) continue;
182  // Collection tables do not have a fully-qualified implicit alias.
183  if (isCollectionTableRef(t1) && isCollectionTableRef(t2)) continue;
184  for (String col: columns) {
185  AnalyzesOk(String.format(
186  "select functional.%s.%s, functional.%s.%s " +
187  "from functional.%s, functional.%s", t1, col, t2, col, t1, t2));
188  }
189  }
190  }
191 
192  String col = columns[0];
193  for (String tbl: tables) {
194  TableName tblName = new TableName("functional", tbl);
195  // Make sure a column reference requires an existing table alias.
196  TblsAnalysisError("select alltypessmall.int_col from $TBL", tblName,
197  "Could not resolve column/field reference: 'alltypessmall.int_col'");
198  // Duplicate explicit alias.
200  String.format("select a.%s from $TBL a, functional.testtbl a", col),
201  tblName, "Duplicate table alias");
202  // Duplicate implicit alias.
203  TblsAnalysisError(String.format("select %s from $TBL, $TBL", col), tblName,
204  "Duplicate table alias");
205  // Duplicate implicit/explicit alias.
206  String uqAlias = tbl.substring(tbl.lastIndexOf(".") + 1);
207  TblsAnalysisError(String.format(
208  "select %s.%s from $TBL, functional.testtbl %s", tbl, col, uqAlias), tblName,
209  "Duplicate table alias");
210  }
211  }
212 
213  @Test
215  // Test ARRAY type referenced as a table.
216  testAllTableAliases(new String[] {
217  "allcomplextypes.int_array_col"},
219  testAllTableAliases(new String[] {
220  "allcomplextypes.struct_array_col"},
221  new String[] {"f1", "f2", "*"});
222 
223  // Test MAP type referenced as a table.
224  testAllTableAliases(new String[] {
225  "allcomplextypes.int_map_col"},
227  testAllTableAliases(new String[] {
228  "allcomplextypes.struct_map_col"},
229  new String[] {Path.MAP_KEY_FIELD_NAME, "f1", "f2", "*"});
230 
231  // Test complex table ref path with structs and multiple collections.
232  testAllTableAliases(new String[] {
233  "allcomplextypes.complex_nested_struct_col.f2.f12"},
234  new String[] {Path.MAP_KEY_FIELD_NAME, "f21", "*"});
235 
236  // Test resolution of collection table refs.
240  testCollectionTableRefs("complex_nested_struct_col.f2.f12", "f21");
241 
242  // Path resolution error is reported before duplicate alias.
243  AnalysisError("select 1 from functional.allcomplextypes a, a",
244  "Illegal table reference to non-collection type: 'a'");
245 
246  // Invalid reference to non-collection type.
247  AnalysisError("select 1 from functional.allcomplextypes.int_struct_col",
248  "Illegal table reference to non-collection type: " +
249  "'functional.allcomplextypes.int_struct_col'\n" +
250  "Path resolved to type: STRUCT<f1:INT,f2:INT>");
251  AnalysisError("select 1 from functional.allcomplextypes a, a.int_struct_col",
252  "Illegal table reference to non-collection type: 'a.int_struct_col'\n" +
253  "Path resolved to type: STRUCT<f1:INT,f2:INT>");
254  AnalysisError("select 1 from functional.allcomplextypes.int_array_col.item",
255  "Illegal table reference to non-collection type: " +
256  "'functional.allcomplextypes.int_array_col.item'\n" +
257  "Path resolved to type: INT");
258  AnalysisError("select 1 from functional.allcomplextypes.int_array_col a, a.pos",
259  "Illegal table reference to non-collection type: 'a.pos'\n" +
260  "Path resolved to type: BIGINT");
261  AnalysisError("select 1 from functional.allcomplextypes.int_map_col.key",
262  "Illegal table reference to non-collection type: " +
263  "'functional.allcomplextypes.int_map_col.key'\n" +
264  "Path resolved to type: STRING");
265  AnalysisError("select 1 from functional.allcomplextypes.int_map_col a, a.key",
266  "Illegal table reference to non-collection type: 'a.key'\n" +
267  "Path resolved to type: STRING");
268 
269  // Test that parent/collection joins without an ON clause analyze ok.
270  for (JoinOperator joinOp: JoinOperator.values()) {
271  if (joinOp.isNullAwareLeftAntiJoin()) continue;
272  AnalyzesOk(String.format(
273  "select 1 from functional.allcomplextypes a %s a.int_array_col b", joinOp));
274  AnalyzesOk(String.format(
275  "select 1 from functional.allcomplextypes a %s a.struct_array_col b", joinOp));
276  AnalyzesOk(String.format(
277  "select 1 from functional.allcomplextypes a %s a.int_map_col b", joinOp));
278  AnalyzesOk(String.format(
279  "select 1 from functional.allcomplextypes a %s a.struct_map_col", joinOp));
280  }
281  }
282 
283  @Test
285  String[] tables = new String[] { "alltypes", "alltypes_view" };
286  String[] columns = new String[] { "int_col", "*" };
287  testAllTableAliases(tables, columns);
288 
289  // Unqualified '*' is not ambiguous.
290  AnalyzesOk("select * from functional.alltypes " +
291  "cross join functional_parquet.alltypes");
292 
293  // Ambiguous unqualified column reference.
294  AnalysisError("select int_col from functional.alltypes " +
295  "cross join functional_parquet.alltypes",
296  "Column/field reference is ambiguous: 'int_col'");
297  // Ambiguous implicit unqualified table alias.
298  AnalysisError("select alltypes.int_col from functional.alltypes " +
299  "cross join functional_parquet.alltypes",
300  "Unqualified table alias is ambiguous: 'alltypes'");
301  AnalysisError("select alltypes.* from functional.alltypes " +
302  "cross join functional_parquet.alltypes",
303  "Unqualified table alias is ambiguous: 'alltypes'");
304 
305  // Mixing unqualified and fully-qualified table refs without explicit aliases is an
306  // error because we'd expect a consistent result if we created a view of this stmt
307  // (table names are fully qualified during view creation).
308  AnalysisError("select alltypes.smallint_col, functional.alltypes.int_col " +
309  "from alltypes inner join functional.alltypes " +
310  "on (alltypes.id = functional.alltypes.id)",
311  createAnalyzer("functional"),
312  "Duplicate table alias: 'functional.alltypes'");
313  }
314 
319  private List<Integer> path(Integer... p) { return Lists.newArrayList(p); }
320 
327  private void testSlotRefPath(String sql, List<Integer> expectedPhysPath) {
328  SelectStmt stmt = (SelectStmt) AnalyzesOk(sql);
329  Expr e = stmt.getResultExprs().get(stmt.getResultExprs().size() - 1);
330  Preconditions.checkState(e instanceof SlotRef);
331  SlotRef slotRef = (SlotRef) e;
332  List<Integer> actualPhysPath = slotRef.getDesc().getAbsolutePath();
333  Assert.assertTrue(String.format("Expected path: %s\nActual path:%s",
334  expectedPhysPath, actualPhysPath),
335  actualPhysPath.equals(expectedPhysPath));
336  }
337 
343  private void testStarPath(String sql, List<Integer>... expectedPhysPaths) {
344  SelectStmt stmt = (SelectStmt) AnalyzesOk(sql);
345  List<List<Integer>> actualPaths = Lists.newArrayList();
346  for (int i = 0; i < stmt.getResultExprs().size(); ++i) {
347  Expr e = stmt.getResultExprs().get(i);
348  Preconditions.checkState(e instanceof SlotRef);
349  SlotRef slotRef = (SlotRef) e;
350  actualPaths.add(slotRef.getDesc().getAbsolutePath());
351  }
352  List<List<Integer>> expectedPaths = Lists.newArrayList(expectedPhysPaths);
353  Assert.assertTrue(String.format("Expected paths: %s\nActual paths:%s",
354  expectedPaths, actualPaths),
355  actualPaths.equals(expectedPaths));
356  }
357 
362  private void testTableRefPath(String sql, List<Integer> expectedPhysPath) {
363  SelectStmt stmt = (SelectStmt) AnalyzesOk(sql);
364  TableRef lastTblRef = stmt.getTableRefs().get(stmt.getTableRefs().size() - 1);
365  List<Integer> actualPhysPath = lastTblRef.getDesc().getPath().getAbsolutePath();
366  Assert.assertTrue(String.format("Expected path: %s\nActual path:%s",
367  expectedPhysPath, actualPhysPath),
368  actualPhysPath.equals(expectedPhysPath));
369  }
370 
371  @SuppressWarnings("unchecked")
372  @Test
374  // Check that there are no implicit field names for base tables.
375  String[] implicitFieldNames = new String[] {Path.ARRAY_POS_FIELD_NAME,
376  Path.ARRAY_ITEM_FIELD_NAME, Path.MAP_KEY_FIELD_NAME, Path.MAP_VALUE_FIELD_NAME};
377  for (String field: implicitFieldNames) {
378  AnalysisError(String.format("select %s from functional.alltypes", field),
379  String.format("Could not resolve column/field reference: '%s'", field));
380  }
381 
382  addTestDb("d");
383 
384  // Test array of scalars. Only explicit paths make sense.
385  addTestTable("create table d.t1 (c array<int>)");
386  testSlotRefPath("select item from d.t1.c", path(0, 0));
387  testSlotRefPath("select pos from d.t1.c", path(0, 1));
388  AnalysisError("select item.item from d.t1.c",
389  "Could not resolve column/field reference: 'item.item'");
390  AnalysisError("select item.pos from d.t1.c",
391  "Could not resolve column/field reference: 'item.pos'");
392  // Test star expansion.
393  testStarPath("select * from d.t1.c", path(0, 0));
394  testStarPath("select c.* from d.t1.c", path(0, 0));
395 
396  // Array of structs. No name conflicts with implicit fields. Both implicit and
397  // explicit paths are allowed.
398  addTestTable("create table d.t2 (c array<struct<f:int>>)");
399  testSlotRefPath("select f from d.t2.c", path(0, 0, 0));
400  testSlotRefPath("select item.f from d.t2.c", path(0, 0, 0));
401  testSlotRefPath("select pos from d.t2.c", path(0, 1));
402  AnalysisError("select item from d.t2.c",
403  "Expr 'item' in select list returns a complex type 'STRUCT<f:INT>'.\n" +
404  "Only scalar types are allowed in the select list.");
405  AnalysisError("select item.pos from d.t2.c",
406  "Could not resolve column/field reference: 'item.pos'");
407  // Test star expansion.
408  testStarPath("select * from d.t2.c", path(0, 0, 0));
409  testStarPath("select c.* from d.t2.c", path(0, 0, 0));
410 
411  // Array of structs with name conflicts. Both implicit and explicit
412  // paths are allowed.
413  addTestTable("create table d.t3 (c array<struct<f:int,item:int,pos:int>>)");
414  testSlotRefPath("select f from d.t3.c", path(0, 0, 0));
415  testSlotRefPath("select item.f from d.t3.c", path(0, 0, 0));
416  testSlotRefPath("select item.item from d.t3.c", path(0, 0, 1));
417  testSlotRefPath("select item.pos from d.t3.c", path(0, 0, 2));
418  testSlotRefPath("select pos from d.t3.c", path(0, 1));
419  AnalysisError("select item from d.t3.c",
420  "Expr 'item' in select list returns a complex type " +
421  "'STRUCT<f:INT,item:INT,pos:INT>'.\n" +
422  "Only scalar types are allowed in the select list.");
423  // Test star expansion.
424  testStarPath("select * from d.t3.c", path(0, 0, 0), path(0, 0, 1), path(0, 0, 2));
425  testStarPath("select c.* from d.t3.c", path(0, 0, 0), path(0, 0, 1), path(0, 0, 2));
426 
427  // Map with a scalar key and value. Only implicit paths make sense.
428  addTestTable("create table d.t4 (c map<int,string>)");
429  testSlotRefPath("select key from d.t4.c", path(0, 0));
430  testSlotRefPath("select value from d.t4.c", path(0, 1));
431  AnalysisError("select value.value from d.t4.c",
432  "Could not resolve column/field reference: 'value.value'");
433  // Test star expansion.
434  testStarPath("select * from d.t4.c", path(0, 0), path(0, 1));
435  testStarPath("select c.* from d.t4.c", path(0, 0), path(0, 1));
436 
437  // Map with a scalar key and struct value. No name conflicts. Both implicit and
438  // explicit paths are allowed.
439  addTestTable("create table d.t5 (c map<int,struct<f:int>>)");
440  testSlotRefPath("select key from d.t5.c", path(0, 0));
441  testSlotRefPath("select f from d.t5.c", path(0, 1, 0));
442  testSlotRefPath("select value.f from d.t5.c", path(0, 1, 0));
443  AnalysisError("select value.value from d.t5.c",
444  "Could not resolve column/field reference: 'value.value'");
445  AnalysisError("select value from d.t5.c",
446  "Expr 'value' in select list returns a complex type " +
447  "'STRUCT<f:INT>'.\n" +
448  "Only scalar types are allowed in the select list.");
449  // Test star expansion.
450  testStarPath("select * from d.t5.c", path(0, 0), path(0, 1, 0));
451  testStarPath("select c.* from d.t5.c", path(0, 0), path(0, 1, 0));
452 
453  // Map with a scalar key and struct value with name conflicts. Both implicit and
454  // explicit paths are allowed.
455  addTestTable("create table d.t6 (c map<int,struct<f:int,key:int,value:int>>)");
456  testSlotRefPath("select key from d.t6.c", path(0, 0));
457  testSlotRefPath("select f from d.t6.c", path(0, 1, 0));
458  testSlotRefPath("select value.f from d.t6.c", path(0, 1, 0));
459  testSlotRefPath("select value.key from d.t6.c", path(0, 1, 1));
460  testSlotRefPath("select value.value from d.t6.c", path(0, 1, 2));
461  AnalysisError("select value from d.t6.c",
462  "Expr 'value' in select list returns a complex type " +
463  "'STRUCT<f:INT,key:INT,value:INT>'.\n" +
464  "Only scalar types are allowed in the select list.");
465  // Test star expansion.
466  testStarPath("select * from d.t6.c",
467  path(0, 0), path(0, 1, 0), path(0, 1, 1), path(0, 1, 2));
468  testStarPath("select c.* from d.t6.c",
469  path(0, 0), path(0, 1, 0), path(0, 1, 1), path(0, 1, 2));
470 
471  // Test implicit/explicit paths on a complicated schema.
472  addTestTable("create table d.t7 (" +
473  "c1 int, " +
474  "c2 decimal(10, 4), " +
475  "c3 array<struct<a1:array<int>,a2:array<struct<x:int,y:int,a3:array<int>>>>>, " +
476  "c4 bigint, " +
477  "c5 map<int,struct<m1:map<int,string>," +
478  " m2:map<int,struct<x:int,y:int,m3:map<int,int>>>>>)");
479 
480  // Test paths with c3.
481  testTableRefPath("select 1 from d.t7.c3.a1", path(2, 0, 0));
482  testTableRefPath("select 1 from d.t7.c3.item.a1", path(2, 0, 0));
483  testSlotRefPath("select item from d.t7.c3.a1", path(2, 0, 0, 0));
484  testSlotRefPath("select item from d.t7.c3.item.a1", path(2, 0, 0, 0));
485  testTableRefPath("select 1 from d.t7.c3.a2", path(2, 0, 1));
486  testTableRefPath("select 1 from d.t7.c3.item.a2", path(2, 0, 1));
487  testSlotRefPath("select x from d.t7.c3.a2", path(2, 0, 1, 0, 0));
488  testSlotRefPath("select x from d.t7.c3.item.a2", path(2, 0, 1, 0, 0));
489  testTableRefPath("select 1 from d.t7.c3.a2.a3", path(2, 0, 1, 0, 2));
490  testTableRefPath("select 1 from d.t7.c3.item.a2.item.a3", path(2, 0, 1, 0, 2));
491  testSlotRefPath("select item from d.t7.c3.a2.a3", path(2, 0, 1, 0, 2, 0));
492  testSlotRefPath("select item from d.t7.c3.item.a2.item.a3", path(2, 0, 1, 0, 2, 0));
493  // Test path assembly with multiple tuple descriptors.
494  testTableRefPath("select 1 from d.t7, t7.c3, c3.a2, a2.a3", path(2, 0, 1, 0, 2));
495  testTableRefPath("select 1 from d.t7, t7.c3, c3.item.a2, a2.item.a3",
496  path(2, 0, 1, 0, 2));
497  testSlotRefPath("select y from d.t7, t7.c3, c3.a2, a2.a3", path(2, 0, 1, 0, 1));
498  testSlotRefPath("select y, x from d.t7, t7.c3, c3.a2, a2.a3", path(2, 0, 1, 0, 0));
499  testSlotRefPath("select x, y from d.t7, t7.c3.item.a2, a2.a3", path(2, 0, 1, 0, 1));
500  testSlotRefPath("select a1.item from d.t7, t7.c3, c3.a1, c3.a2, a2.a3",
501  path(2, 0, 0, 0));
502 
503  // Test paths with c5.
504  testTableRefPath("select 1 from d.t7.c5.m1", path(4, 1, 0));
505  testTableRefPath("select 1 from d.t7.c5.value.m1", path(4, 1, 0));
506  testSlotRefPath("select key from d.t7.c5.m1", path(4, 1, 0, 0));
507  testSlotRefPath("select key from d.t7.c5.value.m1", path(4, 1, 0, 0));
508  testSlotRefPath("select value from d.t7.c5.m1", path(4, 1, 0, 1));
509  testSlotRefPath("select value from d.t7.c5.value.m1", path(4, 1, 0, 1));
510  testTableRefPath("select 1 from d.t7.c5.m2", path(4, 1, 1));
511  testTableRefPath("select 1 from d.t7.c5.value.m2", path(4, 1, 1));
512  testSlotRefPath("select key from d.t7.c5.m2", path(4, 1, 1, 0));
513  testSlotRefPath("select key from d.t7.c5.value.m2", path(4, 1, 1, 0));
514  testSlotRefPath("select x from d.t7.c5.m2", path(4, 1, 1, 1, 0));
515  testSlotRefPath("select x from d.t7.c5.value.m2", path(4, 1, 1, 1, 0));
516  testTableRefPath("select 1 from d.t7.c5.m2.m3", path(4, 1, 1, 1, 2));
517  testTableRefPath("select 1 from d.t7.c5.value.m2.value.m3", path(4, 1, 1, 1, 2));
518  testSlotRefPath("select key from d.t7.c5.m2.m3", path(4, 1, 1, 1, 2, 0));
519  testSlotRefPath("select key from d.t7.c5.value.m2.value.m3", path(4, 1, 1, 1, 2, 0));
520  testSlotRefPath("select value from d.t7.c5.m2.m3", path(4, 1, 1, 1, 2, 1));
521  testSlotRefPath("select value from d.t7.c5.value.m2.value.m3",
522  path(4, 1, 1, 1, 2, 1));
523  // Test path assembly with multiple tuple descriptors.
524  testTableRefPath("select 1 from d.t7, t7.c5, c5.m2, m2.m3", path(4, 1, 1, 1, 2));
525  testTableRefPath("select 1 from d.t7, t7.c5, c5.value.m2, m2.value.m3",
526  path(4, 1, 1, 1, 2));
527  testSlotRefPath("select y from d.t7, t7.c5, c5.m2, m2.m3",
528  path(4, 1, 1, 1, 1));
529  testSlotRefPath("select y, x from d.t7, t7.c5, c5.m2, m2.m3",
530  path(4, 1, 1, 1, 0));
531  testSlotRefPath("select x, y from d.t7, t7.c5.value.m2, m2.m3",
532  path(4, 1, 1, 1, 1));
533  testSlotRefPath("select m1.key from d.t7, t7.c5, c5.m1, c5.m2, m2.m3",
534  path(4, 1, 0, 0));
535  }
536 
537  @Test
538  public void TestStructFields() throws AnalysisException {
539  String[] tables = new String[] { "allcomplextypes" };
540  String[] columns = new String[] { "id", "int_struct_col.f1",
541  "nested_struct_col.f2.f12.f21" };
542  testAllTableAliases(tables, columns);
543 
544  // Unknown struct fields.
545  AnalysisError("select nested_struct_col.badfield from functional.allcomplextypes",
546  "Could not resolve column/field reference: 'nested_struct_col.badfield'");
547  AnalysisError("select nested_struct_col.f2.badfield from functional.allcomplextypes",
548  "Could not resolve column/field reference: 'nested_struct_col.f2.badfield'");
549  AnalysisError("select nested_struct_col.badfield.f2 from functional.allcomplextypes",
550  "Could not resolve column/field reference: 'nested_struct_col.badfield.f2'");
551 
552  // Illegal intermediate reference to collection type.
553  AnalysisError("select int_array_col.item from functional.allcomplextypes",
554  "Illegal column/field reference 'int_array_col.item' with intermediate " +
555  "collection 'int_array_col' of type 'ARRAY<INT>'");
556  AnalysisError("select struct_array_col.f1 from functional.allcomplextypes",
557  "Illegal column/field reference 'struct_array_col.f1' with intermediate " +
558  "collection 'struct_array_col' of type 'ARRAY<STRUCT<f1:BIGINT,f2:STRING>>'");
559  AnalysisError("select int_map_col.key from functional.allcomplextypes",
560  "Illegal column/field reference 'int_map_col.key' with intermediate " +
561  "collection 'int_map_col' of type 'MAP<STRING,INT>'");
562  AnalysisError("select struct_map_col.f1 from functional.allcomplextypes",
563  "Illegal column/field reference 'struct_map_col.f1' with intermediate " +
564  "collection 'struct_map_col' of type 'MAP<STRING,STRUCT<f1:BIGINT,f2:STRING>>'");
566  "select complex_nested_struct_col.f2.f11 from functional.allcomplextypes",
567  "Illegal column/field reference 'complex_nested_struct_col.f2.f11' with " +
568  "intermediate collection 'f2' of type " +
569  "'ARRAY<STRUCT<f11:BIGINT,f12:MAP<STRING,STRUCT<f21:BIGINT>>>>'");
571  "select complex_nested_struct_col.f2.f11 from functional.allcomplextypes",
572  "Illegal column/field reference 'complex_nested_struct_col.f2.f11' with " +
573  "intermediate collection 'f2' of type " +
574  "'ARRAY<STRUCT<f11:BIGINT,f12:MAP<STRING,STRUCT<f21:BIGINT>>>>'");
575  }
576 
577  @Test
578  public void TestSlotRefPathAmbiguity() {
579  addTestDb("a");
580  addTestTable("create table a.a (a struct<a:struct<a:int>>)");
581 
582  // Slot path is not ambiguous.
583  AnalyzesOk("select a.a.a.a.a from a.a");
584  AnalyzesOk("select t.a.a.a from a.a t");
585 
586  // Slot path is not ambiguous but resolves to a struct.
587  AnalysisError("select a from a.a",
588  "Expr 'a' in select list returns a complex type 'STRUCT<a:STRUCT<a:INT>>'.\n" +
589  "Only scalar types are allowed in the select list.");
590  AnalysisError("select t.a from a.a t",
591  "Expr 't.a' in select list returns a complex type 'STRUCT<a:STRUCT<a:INT>>'.\n" +
592  "Only scalar types are allowed in the select list.");
593  AnalysisError("select t.a.a from a.a t",
594  "Expr 't.a.a' in select list returns a complex type 'STRUCT<a:INT>'.\n" +
595  "Only scalar types are allowed in the select list.");
596 
597  // Slot paths are ambiguous. A slot path can legally resolve to a non-scalar type,
598  // even though we currently do not support non-scalar SlotRefs in the select list
599  // or in any exprs.
600  AnalysisError("select a.a from a.a",
601  "Column/field reference is ambiguous: 'a.a'");
602  AnalysisError("select a.a.a from a.a",
603  "Column/field reference is ambiguous: 'a.a.a'");
604  AnalysisError("select a.a.a.a from a.a",
605  "Column/field reference is ambiguous: 'a.a.a.a'");
606 
607  // Cannot resolve slot paths.
608  AnalysisError("select a.a.a.a.a.a from a.a",
609  "Could not resolve column/field reference: 'a.a.a.a.a.a'");
610  AnalysisError("select t.a.a.a.a from a.a t",
611  "Could not resolve column/field reference: 't.a.a.a.a'");
612 
613  // Paths resolve to an existing implicit table alias
614  // (the unqualified path resolution would be illegal).
615  addTestTable("create table a.array_test (a array<int>)");
616  addTestTable("create table a.map_test (a map<int, int>)");
617  AnalyzesOk("select a.item from a.array_test t, t.a");
618  AnalyzesOk("select a.key, a.value from a.map_test t, t.a");
619  }
620 
621  @Test
622  public void TestStarPathAmbiguity() {
623  addTestDb("a");
624  addTestTable("create table a.a (a struct<a:struct<a:int>>)");
625 
626  // Star path is not ambiguous.
627  AnalyzesOk("select a.a.a.a.* from a.a");
628  AnalyzesOk("select t.a.a.* from a.a t");
629 
630  // Not ambiguous, but illegal.
631  AnalysisError("select a.a.a.a.a.* from a.a",
632  "Cannot expand star in 'a.a.a.a.a.*' because path 'a.a.a.a.a' " +
633  "resolved to type 'INT'.");
634  AnalysisError("select t.a.a.a.* from a.a t",
635  "Cannot expand star in 't.a.a.a.*' because path 't.a.a.a' " +
636  "resolved to type 'INT'.");
637  AnalysisError("select t.* from a.a t",
638  "Expr 't.a' in select list returns a complex type 'STRUCT<a:STRUCT<a:INT>>'.\n" +
639  "Only scalar types are allowed in the select list.");
640 
641  // Star paths are ambiguous.
642  AnalysisError("select a.* from a.a",
643  "Star expression is ambiguous: 'a.*'");
644  AnalysisError("select a.a.* from a.a",
645  "Star expression is ambiguous: 'a.a.*'");
646  AnalysisError("select a.a.a.* from a.a",
647  "Star expression is ambiguous: 'a.a.a.*'");
648 
649  // Cannot resolve star paths.
650  AnalysisError("select a.a.a.a.a.a.* from a.a",
651  "Could not resolve star expression: 'a.a.a.a.a.a.*'");
652  AnalysisError("select t.a.a.a.a.* from a.a t",
653  "Could not resolve star expression: 't.a.a.a.a.*'");
654 
655  // Paths resolve to an existing implicit table alias
656  // (the unqualified path resolution would be illegal).
657  addTestTable("create table a.array_test (a array<int>)");
658  addTestTable("create table a.map_test (a map<int, int>)");
659  AnalyzesOk("select a.* from a.array_test t, t.a");
660  AnalyzesOk("select a.* from a.map_test t, t.a");
661  }
662 
663  @Test
665  addTestDb("a");
666  addTestTable("create table a.a (a array<struct<a:array<int>>>)");
667 
668  // Table paths are not ambiguous.
669  AnalyzesOk("select 1 from a.a");
670  AnalyzesOk("select 1 from a.a.a");
671  AnalyzesOk("select 1 from a.a.a.a");
672  AnalyzesOk("select 1 from a", createAnalyzer("a"));
673  AnalyzesOk("select 1 from a.a.a.a", createAnalyzer("a"));
674 
675  // Table paths are ambiguous.
676  AnalysisError("select 1 from a.a", createAnalyzer("a"),
677  "Table reference is ambiguous: 'a.a'");
678  AnalysisError("select 1 from a.a.a", createAnalyzer("a"),
679  "Table reference is ambiguous: 'a.a.a'");
680 
681  // Ambiguous reference to registered table aliases.
682  addTestTable("create table a.t1 (x array<struct<y:array<int>>>)");
683  addTestTable("create table a.t2 (y array<int>)");
684  AnalysisError("select 1 from a.t1 a, a.t2 `a.x`, a.x.y",
685  "Table reference is ambiguous: 'a.x.y'");
686  }
687 
688  @Test
689  public void TestFromClause() throws AnalysisException {
690  AnalyzesOk("select int_col from functional.alltypes");
691  AnalysisError("select int_col from badtbl",
692  "Could not resolve table reference: 'badtbl'");
693 
694  // case-insensitive
695  AnalyzesOk("SELECT INT_COL FROM FUNCTIONAL.ALLTYPES");
696  AnalyzesOk("SELECT INT_COL FROM functional.alltypes");
697  AnalyzesOk("SELECT INT_COL FROM functional.aLLTYPES");
698  AnalyzesOk("SELECT INT_COL FROM Functional.ALLTYPES");
699  AnalyzesOk("SELECT INT_COL FROM FUNCTIONAL.ALLtypes");
700  AnalyzesOk("SELECT INT_COL FROM FUNCTIONAL.alltypes");
701  AnalyzesOk("select functional.AllTypes.Int_Col from functional.alltypes");
702  }
703 
704  @Test
705  public void TestNoFromClause() throws AnalysisException {
706  AnalyzesOk("select 'test'");
707  AnalyzesOk("select 1 + 1, -128, 'two', 1.28");
708  AnalyzesOk("select -1, 1 - 1, 10 - -1, 1 - - - 1");
709  AnalyzesOk("select -1.0, 1.0 - 1.0, 10.0 - -1.0, 1.0 - - - 1.0");
710  AnalysisError("select a + 1", "Could not resolve column/field reference: 'a'");
711  // Test predicates in select list.
712  AnalyzesOk("select true");
713  AnalyzesOk("select false");
714  AnalyzesOk("select true or false");
715  AnalyzesOk("select true and false");
716  // Test NULL's in select list.
717  AnalyzesOk("select null");
718  AnalyzesOk("select null and null");
719  AnalyzesOk("select null or null");
720  AnalyzesOk("select null is null");
721  AnalyzesOk("select null is not null");
722  AnalyzesOk("select int_col is not null from functional.alltypes");
723  }
724 
725  @Test
726  public void TestStar() throws AnalysisException {
727  AnalyzesOk("select * from functional.AllTypes");
728  AnalyzesOk("select functional.alltypes.* from functional.AllTypes");
729  // different db
730  AnalyzesOk("select functional_seq.alltypes.* from functional_seq.alltypes");
731  // two tables w/ identical names from different dbs
732  AnalyzesOk("select functional.alltypes.*, functional_seq.alltypes.* " +
733  "from functional.alltypes, functional_seq.alltypes");
734  AnalyzesOk("select * from functional.alltypes, functional_seq.alltypes");
735  // expand '*' on a struct-typed column
736  AnalyzesOk("select int_struct_col.* from functional.allcomplextypes");
737  AnalyzesOk("select a.int_struct_col.* from functional.allcomplextypes a");
738  AnalyzesOk("select allcomplextypes.int_struct_col.* from functional.allcomplextypes");
739  AnalyzesOk("select functional.allcomplextypes.int_struct_col.* " +
740  "from functional.allcomplextypes");
741 
742  // '*' without from clause has no meaning.
743  AnalysisError("select *", "'*' expression in select list requires FROM clause.");
744  AnalysisError("select 1, *, 2+4",
745  "'*' expression in select list requires FROM clause.");
746  AnalysisError("select a.*", "Could not resolve star expression: 'a.*'");
747 
748  // invalid star expansions
749  AnalysisError("select functional.* from functional.alltypes",
750  "Could not resolve star expression: 'functional.*'");
751  AnalysisError("select int_col.* from functional.alltypes",
752  "Cannot expand star in 'int_col.*' because " +
753  "path 'int_col' resolved to type 'INT'.\n" +
754  "Star expansion is only valid for paths to a struct type.");
755  AnalysisError("select complex_struct_col.f2.* from functional.allcomplextypes",
756  "Cannot expand star in 'complex_struct_col.f2.*' because " +
757  "path 'complex_struct_col.f2' resolved to type 'ARRAY<INT>'.\n" +
758  "Star expansion is only valid for paths to a struct type.");
759 
760  for (String joinType: new String[] { "left semi join", "left anti join" }) {
761  // ignore semi-/anti-joined tables in unqualified '*' expansion
762  SelectStmt stmt = (SelectStmt) AnalyzesOk(String.format(
763  "select * from functional.alltypes a " +
764  "%s functional.testtbl b on (a.id = b.id)", joinType));
765  // expect to have as many result exprs as alltypes has columns
766  assertEquals(13, stmt.getResultExprs().size());
767 
768  // cannot expand '*" for a semi-/anti-joined table
769  AnalysisError(String.format("select a.*, b.* from functional.alltypes a " +
770  "%s functional.alltypes b on (a.id = b.id)", joinType),
771  "Illegal star expression 'b.*' of semi-/anti-joined table 'b'");
772  }
773  for (String joinType: new String[] { "right semi join", "right anti join" }) {
774  // ignore semi-/anti-joined tables in unqualified '*' expansion
775  SelectStmt stmt = (SelectStmt) AnalyzesOk(String.format(
776  "select * from functional.alltypes a " +
777  "%s functional.testtbl b on (a.id = b.id)", joinType));
778  // expect to have as many result exprs as testtbl has columns
779  assertEquals(3, stmt.getResultExprs().size());
780 
781  // cannot expand '*" for a semi-/anti-joined table
782  AnalysisError(String.format("select a.*, b.* from functional.alltypes a " +
783  "%s functional.alltypes b on (a.id = b.id)", joinType),
784  "Illegal star expression 'a.*' of semi-/anti-joined table 'a'");
785  }
786  }
787 
791  @Test
793  // Illegal complex-typed expr in select list.
794  AnalysisError("select int_struct_col from functional.allcomplextypes",
795  "Expr 'int_struct_col' in select list returns a " +
796  "complex type 'STRUCT<f1:INT,f2:INT>'.\n" +
797  "Only scalar types are allowed in the select list.");
798  // Illegal complex-typed expr in a union.
799  AnalysisError("select int_struct_col from functional.allcomplextypes " +
800  "union all select int_struct_col from functional.allcomplextypes",
801  "Expr 'int_struct_col' in select list returns a " +
802  "complex type 'STRUCT<f1:INT,f2:INT>'.\n" +
803  "Only scalar types are allowed in the select list.");
804  // Illegal complex-typed expr inside inline view.
805  AnalysisError("select 1 from " +
806  "(select int_struct_col from functional.allcomplextypes) v",
807  "Expr 'int_struct_col' in select list returns a " +
808  "complex type 'STRUCT<f1:INT,f2:INT>'.\n" +
809  "Only scalar types are allowed in the select list.");
810  // Illegal complex-typed expr in an insert.
811  AnalysisError("insert into functional.allcomplextypes " +
812  "select int_struct_col from functional.allcomplextypes",
813  "Expr 'int_struct_col' in select list returns a " +
814  "complex type 'STRUCT<f1:INT,f2:INT>'.\n" +
815  "Only scalar types are allowed in the select list.");
816  // Illegal complex-typed expr in a CTAS.
817  AnalysisError("create table new_tbl as " +
818  "select int_struct_col from functional.allcomplextypes",
819  "Expr 'int_struct_col' in select list returns a " +
820  "complex type 'STRUCT<f1:INT,f2:INT>'.\n" +
821  "Only scalar types are allowed in the select list.");
822  // Legal star expansion adds illegal complex-typed expr.
823  AnalysisError("select * from functional.allcomplextypes " +
824  "cross join functional_parquet.alltypes",
825  "Expr 'functional.allcomplextypes.int_array_col' in select list returns a " +
826  "complex type 'ARRAY<INT>'.\n" +
827  "Only scalar types are allowed in the select list.");
828  AnalysisError("select complex_struct_col.* from functional.allcomplextypes",
829  "Expr 'functional.allcomplextypes.complex_struct_col.f2' in select list " +
830  "returns a complex type 'ARRAY<INT>'.\n" +
831  "Only scalar types are allowed in the select list.");
832  }
833 
834  @Test
835  public void TestOrdinals() throws AnalysisException {
836  AnalysisError("select * from functional.alltypes group by 1",
837  "cannot combine '*' in select list with GROUP BY");
838  AnalysisError("select * from functional.alltypes order by 14",
839  "ORDER BY: ordinal exceeds number of items in select list: 14");
840  AnalyzesOk("select t.* from functional.alltypes t order by 1");
841  AnalyzesOk("select t2.* from functional.alltypes t1, " +
842  "functional.alltypes t2 order by 1");
843  AnalyzesOk("select * from (select max(id) from functional.testtbl) t1 order by 1");
844  AnalysisError("select * from (select max(id) from functional.testtbl) t1 order by 2",
845  "ORDER BY: ordinal exceeds number of items in select list: 2");
846  }
847 
848  @Test
849  public void TestInlineView() throws AnalysisException {
850  AnalyzesOk("select y x from (select id y from functional_hbase.alltypessmall) a");
851  AnalyzesOk("select id from (select id from functional_hbase.alltypessmall) a");
852  AnalyzesOk("select * from (select id+2 from functional_hbase.alltypessmall) a");
853  AnalyzesOk("select t1 c from " +
854  "(select c t1 from (select id c from functional_hbase.alltypessmall) t1) a");
855  AnalysisError("select id from (select id+2 from functional_hbase.alltypessmall) a",
856  "Could not resolve column/field reference: 'id'");
857  AnalyzesOk("select a.* from (select id+2 from functional_hbase.alltypessmall) a");
858 
859  // join test
860  AnalyzesOk("select * from (select id+2 id from functional_hbase.alltypessmall) a " +
861  "join (select * from functional.AllTypes where true) b");
862  AnalyzesOk("select a.x from (select count(id) x from functional.AllTypes) a");
863  AnalyzesOk("select a.* from (select count(id) from functional.AllTypes) a");
864  AnalysisError("select a.id from (select id y from functional_hbase.alltypessmall) a",
865  "Could not resolve column/field reference: 'a.id'");
866  AnalyzesOk("select * from (select * from functional.AllTypes) a where year = 2009");
867  AnalyzesOk("select * from (select * from functional.alltypesagg) a right outer join" +
868  " (select * from functional.alltypessmall) b using (id, int_col) " +
869  " where a.day >= 6 and b.month > 2 and a.tinyint_col = 15 and " +
870  " b.string_col = '15' and a.tinyint_col + b.tinyint_col < 15");
871  AnalyzesOk("select * from (select a.smallint_col+b.smallint_col c1" +
872  " from functional.alltypesagg a join functional.alltypessmall b " +
873  " using (id, int_col)) x " +
874  " where x.c1 > 100");
875  AnalyzesOk("select a.* from" +
876  " (select * from (select id+2 from functional_hbase.alltypessmall) b) a");
877  AnalysisError("select * from " +
878  "(select * from functional.alltypes a join " +
879  "functional.alltypes b on (a.int_col = b.int_col)) x",
880  "duplicated inline view column alias: 'id' in inline view 'x'");
881 
882  // subquery on the rhs of the join
883  AnalyzesOk("select x.float_col " +
884  " from functional.alltypessmall c join " +
885  " (select a.smallint_col smallint_col, a.tinyint_col tinyint_col, " +
886  " a.int_col int_col, b.float_col float_col" +
887  " from (select * from functional.alltypesagg a where month=1) a join " +
888  " functional.alltypessmall b on (a.smallint_col = b.id)) x " +
889  " on (x.tinyint_col = c.id)");
890 
891  // aggregate test
892  AnalyzesOk("select count(*) from (select count(id) from " +
893  "functional.AllTypes group by id) a");
894  AnalyzesOk("select count(a.x) from (select id+2 x " +
895  "from functional_hbase.alltypessmall) a");
896  AnalyzesOk("select * from (select id, zip " +
897  " from (select * from functional.testtbl) x " +
898  " group by zip, id having count(*) > 0) x");
899 
900  AnalysisError("select zip + count(*) from functional.testtbl",
901  "select list expression not produced by aggregation output " +
902  "(missing from GROUP BY clause?)");
903 
904  // union test
905  AnalyzesOk("select a.* from " +
906  "(select rank() over(order by string_col) from functional.alltypes " +
907  " union all " +
908  " select tinyint_col from functional.alltypessmall) a");
909  AnalyzesOk("select a.* from " +
910  "(select int_col from functional.alltypes " +
911  " union all " +
912  " select tinyint_col from functional.alltypessmall) a " +
913  "union all " +
914  "select smallint_col from functional.alltypes");
915  AnalyzesOk("select a.* from " +
916  "(select int_col from functional.alltypes " +
917  " union all " +
918  " select b.smallint_col from " +
919  " (select smallint_col from functional.alltypessmall" +
920  " union all" +
921  " select tinyint_col from functional.alltypes) b) a");
922  // negative union test, column labels are inherited from first select block
923  AnalysisError("select tinyint_col from " +
924  "(select int_col from functional.alltypes " +
925  " union all " +
926  " select tinyint_col from functional.alltypessmall) a",
927  "Could not resolve column/field reference: 'tinyint_col'");
928 
929  // negative aggregate test
930  AnalysisError("select * from " +
931  "(select id, zip from functional.testtbl group by id having count(*) > 0) x",
932  "select list expression not produced by aggregation output " +
933  "(missing from GROUP BY clause?)");
934  AnalysisError("select * from " +
935  "(select id from functional.testtbl group by id having zip + count(*) > 0) x",
936  "HAVING clause not produced by aggregation output " +
937  "(missing from GROUP BY clause?)");
938  AnalysisError("select * from " +
939  "(select zip, count(*) from functional.testtbl group by 3) x",
940  "GROUP BY: ordinal exceeds number of items in select list");
941  AnalysisError("select * from " +
942  "(select * from functional.alltypes group by 1) x",
943  "cannot combine '*' in select list with GROUP BY");
944  AnalysisError("select * from " +
945  "(select zip, count(*) from functional.testtbl group by count(*)) x",
946  "GROUP BY expression must not contain aggregate functions");
947  AnalysisError("select * from " +
948  "(select zip, count(*) from functional.testtbl group by count(*) + min(zip)) x",
949  "GROUP BY expression must not contain aggregate functions");
950  AnalysisError("select * from " +
951  "(select zip, count(*) from functional.testtbl group by 2) x",
952  "GROUP BY expression must not contain aggregate functions");
953 
954  // order by, top-n
955  AnalyzesOk("select * from (select zip, count(*) " +
956  " from (select * from functional.testtbl) x " +
957  " group by 1 order by count(*) + min(zip) limit 5) x");
958  AnalyzesOk("select * from (select zip, count(*) " +
959  " from (select * from functional.testtbl) x " +
960  " group by 1 order by count(*) + min(zip)) x");
961  AnalysisError("select * from (select zip, count(*) " +
962  " from (select * from functional.testtbl) x " +
963  " group by 1 offset 5) x",
964  "OFFSET requires an ORDER BY clause: OFFSET 5");
965  AnalysisError("select * from (select zip, count(*) " +
966  " from (select * from functional.testtbl) x " +
967  " group by 1 order by count(*) + min(zip) offset 5) x",
968  "Order-by with offset without limit not supported in nested queries");
969  AnalyzesOk("select c1, c2 from (select zip c1 , count(*) c2 " +
970  " from (select * from functional.testtbl) x group by 1) x " +
971  " order by 2, 1 limit 5");
972  AnalyzesOk("select c1, c2 from (select zip c1 , count(*) c2 " +
973  " from (select * from functional.testtbl) x group by 1) x " +
974  " order by 2, 1");
975  AnalyzesOk("select c1, c2 from (select zip c1 , count(*) c2 " +
976  " from (select * from functional.testtbl) x group by 1) x " +
977  " order by 2, 1 offset 5");
978 
979  // test NULLs
980  AnalyzesOk("select * from (select NULL) a");
981 
982  // test that auto-generated columns are not used by default
983  AnalyzesOk("select `int_col * 1`, a, int_col, `NOT bool_col` from " +
984  "(select int_col * 1, int_col as a, int_col, !bool_col, concat(string_col) " +
985  "from functional.alltypes) t");
986  // test auto-generated column labels by enforcing their use in inline views
987  AnalyzesOk("select _c0, a, int_col, _c3 from " +
988  "(select int_col * 1, int_col as a, int_col, !bool_col, concat(string_col) " +
989  "from functional.alltypes) t", createAnalyzerUsingHiveColLabels());
990  // test auto-generated column labels in group by and order by
991  AnalyzesOk("select _c0, count(a), count(int_col), _c3 from " +
992  "(select int_col * 1, int_col as a, int_col, !bool_col, concat(string_col) " +
993  "from functional.alltypes) t group by _c0, _c3 order by _c0 limit 10",
995  // test auto-generated column labels in multiple scopes
996  AnalyzesOk("select x.front, x._c1, x._c2 from " +
997  "(select y.back as front, y._c0 * 10, y._c2 + 2 from " +
998  "(select int_col * 10, int_col as back, int_col + 2 from " +
999  "functional.alltypestiny) y) x",
1001 
1002  // ambiguous reference to an auto-generated column
1003  AnalysisError("select _c0 from " +
1004  "(select int_col * 2, id from functional.alltypes) a inner join " +
1005  "(select int_col + 6, id from functional.alltypes) b " +
1006  "on (a.id = b.id)",
1008  "Column/field reference is ambiguous: '_c0'");
1009  // auto-generated column doesn't exist
1010  AnalysisError("select _c0, a, _c2, _c3 from " +
1011  "(select int_col * 1, int_col as a, int_col, !bool_col, concat(string_col) " +
1012  "from functional.alltypes) t",
1014  "Could not resolve column/field reference: '_c2'");
1015 
1016  // Regression test for IMPALA-984.
1017  AnalyzesOk("SELECT 1 " +
1018  "FROM functional.decimal_tbl AS t1 LEFT JOIN " +
1019  "(SELECT SUM(t1.d2) - SUM(t1.d3) as double_col_3, " +
1020  "SUM(t1.d2) IS NULL " +
1021  "FROM functional.decimal_tbl AS t1) AS t3 " +
1022  "ON t3.double_col_3 = t1.d3");
1023 
1024  // Test that InlineViewRef.makeOutputNullable() preserves expr signatures when
1025  // substituting NULL literals for SlotRefs (IMPALA-1468).
1026  AnalyzesOk("select 1 from functional.alltypes a left outer join " +
1027  "(select id, upper(decode(string_col, NULL, date_string_col)) " +
1028  "from functional.alltypes) v on (a.id = v.id)");
1029 
1030  // Inline view with a subquery
1031  AnalyzesOk("select y x from " +
1032  "(select id y from functional.alltypestiny where id in " +
1033  "(select id from functional.alltypessmall)) a");
1034  }
1035 
1036  @Test
1037  public void TestOnClause() throws AnalysisException {
1038  AnalyzesOk(
1039  "select a.int_col from functional.alltypes a " +
1040  "join functional.alltypes b on (a.int_col = b.int_col)");
1041  AnalyzesOk(
1042  "select a.int_col " +
1043  "from functional.alltypes a join functional.alltypes b on " +
1044  "(a.int_col = b.int_col and a.string_col = b.string_col)");
1045  AnalyzesOk(
1046  "select a.int_col from functional.alltypes a " +
1047  "join functional.alltypes b on (a.bool_col)");
1048  AnalyzesOk(
1049  "select a.int_col from functional.alltypes a " +
1050  "join functional.alltypes b on (NULL)");
1051  // ON or USING clause not required for inner join
1052  AnalyzesOk("select a.int_col from functional.alltypes a join functional.alltypes b");
1053  // arbitrary expr not returning bool
1054  AnalysisError(
1055  "select a.int_col from functional.alltypes a " +
1056  "join functional.alltypes b on trim(a.string_col)",
1057  "ON clause 'trim(a.string_col)' requires return type 'BOOLEAN'. " +
1058  "Actual type is 'STRING'.");
1059  AnalysisError(
1060  "select a.int_col from functional.alltypes a " +
1061  "join functional.alltypes b on a.int_col * b.float_col",
1062  "ON clause 'a.int_col * b.float_col' requires return type 'BOOLEAN'. " +
1063  "Actual type is 'DOUBLE'.");
1064  // wrong kind of expr
1065  AnalysisError(
1066  "select a.int_col from functional.alltypes a " +
1067  "join functional.alltypes b on (a.bigint_col = sum(b.int_col))",
1068  "aggregate function not allowed in ON clause");
1069  AnalysisError(
1070  "select a.int_col from functional.alltypes a " +
1071  "join functional.alltypes b on (a.bigint_col = " +
1072  "lag(b.int_col) over(order by a.bigint_col))",
1073  "analytic expression not allowed in ON clause");
1074  // unknown column
1075  AnalysisError(
1076  "select a.int_col from functional.alltypes a " +
1077  "join functional.alltypes b on (a.int_col = b.badcol)",
1078  "Could not resolve column/field reference: 'b.badcol'");
1079  // ambiguous col ref
1080  AnalysisError(
1081  "select a.int_col from functional.alltypes a " +
1082  "join functional.alltypes b on (int_col = int_col)",
1083  "Column/field reference is ambiguous: 'int_col'");
1084  // unknown alias
1085  AnalysisError(
1086  "select a.int_col from functional.alltypes a join functional.alltypes b on " +
1087  "(a.int_col = badalias.int_col)",
1088  "Could not resolve column/field reference: 'badalias.int_col'");
1089  // incompatible comparison
1090  AnalysisError(
1091  "select a.int_col from functional.alltypes a join " +
1092  "functional.alltypes b on a.bool_col = b.string_col",
1093  "operands of type BOOLEAN and STRING are not comparable: " +
1094  "a.bool_col = b.string_col");
1095  AnalyzesOk(
1096  "select a.int_col, b.int_col, c.int_col " +
1097  "from functional.alltypes a join functional.alltypes b on " +
1098  "(a.int_col = b.int_col and a.string_col = b.string_col)" +
1099  "join functional.alltypes c on " +
1100  "(b.int_col = c.int_col and b.string_col = c.string_col " +
1101  "and b.bool_col = c.bool_col)");
1102  // can't reference an alias that gets declared afterwards
1103  AnalysisError(
1104  "select a.int_col, b.int_col, c.int_col " +
1105  "from functional.alltypes a join functional.alltypes b on " +
1106  "(c.int_col = b.int_col and a.string_col = b.string_col)" +
1107  "join functional.alltypes c on " +
1108  "(b.int_col = c.int_col and b.string_col = c.string_col " +
1109  "and b.bool_col = c.bool_col)",
1110  "Could not resolve column/field reference: 'c.int_col'");
1111 
1112  // outer joins require ON/USING clause
1113  AnalyzesOk("select * from functional.alltypes a left outer join " +
1114  "functional.alltypes b on (a.id = b.id)");
1115  AnalyzesOk("select * from functional.alltypes a left outer join " +
1116  "functional.alltypes b using (id)");
1117  AnalysisError("select * from functional.alltypes a " +
1118  "left outer join functional.alltypes b",
1119  "LEFT OUTER JOIN requires an ON or USING clause");
1120  AnalyzesOk("select * from functional.alltypes a right outer join " +
1121  "functional.alltypes b on (a.id = b.id)");
1122  AnalyzesOk("select * from functional.alltypes a right outer join " +
1123  "functional.alltypes b using (id)");
1124  AnalysisError("select * from functional.alltypes a " +
1125  "right outer join functional.alltypes b",
1126  "RIGHT OUTER JOIN requires an ON or USING clause");
1127  AnalyzesOk("select * from functional.alltypes a full outer join " +
1128  "functional.alltypes b on (a.id = b.id)");
1129  AnalyzesOk("select * from functional.alltypes a full outer join " +
1130  "functional.alltypes b using (id)");
1131  AnalysisError("select * from functional.alltypes a full outer join " +
1132  "functional.alltypes b",
1133  "FULL OUTER JOIN requires an ON or USING clause");
1134  }
1135 
1136  @Test
1137  public void TestUsingClause() throws AnalysisException {
1138  AnalyzesOk("select a.int_col, b.int_col from functional.alltypes a join " +
1139  "functional.alltypes b using (int_col)");
1140  AnalyzesOk("select a.int_col, b.int_col from " +
1141  "functional.alltypes a join functional.alltypes b " +
1142  "using (int_col, string_col)");
1143  AnalyzesOk(
1144  "select a.int_col, b.int_col, c.int_col " +
1145  "from functional.alltypes a " +
1146  "join functional.alltypes b using (int_col, string_col) " +
1147  "join functional.alltypes c using (int_col, string_col, bool_col)");
1148  // unknown column
1149  AnalysisError("select a.int_col from functional.alltypes a " +
1150  "join functional.alltypes b using (badcol)",
1151  "unknown column badcol for alias a");
1152  AnalysisError(
1153  "select a.int_col from functional.alltypes a " +
1154  "join functional.alltypes b using (int_col, badcol)",
1155  "unknown column badcol for alias a ");
1156  }
1157 
1161  @Test
1162  public void TestSemiJoins() {
1163  // Test left semi joins.
1164  for (String joinType: new String[] { "left semi join", "left anti join" }) {
1165  // semi/anti join requires ON/USING clause
1166  AnalyzesOk(String.format("select a.id from functional.alltypes a " +
1167  "%s functional.alltypes b on (a.id = b.id)", joinType));
1168  AnalyzesOk(String.format("select a.id from functional.alltypes a " +
1169  "%s functional.alltypes b on (a.id = b.id) " +
1170  "%s functional.alltypes c on (a.id = c.id)", joinType, joinType));
1171  AnalyzesOk(String.format("select a.id from functional.alltypes a %s " +
1172  "functional.alltypes b using (id)", joinType));
1173  // unqualified column reference is not ambiguous outside of the On-clause
1174  // because a semi/anti-joined tuple is invisible
1175  AnalyzesOk(String.format("select int_col from functional.alltypes a " +
1176  "%s functional.alltypes b on (a.id = b.id)", joinType));
1177  AnalysisError(String.format("select * from functional.alltypes a " +
1178  "%s functional.alltypes b on (a.id = b.id and a.int_col = int_col)", joinType),
1179  "Column/field reference is ambiguous: 'int_col'");
1180  // flip 'a' and 'b' aliases to test the unqualified column resolution logic
1181  AnalyzesOk(String.format("select int_col from functional.alltypes b " +
1182  "%s functional.alltypes a on (b.id = a.id)", joinType));
1183  AnalysisError(String.format("select * from functional.alltypes b " +
1184  "%s functional.alltypes a on (b.id = a.id and b.int_col = int_col)", joinType),
1185  "Column/field reference is ambiguous: 'int_col'");
1186  // unqualified column reference that matches two semi-/anti-joined tables
1187  // is not ambiguous outside of On-clause
1188  AnalyzesOk(String.format("select int_col from functional.alltypes c " +
1189  "%s functional.alltypes b on (c.id = b.id) " +
1190  "%s functional.jointbl a on (test_id = c.id)", joinType, joinType));
1191  AnalyzesOk(String.format("select int_col from functional.alltypes c " +
1192  "%s functional.alltypes b on (c.id = b.id) " +
1193  "%s functional.jointbl a on (test_id = id)", joinType, joinType));
1194  AnalysisError(String.format("select int_col from functional.alltypes c " +
1195  "%s functional.alltypes b on (c.id = b.id) " +
1196  "%s functional.jointbl a on (test_id = b.id)", joinType, joinType),
1197  "Illegal column/field reference 'b.id' of semi-/anti-joined table 'b'");
1198  // must not reference semi/anti-joined alias outside of join clause
1199  AnalysisError(String.format("select a.id, b.id from functional.alltypes a " +
1200  "%s functional.alltypes b on (a.id = b.id)", joinType),
1201  "Illegal column/field reference 'b.id' of semi-/anti-joined table 'b'");
1202  AnalysisError(String.format("select a.id from functional.alltypes a " +
1203  "%s (select * from functional.alltypes) b " +
1204  "on (a.id = b.id) where b.int_col > 10", joinType),
1205  "Illegal column/field reference 'b.int_col' of semi-/anti-joined table 'b'");
1206  AnalysisError(String.format("select a.id from functional.alltypes a " +
1207  "%s functional.alltypes b on (a.id = b.id) group by b.bool_col", joinType),
1208  "Illegal column/field reference 'b.bool_col' of semi-/anti-joined table 'b'");
1209  AnalysisError(String.format("select a.id from functional.alltypes a " +
1210  "%s (select * from functional.alltypes) b " +
1211  "on (a.id = b.id) order by b.string_col", joinType),
1212  "Illegal column/field reference 'b.string_col' of " +
1213  "semi-/anti-joined table 'b'");
1214  // column of semi/anti-joined table is not visible in other On-clause
1215  AnalysisError(String.format("select a.id from functional.alltypes a " +
1216  "%s functional.alltypes b on (a.id = b.id)" +
1217  "left outer join functional.testtbl c on (b.id = c.id)", joinType),
1218  "Illegal column/field reference 'b.id' of semi-/anti-joined table 'b'");
1219  // column of semi/anti-joined table is not visible in other On-clause
1220  AnalysisError(String.format("select a.id from functional.alltypes a " +
1221  "%s functional.alltypes b on (a.id = b.id)" +
1222  "%s functional.testtbl c on (b.id = c.id)", joinType, joinType),
1223  "Illegal column/field reference 'b.id' of semi-/anti-joined table 'b'");
1224  // using clause always refers to lhs/rhs table
1225  AnalysisError(String.format("select a.id from functional.alltypes a " +
1226  "%s functional.alltypes b using(id) " +
1227  "%s functional.alltypes c using(int_col)", joinType, joinType),
1228  "Illegal column/field reference 'b.int_col' of semi-/anti-joined table 'b'");
1229  // unqualified column reference is ambiguous in the On-clause of a semi/anti join
1230  AnalysisError(String.format("select * from functional.alltypes a " +
1231  "%s functional.alltypes b on (a.id = b.id and a.int_col = int_col)", joinType),
1232  "Column/field reference is ambiguous: 'int_col'");
1233  // illegal unqualified column reference against semi/anti-joined table
1234  AnalysisError(String.format("select test_id from functional.alltypes a " +
1235  "%s functional.jointbl b on (a.id = b.alltypes_id)", joinType),
1236  "Illegal column/field reference 'test_id' of semi-/anti-joined table 'b'");
1237  // unqualified table ref is ambiguous even if semi/anti-joined
1238  AnalysisError(String.format("select alltypes.int_col from functional.alltypes " +
1239  "%s functional_parquet.alltypes " +
1240  "on (functional.alltypes.id = functional_parquet.alltypes.id)", joinType),
1241  "Unqualified table alias is ambiguous: 'alltypes'");
1242  // illegal collection table reference through semi/anti joined table
1243  AnalysisError(String.format("select 1 from functional.allcomplextypes a " +
1244  "%s functional.allcomplextypes b on (a.id = b.id) " +
1245  "inner join b.int_array_col", joinType),
1246  "Illegal table reference 'b.int_array_col' of semi-/anti-joined table 'b'");
1247  }
1248 
1249  // Test right semi joins. Do not combine these with the left semi join tests above
1250  // for better readability.
1251  for (String joinType: new String[] { "right semi join", "right anti join" }) {
1252  // semi/anti join requires ON/USING clause
1253  AnalyzesOk(String.format("select b.id from functional.alltypes a " +
1254  "%s functional.alltypes b on (a.id = b.id)", joinType));
1255  AnalyzesOk(String.format("select c.id from functional.alltypes a " +
1256  "%s functional.alltypes b on (a.id = b.id) " +
1257  "%s functional.alltypes c on (b.id = c.id)", joinType, joinType));
1258  AnalyzesOk(String.format("select b.id from functional.alltypes a %s " +
1259  "functional.alltypes b using (id)", joinType));
1260  // unqualified column reference is not ambiguous outside of the On-clause
1261  // because a semi/anti-joined tuple is invisible
1262  AnalyzesOk(String.format("select int_col from functional.alltypes a " +
1263  "%s functional.alltypes b on (a.id = b.id)", joinType));
1264  AnalysisError(String.format("select * from functional.alltypes a " +
1265  "%s functional.alltypes b on (a.id = b.id and a.int_col = int_col)", joinType),
1266  "Column/field reference is ambiguous: 'int_col'");
1267  // flip 'a' and 'b' aliases to test the unqualified column resolution logic
1268  AnalyzesOk(String.format("select int_col from functional.alltypes b " +
1269  "%s functional.alltypes a on (b.id = a.id)", joinType));
1270  AnalysisError(String.format("select * from functional.alltypes b " +
1271  "%s functional.alltypes a on (b.id = a.id and b.int_col = int_col)", joinType),
1272  "Column/field reference is ambiguous: 'int_col'");
1273  // unqualified column reference that matches two semi-/anti-joined tables
1274  // is not ambiguous outside of On-clause
1275  AnalyzesOk(String.format("select int_col from functional.jointbl c " +
1276  "%s functional.alltypes b on (test_id = b.id) " +
1277  "%s functional.alltypes a on (b.id = a.id)", joinType, joinType));
1278  AnalyzesOk(String.format("select int_col from functional.jointbl c " +
1279  "%s functional.alltypes b on (test_id = id) " +
1280  "%s functional.alltypes a on (b.id = a.id)", joinType, joinType));
1281  AnalysisError(String.format("select int_col from functional.jointbl c " +
1282  "%s functional.alltypes b on (test_id = a.id) " +
1283  "%s functional.alltypes a on (c.id = b.id)", joinType, joinType),
1284  "Could not resolve column/field reference: 'a.id'");
1285  // must not reference semi/anti-joined alias outside of join clause
1286  AnalysisError(String.format("select a.id, b.id from functional.alltypes a " +
1287  "%s functional.alltypes b on (a.id = b.id)", joinType),
1288  "Illegal column/field reference 'a.id' of semi-/anti-joined table 'a'");
1289  AnalysisError(String.format("select b.id from functional.alltypes a " +
1290  "%s (select * from functional.alltypes) b " +
1291  "on (a.id = b.id) where a.int_col > 10", joinType),
1292  "Illegal column/field reference 'a.int_col' of semi-/anti-joined table 'a'");
1293  AnalysisError(String.format("select b.id from functional.alltypes a " +
1294  "%s functional.alltypes b on (a.id = b.id) group by a.bool_col", joinType),
1295  "Illegal column/field reference 'a.bool_col' of semi-/anti-joined table 'a'");
1296  AnalysisError(String.format("select b.id from functional.alltypes a " +
1297  "%s (select * from functional.alltypes) b " +
1298  "on (a.id = b.id) order by a.string_col", joinType),
1299  "Illegal column/field reference 'a.string_col' of " +
1300  "semi-/anti-joined table 'a'");
1301  // column of semi/anti-joined table is not visible in other On-clause
1302  AnalysisError(String.format("select b.id from functional.alltypes a " +
1303  "%s functional.alltypes b on (a.id = b.id)" +
1304  "left outer join functional.testtbl c on (a.id = c.id)", joinType),
1305  "Illegal column/field reference 'a.id' of semi-/anti-joined table 'a'");
1306  // column of semi/anti-joined table is not visible in other On-clause
1307  AnalysisError(String.format("select b.id from functional.alltypes a " +
1308  "%s functional.alltypes b on (a.id = b.id)" +
1309  "%s functional.testtbl c on (a.id = c.id)", joinType, joinType),
1310  "Illegal column/field reference 'a.id' of semi-/anti-joined table 'a'");
1311  // using clause always refers to lhs/rhs table
1312  AnalysisError(String.format("select b.id from functional.alltypes a " +
1313  "%s functional.alltypes b using(id) " +
1314  "%s functional.alltypes c using(int_col)", joinType, joinType),
1315  "Illegal column/field reference 'b.id' of semi-/anti-joined table 'b'");
1316  // unqualified column reference is ambiguous in the On-clause of a semi/anti join
1317  AnalysisError(String.format("select * from functional.alltypes a " +
1318  "%s functional.alltypes b on (a.id = b.id and a.int_col = int_col)", joinType),
1319  "Column/field reference is ambiguous: 'int_col'");
1320  // illegal unqualified column reference against semi/anti-joined table
1321  AnalysisError(String.format("select test_id from functional.jointbl a " +
1322  "%s functional.alltypes b on (a.alltypes_id = b.id)", joinType),
1323  "Illegal column/field reference 'test_id' of semi-/anti-joined table 'a'");
1324  // unqualified table ref is ambiguous even if semi/anti-joined
1325  AnalysisError(String.format("select alltypes.int_col from functional.alltypes " +
1326  "%s functional_parquet.alltypes " +
1327  "on (functional.alltypes.id = functional_parquet.alltypes.id)", joinType),
1328  "Unqualified table alias is ambiguous: 'alltypes'");
1329  // illegal collection table reference through semi/anti joined table
1330  AnalysisError(String.format("select 1 from functional.allcomplextypes a " +
1331  "%s functional.allcomplextypes b on (a.id = b.id) " +
1332  "inner join a.int_array_col", joinType),
1333  "Illegal table reference 'a.int_array_col' of semi-/anti-joined table 'a'");
1334  }
1335  }
1336 
1337  @Test
1338  public void TestJoinHints() throws AnalysisException {
1339  String[][] hintStyles = new String[][] {
1340  new String[] { "/* +", "*/" }, // traditional commented hint
1341  new String[] { "\n-- +", "\n" }, // eol commented hint
1342  new String[] { "[", "]" } // legacy style
1343  };
1344  for (String[] hintStyle: hintStyles) {
1345  String prefix = hintStyle[0];
1346  String suffix = hintStyle[1];
1347  AnalyzesOk(
1348  String.format("select * from functional.alltypes a join %sbroadcast%s " +
1349  "functional.alltypes b using (int_col)", prefix, suffix));
1350  AnalyzesOk(
1351  String.format("select * from functional.alltypes a join %sshuffle%s " +
1352  "functional.alltypes b using (int_col)", prefix, suffix));
1353  AnalyzesOk(
1354  String.format("select * from functional.alltypes a cross join %sbroadcast%s " +
1355  "functional.alltypes b", prefix, suffix));
1356  // Only warn on unrecognized hints for view-compatibility with Hive.
1357  AnalyzesOk(
1358  String.format("select * from functional.alltypes a join %sbadhint%s " +
1359  "functional.alltypes b using (int_col)", prefix, suffix),
1360  "JOIN hint not recognized: badhint");
1361  // Hints must be comma separated. Legacy-style hint does not parse because
1362  // of space-separated identifiers.
1363  if (!prefix.contains("[")) {
1364  AnalyzesOk(String.format(
1365  "select * from functional.alltypes a join %sbroadcast broadcast%s " +
1366  "functional.alltypes b using (int_col)", prefix, suffix),
1367  "JOIN hint not recognized: broadcast broadcast");
1368  }
1369  AnalysisError(
1370  String.format("select * from functional.alltypes a cross join %sshuffle%s " +
1371  "functional.alltypes b", prefix, suffix),
1372  "CROSS JOIN does not support SHUFFLE.");
1373  AnalysisError(String.format(
1374  "select * from functional.alltypes a right outer join %sbroadcast%s " +
1375  "functional.alltypes b using (int_col)", prefix, suffix),
1376  "RIGHT OUTER JOIN does not support BROADCAST.");
1377  AnalysisError(String.format(
1378  "select * from functional.alltypes a full outer join %sbroadcast%s " +
1379  "functional.alltypes b using (int_col)", prefix, suffix),
1380  "FULL OUTER JOIN does not support BROADCAST.");
1381  AnalysisError(String.format(
1382  "select * from functional.alltypes a right semi join %sbroadcast%s " +
1383  "functional.alltypes b using (int_col)", prefix, suffix),
1384  "RIGHT SEMI JOIN does not support BROADCAST.");
1385  AnalysisError(String.format(
1386  "select * from functional.alltypes a right anti join %sbroadcast%s " +
1387  "functional.alltypes b using (int_col)", prefix, suffix),
1388  "RIGHT ANTI JOIN does not support BROADCAST.");
1389  // Conflicting join hints.
1390  AnalysisError(String.format(
1391  "select * from functional.alltypes a join %sbroadcast,shuffle%s " +
1392  "functional.alltypes b using (int_col)", prefix, suffix),
1393  "Conflicting JOIN hint: shuffle");
1394  }
1395  }
1396 
1397  @Test
1399  String[][] hintStyles = new String[][] {
1400  new String[] { "/* +", "*/" }, // traditional commented hint
1401  new String[] { "\n-- +", "\n" }, // eol commented hint
1402  new String[] { "", "" } // legacy style
1403  };
1404  for (String[] hintStyle: hintStyles) {
1405  String prefix = hintStyle[0];
1406  String suffix = hintStyle[1];
1407  AnalyzesOk(String.format(
1408  "select %sstraight_join%s * from functional.alltypes", prefix, suffix));
1409  AnalyzesOk(String.format(
1410  "select %sStrAigHt_jOiN%s * from functional.alltypes", prefix, suffix));
1411  if (!prefix.equals("")) {
1412  // Only warn on unrecognized hints for view-compatibility with Hive.
1413  // Legacy hint style does not parse.
1414  AnalyzesOk(String.format(
1415  "select %sbadhint%s * from functional.alltypes", prefix, suffix),
1416  "PLAN hint not recognized: badhint");
1417  // Multiple hints. Legacy hint style does not parse.
1418  AnalyzesOk(String.format(
1419  "select %sstraight_join,straight_join%s * from functional.alltypes",
1420  prefix, suffix));
1421  }
1422  }
1423  }
1424 
1425  @Test
1426  public void TestInsertHints() throws AnalysisException {
1427  String[][] hintStyles = new String[][] {
1428  new String[] { "/* +", "*/" }, // traditional commented hint
1429  new String[] { "\n-- +", "\n" }, // eol commented hint
1430  new String[] { "[", "]" } // legacy style
1431  };
1432  for (String[] hintStyle: hintStyles) {
1433  String prefix = hintStyle[0];
1434  String suffix = hintStyle[1];
1435  // Test plan hints for partitioned Hdfs tables.
1436  AnalyzesOk(String.format("insert into functional.alltypessmall " +
1437  "partition (year, month) %sshuffle%s select * from functional.alltypes",
1438  prefix, suffix));
1439  AnalyzesOk(String.format("insert into table functional.alltypessmall " +
1440  "partition (year, month) %snoshuffle%s select * from functional.alltypes",
1441  prefix, suffix));
1442  // Only warn on unrecognized hints.
1443  AnalyzesOk(String.format("insert into functional.alltypessmall " +
1444  "partition (year, month) %sbadhint%s select * from functional.alltypes",
1445  prefix, suffix),
1446  "INSERT hint not recognized: badhint");
1447  // Plan hints require a partition clause.
1448  AnalysisError(String.format(
1449  "insert into table functional.alltypesnopart %sshuffle%s " +
1450  "select * from functional.alltypesnopart", prefix, suffix),
1451  "INSERT hints are only supported for inserting into partitioned Hdfs tables.");
1452  // Plan hints do not make sense for inserting into HBase tables.
1453  AnalysisError(String.format(
1454  "insert into table functional_hbase.alltypes %sshuffle%s " +
1455  "select * from functional_hbase.alltypes", prefix, suffix),
1456  "INSERT hints are only supported for inserting into partitioned Hdfs tables.");
1457  // Conflicting plan hints.
1458  AnalysisError("insert into table functional.alltypessmall " +
1459  "partition (year, month) /* +shuffle,noshuffle */ " +
1460  "select * from functional.alltypes",
1461  "Conflicting INSERT hint: noshuffle");
1462  }
1463 
1464  // Multiple non-conflicting hints and case insensitivity of hints.
1465  AnalyzesOk("insert into table functional.alltypessmall " +
1466  "partition (year, month) /* +shuffle, ShUfFlE */ " +
1467  "select * from functional.alltypes");
1468  AnalyzesOk("insert into table functional.alltypessmall " +
1469  "partition (year, month) [shuffle, ShUfFlE] " +
1470  "select * from functional.alltypes");
1471  }
1472 
1473  @Test
1474  public void TestWhereClause() throws AnalysisException {
1475  AnalyzesOk("select zip, name from functional.testtbl where id > 15");
1476  AnalysisError("select zip, name from functional.testtbl where badcol > 15",
1477  "Could not resolve column/field reference: 'badcol'");
1478  AnalyzesOk("select * from functional.testtbl where true");
1479  AnalysisError("select * from functional.testtbl where count(*) > 0",
1480  "aggregate function not allowed in WHERE clause");
1481  // NULL and bool literal in binary predicate.
1482  for (BinaryPredicate.Operator op : BinaryPredicate.Operator.values()) {
1483  AnalyzesOk("select id from functional.testtbl where id " +
1484  op.toString() + " true");
1485  AnalyzesOk("select id from functional.testtbl where id " +
1486  op.toString() + " false");
1487  AnalyzesOk("select id from functional.testtbl where id " +
1488  op.toString() + " NULL");
1489  }
1490  // Where clause is a SlotRef of type bool.
1491  AnalyzesOk("select id from functional.alltypes where bool_col");
1492  // Arbitrary exprs that do not return bool.
1493  AnalysisError("select id from functional.alltypes where int_col",
1494  "WHERE clause requires return type 'BOOLEAN'. Actual type is 'INT'.");
1495  AnalysisError("select id from functional.alltypes where trim('abc')",
1496  "WHERE clause requires return type 'BOOLEAN'. Actual type is 'STRING'.");
1497  AnalysisError("select id from functional.alltypes where (int_col + float_col) * 10",
1498  "WHERE clause requires return type 'BOOLEAN'. Actual type is 'DOUBLE'.");
1499  }
1500 
1501  @Test
1502  public void TestFunctions() throws AnalysisException {
1503  // Test with partition columns and substitution
1504  AnalyzesOk("select year(timestamp_col), count(*) " +
1505  "from functional.alltypes group by 1");
1506  AnalyzesOk("select year(timestamp_col), count(*) " +
1507  "from functional.alltypes group by year(timestamp_col)");
1508 
1509  // Check abs() retains type, originally abs() would return double,
1510  // which is incompatible with interval, see IMPALA-1424
1511  AnalyzesOk("select now() + interval abs(cast(1 as int)) days");
1512  AnalyzesOk("select now() + interval abs(cast(1 as smallint)) days");
1513  AnalyzesOk("select now() + interval abs(cast(1 as tinyint)) days");
1514 
1515  AnalyzesOk("select round(c1) from functional.decimal_tiny");
1516  AnalyzesOk("select round(c1, 2) from functional.decimal_tiny");
1517  AnalysisError("select round(c1, cast(c3 as int)) from functional.decimal_tiny",
1518  "round() must be called with a constant second argument.");
1519  AnalysisError("select truncate(c1, cast(c3 as int)) from functional.decimal_tiny",
1520  "truncate() must be called with a constant second argument.");
1521  }
1522 
1523  @Test
1524  public void TestAggregates() throws AnalysisException {
1525  // Add udas:
1526  // bigint AggFn(int)
1527  // bigint AggFn(bigint)
1528  // bigint AggFn(double)
1529  // string AggFn(string, string)
1530  // TODO: if we could persist these in the catalog, we'd just use those
1531  // TODO: add cases where the intermediate type is not the return type when
1532  // the planner supports that.
1533  addTestUda("AggFn", Type.BIGINT, Type.INT);
1534  addTestUda("AggFn", Type.BIGINT, Type.BIGINT);
1535  addTestUda("AggFn", Type.BIGINT, Type.DOUBLE);
1536  addTestUda("AggFn", Type.STRING, Type.STRING, Type.STRING);
1537 
1538  AnalyzesOk("select aggfn(int_col) from functional.alltypesagg");
1539  AnalysisError("select default.AggFn(1)",
1540  "aggregation without a FROM clause is not allowed");
1541  AnalysisError(
1542  "select aggfn(int_col) over (partition by int_col) from functional.alltypesagg",
1543  "Aggregate function 'default.aggfn(int_col)' not supported with OVER clause.");
1544  AnalysisError("select aggfn(distinct int_col) from functional.alltypesagg",
1545  "User defined aggregates do not support DISTINCT.");
1546  AnalyzesOk("select default.aggfn(int_col) from functional.alltypes");
1547  AnalyzesOk("select count(*) from functional.testtbl");
1548  AnalyzesOk("select min(id), max(id), sum(id) from functional.testtbl");
1549  AnalyzesOk("select avg(id) from functional.testtbl");
1550 
1551  AnalyzesOk("select count(*), min(id), max(id), sum(id), avg(id), aggfn(id) " +
1552  "from functional.testtbl");
1553  AnalyzesOk("select AggFn(tinyint_col), AggFn(int_col), AggFn(bigint_col), " +
1554  "AggFn(double_col) from functional.alltypes");
1555  AnalysisError("select AggFn(string_col) from functional.alltypes",
1556  "No matching function with signature: default.aggfn(STRING)");
1557  AnalyzesOk("select AggFn(string_col, string_col) from functional.alltypes");
1558 
1559  AnalyzesOk("select count(NULL), min(NULL), max(NULL), sum(NULL), avg(NULL), " +
1560  "group_concat(NULL), group_concat(name, NULL) from functional.testtbl");
1561  AnalysisError("select id, zip from functional.testtbl where count(*) > 0",
1562  "aggregate function not allowed in WHERE clause");
1563  AnalysisError("select 1 from functional.alltypes where aggfn(1)",
1564  "aggregate function not allowed in WHERE clause");
1565 
1566  AnalysisError("select count() from functional.alltypes",
1567  "count() is not allowed.");
1568  AnalysisError("select min() from functional.alltypes",
1569  "No matching function with signature: min().");
1570  AnalysisError("select int_col from functional.alltypes order by count(*)",
1571  "select list expression not produced by aggregation output (missing from "
1572  + "GROUP BY clause?): int_col");
1573 
1574  // only count() allows '*'
1575  AnalysisError("select avg(*) from functional.testtbl",
1576  "'*' can only be used in conjunction with COUNT");
1577  AnalysisError("select min(*) from functional.testtbl",
1578  "'*' can only be used in conjunction with COUNT");
1579  AnalysisError("select max(*) from functional.testtbl",
1580  "'*' can only be used in conjunction with COUNT");
1581  AnalysisError("select group_concat(*) from functional.testtbl",
1582  "'*' can only be used in conjunction with COUNT");
1583 
1584  // multiple args
1585  AnalysisError("select count(id, zip) from functional.testtbl",
1586  "COUNT must have DISTINCT for multiple arguments: count(id, zip)");
1587  AnalysisError("select min(id, zip) from functional.testtbl",
1588  "No matching function with signature: min(BIGINT, INT).");
1589  AnalysisError("select group_concat(name, '-', ',') from functional.testtbl",
1590  "No matching function with signature: group_concat(STRING, STRING, STRING)");
1591 
1592  // nested aggregates
1593  AnalysisError("select sum(count(*)) from functional.testtbl",
1594  "aggregate function must not contain aggregate parameters");
1595  AnalysisError("select sum(rank() over (order by id)) from functional.testtbl",
1596  "aggregate function must not contain analytic parameters");
1597  AnalysisError("select min(aggfn(int_col)) from functional.alltypes",
1598  "aggregate function must not contain aggregate parameters: " +
1599  "min(default.aggfn(int_col))");
1600 
1601  // wrong type
1602  AnalysisError("select sum(timestamp_col) from functional.alltypes",
1603  "SUM requires a numeric parameter: sum(timestamp_col)");
1604  AnalysisError("select sum(string_col) from functional.alltypes",
1605  "SUM requires a numeric parameter: sum(string_col)");
1606  AnalysisError("select avg(string_col) from functional.alltypes",
1607  "AVG requires a numeric or timestamp parameter: avg(string_col)");
1608 
1609  // aggregate requires table in the FROM clause
1610  AnalysisError("select count(*)", "aggregation without a FROM clause is not allowed");
1611  AnalysisError("select min(1)", "aggregation without a FROM clause is not allowed");
1612  AnalysisError("select group_concat('')",
1613  "aggregation without a FROM clause is not allowed");
1614 
1615  // test group_concat
1616  AnalyzesOk("select group_concat(string_col) from functional.alltypes");
1617  AnalyzesOk("select group_concat(string_col, '-') from functional.alltypes");
1618  AnalyzesOk("select group_concat(string_col, string_col) from functional.alltypes");
1619  // test all types as arguments
1620  for (Type type: typeToLiteralValue_.keySet()) {
1621  String literal = typeToLiteralValue_.get(type);
1622  String query1 = String.format(
1623  "select group_concat(%s) from functional.alltypes", literal);
1624  String query2 = String.format(
1625  "select group_concat(string_col, %s) from functional.alltypes", literal);
1626  if (type.getPrimitiveType() == PrimitiveType.STRING || type.isNull()) {
1627  AnalyzesOk(query1);
1628  AnalyzesOk(query2);
1629  } else {
1630  AnalysisError(query1,
1631  "No matching function with signature: group_concat(");
1632  AnalysisError(query2,
1633  "No matching function with signature: group_concat(");
1634  }
1635  }
1636 
1637  // Test distinct estimate
1638  for (Type type: typeToLiteralValue_.keySet()) {
1639  AnalyzesOk(String.format(
1640  "select ndv(%s) from functional.alltypes",
1641  typeToLiteralValue_.get(type)));
1642  }
1643 
1644  // Decimal
1645  AnalyzesOk("select min(d1), max(d2), count(d3), sum(d4) "
1646  + "from functional.decimal_tbl");
1647  AnalyzesOk("select ndv(d1), distinctpc(d2), distinctpcsa(d3), count(distinct d4) "
1648  + "from functional.decimal_tbl");
1649  AnalyzesOk("select avg(d5) from functional.decimal_tbl");
1650  AnalysisError("select group_concat(d5) from functional.decimal_tbl",
1651  "No matching function with signature: group_concat(DECIMAL(10,5))");
1652 
1653  // Test select stmt avg smap.
1654  AnalyzesOk("select cast(avg(c1) as decimal(10,4)) as c from " +
1655  "functional.decimal_tiny group by c3 having c = 5.1106 order by 1");
1656 
1657  // check CHAR and VARCHAR aggregates
1658  checkExprType("select min(cast('foo' as char(5))) from functional.chars_tiny",
1659  ScalarType.STRING);
1660  checkExprType("select max(cast('foo' as varchar(5))) from functional.chars_tiny",
1661  ScalarType.STRING);
1662  checkExprType("select max(vc) from functional.chars_tiny", ScalarType.STRING);
1663  checkExprType("select max(cs) from functional.chars_tiny", ScalarType.STRING);
1664  checkExprType("select max(lower(cs)) from functional.chars_tiny",
1665  ScalarType.STRING);
1666  }
1667 
1668  @Test
1669  public void TestDistinct() throws AnalysisException {
1670  AnalyzesOk("select count(distinct id) as sum_id from functional.testtbl");
1671  AnalyzesOk("select count(distinct id) as sum_id from " +
1672  "functional.testtbl order by sum_id");
1673  AnalyzesOk("select count(distinct id) as sum_id from " +
1674  "functional.testtbl order by max(id)");
1675  AnalyzesOk("select distinct id, zip from functional.testtbl");
1676  AnalyzesOk("select distinct * from functional.testtbl");
1677  AnalysisError("select distinct count(*) from functional.testtbl",
1678  "cannot combine SELECT DISTINCT with aggregate functions or GROUP BY");
1679  AnalysisError("select distinct id, zip from functional.testtbl group by 1, 2",
1680  "cannot combine SELECT DISTINCT with aggregate functions or GROUP BY");
1681  AnalysisError("select distinct id, zip, count(*) from " +
1682  "functional.testtbl group by 1, 2",
1683  "cannot combine SELECT DISTINCT with aggregate functions or GROUP BY");
1684  AnalyzesOk("select count(distinct id, zip) from functional.testtbl");
1685  AnalysisError("select count(distinct id, zip), count(distinct zip) " +
1686  "from functional.testtbl",
1687  "all DISTINCT aggregate functions need to have the same set of parameters");
1688  AnalyzesOk("select tinyint_col, count(distinct int_col, bigint_col) "
1689  + "from functional.alltypesagg group by 1");
1690  AnalyzesOk("select tinyint_col, count(distinct int_col),"
1691  + "sum(distinct int_col) from functional.alltypesagg group by 1");
1692  AnalyzesOk("select avg(DISTINCT(tinyint_col)) from functional.alltypesagg");
1693 
1694  // SUM(DISTINCT) and AVG(DISTINCT) with duplicate grouping exprs (IMPALA-847).
1695  AnalyzesOk("select sum(distinct t1.bigint_col), avg(distinct t1.bigint_col) " +
1696  "from functional.alltypes t1 group by t1.int_col, t1.int_col");
1697 
1698  AnalysisError("select tinyint_col, count(distinct int_col),"
1699  + "sum(distinct bigint_col) from functional.alltypesagg group by 1",
1700  "all DISTINCT aggregate functions need to have the same set of parameters");
1701  // min and max are ignored in terms of DISTINCT
1702  AnalyzesOk("select tinyint_col, count(distinct int_col),"
1703  + "min(distinct smallint_col), max(distinct string_col) "
1704  + "from functional.alltypesagg group by 1");
1705  AnalysisError("select group_concat(distinct name) from functional.testtbl",
1706  "GROUP_CONCAT() does not support DISTINCT");
1707  }
1708 
1709  @Test
1711  // DISTINCT
1712  AnalyzesOk("select distinct id from " +
1713  "(select distinct id, zip from (select * from functional.testtbl) x) y");
1714  AnalyzesOk("select distinct * from " +
1715  "(select distinct * from (Select * from functional.testtbl) x) y");
1716  AnalyzesOk("select distinct * from (select count(*) from functional.testtbl) x");
1717  AnalyzesOk("select count(distinct id, zip) " +
1718  "from (select * from functional.testtbl) x");
1719  AnalyzesOk("select * from (select tinyint_col, count(distinct int_col, bigint_col) "
1720  + "from (select * from functional.alltypesagg) x group by 1) y");
1721  AnalyzesOk("select tinyint_col, count(distinct int_col),"
1722  + "sum(distinct int_col) from " +
1723  "(select * from functional.alltypesagg) x group by 1");
1724 
1725  // Error case when distinct is inside an inline view
1726  AnalysisError("select * from " +
1727  "(select distinct count(*) from functional.testtbl) x",
1728  "cannot combine SELECT DISTINCT with aggregate functions or GROUP BY");
1729  AnalysisError("select * from " +
1730  "(select distinct id, zip from functional.testtbl group by 1, 2) x",
1731  "cannot combine SELECT DISTINCT with aggregate functions or GROUP BY");
1732  AnalysisError("select * from " +
1733  "(select distinct id, zip, count(*) from functional.testtbl group by 1, 2) x",
1734  "cannot combine SELECT DISTINCT with aggregate functions or GROUP BY");
1735  AnalysisError("select * from " +
1736  "(select count(distinct id, zip), count(distinct zip) " +
1737  "from functional.testtbl) x",
1738  "all DISTINCT aggregate functions need to have the same set of parameters");
1739  AnalysisError("select * from " + "(select tinyint_col, count(distinct int_col),"
1740  + "sum(distinct bigint_col) from functional.alltypesagg group by 1) x",
1741  "all DISTINCT aggregate functions need to have the same set of parameters");
1742 
1743  // Error case when inline view is in the from clause
1744  AnalysisError("select distinct count(*) from (select * from functional.testtbl) x",
1745  "cannot combine SELECT DISTINCT with aggregate functions or GROUP BY");
1746  AnalysisError("select distinct id, zip from " +
1747  "(select * from functional.testtbl) x group by 1, 2",
1748  "cannot combine SELECT DISTINCT with aggregate functions or GROUP BY");
1749  AnalysisError("select distinct id, zip, count(*) from " +
1750  "(select * from functional.testtbl) x group by 1, 2",
1751  "cannot combine SELECT DISTINCT with aggregate functions or GROUP BY");
1752  AnalyzesOk("select count(distinct id, zip) " +
1753  "from (select * from functional.testtbl) x");
1754  AnalysisError("select count(distinct id, zip), count(distinct zip) " +
1755  " from (select * from functional.testtbl) x",
1756  "all DISTINCT aggregate functions need to have the same set of parameters");
1757  AnalyzesOk("select tinyint_col, count(distinct int_col, bigint_col) "
1758  + "from (select * from functional.alltypesagg) x group by 1");
1759  AnalyzesOk("select tinyint_col, count(distinct int_col),"
1760  + "sum(distinct int_col) from " +
1761  "(select * from functional.alltypesagg) x group by 1");
1762  AnalysisError("select tinyint_col, count(distinct int_col),"
1763  + "sum(distinct bigint_col) from " +
1764  "(select * from functional.alltypesagg) x group by 1",
1765  "all DISTINCT aggregate functions need to have the same set of parameters");
1766  }
1767 
1768  @Test
1769  public void TestGroupBy() throws AnalysisException {
1770  AnalyzesOk("select zip, count(*) from functional.testtbl group by zip");
1771  AnalyzesOk("select zip + count(*) from functional.testtbl group by zip");
1772  // grouping on constants is ok and doesn't require them to be in select list
1773  AnalyzesOk("select count(*) from functional.testtbl group by 2*3+4");
1774  AnalyzesOk("select count(*) from functional.testtbl " +
1775  "group by true, false, NULL");
1776  // ok for constants in select list not to be in group by list
1777  AnalyzesOk("select true, NULL, 1*2+5 as a, zip, count(*) from functional.testtbl " +
1778  "group by zip");
1779  AnalyzesOk("select d1, d2, count(*) from functional.decimal_tbl " +
1780  "group by 1, 2");
1781 
1782  // doesn't group by all non-agg select list items
1783  AnalysisError("select zip, count(*) from functional.testtbl",
1784  "select list expression not produced by aggregation output " +
1785  "(missing from GROUP BY clause?)");
1786  AnalysisError("select zip + count(*) from functional.testtbl",
1787  "select list expression not produced by aggregation output " +
1788  "(missing from GROUP BY clause?)");
1789 
1790  // test having clause
1791  AnalyzesOk("select id, zip from functional.testtbl " +
1792  "group by zip, id having count(*) > 0");
1793  AnalyzesOk("select count(*) from functional.alltypes " +
1794  "group by bool_col having bool_col");
1795  // arbitrary exprs not returning boolean
1796  AnalysisError("select count(*) from functional.alltypes " +
1797  "group by bool_col having 5 + 10 * 5.6",
1798  "HAVING clause '5 + 10 * 5.6' requires return type 'BOOLEAN'. " +
1799  "Actual type is 'DOUBLE'.");
1800  AnalysisError("select count(*) from functional.alltypes " +
1801  "group by bool_col having int_col",
1802  "HAVING clause 'int_col' requires return type 'BOOLEAN'. Actual type is 'INT'.");
1803  AnalysisError("select id, zip from functional.testtbl " +
1804  "group by id having count(*) > 0",
1805  "select list expression not produced by aggregation output " +
1806  "(missing from GROUP BY clause?)");
1807  AnalysisError("select id from functional.testtbl " +
1808  "group by id having zip + count(*) > 0",
1809  "HAVING clause not produced by aggregation output " +
1810  "(missing from GROUP BY clause?)");
1811  // resolves ordinals
1812  AnalyzesOk("select zip, count(*) from functional.testtbl group by 1");
1813  AnalyzesOk("select count(*), zip from functional.testtbl group by 2");
1814  AnalysisError("select zip, count(*) from functional.testtbl group by 3",
1815  "GROUP BY: ordinal exceeds number of items in select list: 3");
1816  AnalysisError("select * from functional.alltypes group by 1",
1817  "cannot combine '*' in select list with GROUP BY");
1818  // picks up select item alias
1819  AnalyzesOk("select zip z, id iD1, id ID2, count(*) " +
1820  "from functional.testtbl group by z, ID1, id2");
1821  // same alias is not ambiguous if it refers to the same expr
1822  AnalyzesOk("select int_col, INT_COL from functional.alltypes group by int_col");
1823  AnalyzesOk("select bool_col a, bool_col A from functional.alltypes group by a");
1824  AnalyzesOk("select int_col A, bool_col b, int_col a, bool_col B " +
1825  "from functional.alltypes group by a, b");
1826  // ambiguous alias
1827  AnalysisError("select zip a, id a, count(*) from functional.testtbl group by a",
1828  "Column 'a' in GROUP BY clause is ambiguous");
1829  AnalysisError("select zip id, id, count(*) from functional.testtbl group by id",
1830  "Column 'id' in GROUP BY clause is ambiguous");
1831 
1832  // can't group by aggregate
1833  AnalysisError("select zip, count(*) from functional.testtbl group by count(*)",
1834  "GROUP BY expression must not contain aggregate functions");
1835  AnalysisError("select zip, count(*) " +
1836  "from functional.testtbl group by count(*) + min(zip)",
1837  "GROUP BY expression must not contain aggregate functions");
1838  AnalysisError("select zip, count(*) from functional.testtbl group by 2",
1839  "GROUP BY expression must not contain aggregate functions");
1840 
1841  // multiple grouping cols
1842  AnalyzesOk("select int_col, string_col, bigint_col, count(*) " +
1843  "from functional.alltypes group by string_col, int_col, bigint_col");
1844  AnalyzesOk("select int_col, string_col, bigint_col, count(*) " +
1845  "from functional.alltypes group by 2, 1, 3");
1846  AnalysisError("select int_col, string_col, bigint_col, count(*) " +
1847  "from functional.alltypes group by 2, 1, 4",
1848  "GROUP BY expression must not contain aggregate functions");
1849 
1850  // group by floating-point column
1851  AnalyzesOk("select float_col, double_col, count(*) " +
1852  "from functional.alltypes group by 1, 2");
1853  // group by floating-point exprs
1854  AnalyzesOk("select int_col + 0.5, count(*) from functional.alltypes group by 1");
1855  AnalyzesOk("select cast(int_col as double), count(*)" +
1856  "from functional.alltypes group by 1");
1857  }
1858 
1859  @Test
1860  public void TestOrderBy() throws AnalysisException {
1861  AnalyzesOk("select zip, id from functional.testtbl order by zip");
1862  AnalyzesOk("select zip, id from functional.testtbl order by zip asc");
1863  AnalyzesOk("select zip, id from functional.testtbl order by zip desc");
1864  AnalyzesOk("select zip, id from functional.testtbl " +
1865  "order by true asc, false desc, NULL asc");
1866  AnalyzesOk("select d1, d2 from functional.decimal_tbl order by d1");
1867 
1868  // resolves ordinals
1869  AnalyzesOk("select zip, id from functional.testtbl order by 1");
1870  AnalyzesOk("select zip, id from functional.testtbl order by 2 desc, 1 asc");
1871  // ordinal out of range
1872  AnalysisError("select zip, id from functional.testtbl order by 0",
1873  "ORDER BY: ordinal must be >= 1");
1874  AnalysisError("select zip, id from functional.testtbl order by 3",
1875  "ORDER BY: ordinal exceeds number of items in select list: 3");
1876  AnalyzesOk("select * from functional.alltypes order by 1");
1877  // picks up select item alias
1878  AnalyzesOk("select zip z, id C, id D from functional.testtbl order by z, C, d");
1879 
1880  // can introduce additional aggregates in order by clause
1881  AnalyzesOk("select zip, count(*) from functional.testtbl group by 1 " +
1882  " order by count(*)");
1883  AnalyzesOk("select zip, count(*) from functional.testtbl " +
1884  "group by 1 order by count(*) + min(zip)");
1885  AnalysisError("select zip, count(*) from functional.testtbl group by 1 order by id",
1886  "ORDER BY expression not produced by aggregation output " +
1887  "(missing from GROUP BY clause?)");
1888 
1889  // multiple ordering exprs
1890  AnalyzesOk("select int_col, string_col, bigint_col from functional.alltypes " +
1891  "order by string_col, 15.7 * float_col, int_col + bigint_col");
1892  AnalyzesOk("select int_col, string_col, bigint_col from functional.alltypes " +
1893  "order by 2, 1, 3");
1894 
1895  // ordering by floating-point exprs is okay
1896  AnalyzesOk("select float_col, int_col + 0.5 from functional.alltypes order by 1, 2");
1897  AnalyzesOk("select float_col, int_col + 0.5 from functional.alltypes order by 2, 1");
1898 
1899  // select-list item takes precedence
1900  AnalyzesOk("select t1.int_col from functional.alltypes t1, " +
1901  "functional.alltypes t2 where t1.id = t2.id order by int_col");
1902 
1903  // same alias is not ambiguous if it refers to the same expr
1904  AnalyzesOk("select int_col, INT_COL from functional.alltypes order by int_col");
1905  AnalyzesOk("select bool_col a, bool_col A from functional.alltypes order by a");
1906  AnalyzesOk("select int_col A, bool_col b, int_col a, bool_col B " +
1907  "from functional.alltypes order by a, b");
1908  // ambiguous alias causes error
1909  AnalysisError("select string_col a, int_col a from " +
1910  "functional.alltypessmall order by a limit 1",
1911  "Column 'a' in ORDER BY clause is ambiguous");
1912  AnalysisError("select string_col a, int_col A from " +
1913  "functional.alltypessmall order by a limit 1",
1914  "Column 'a' in ORDER BY clause is ambiguous");
1915 
1916  // Test if an ignored order by produces the expected warning.
1917  AnalyzesOk("select * from (select * from functional.alltypes order by int_col) A",
1918  "Ignoring ORDER BY clause without LIMIT or OFFSET: " +
1919  "ORDER BY int_col ASC");
1920  AnalyzesOk("select * from functional.alltypes order by int_col desc union all " +
1921  "select * from functional.alltypes",
1922  "Ignoring ORDER BY clause without LIMIT or OFFSET: " +
1923  "ORDER BY int_col DESC");
1924  AnalyzesOk("insert into functional.alltypes partition (year, month) " +
1925  "select * from functional.alltypes order by int_col",
1926  "Ignoring ORDER BY clause without LIMIT or OFFSET: " +
1927  "ORDER BY int_col ASC");
1928  AnalyzesOk("create table functional.alltypescopy as " +
1929  "select * from functional.alltypes order by int_col",
1930  "Ignoring ORDER BY clause without LIMIT or OFFSET: " +
1931  "ORDER BY int_col ASC");
1932  }
1933 
1934  @Test
1935  public void TestUnion() {
1936  // Selects on different tables.
1937  AnalyzesOk("select rank() over (order by int_col) from functional.alltypes union " +
1938  "select int_col from functional.alltypessmall");
1939  // Selects on same table without aliases.
1940  AnalyzesOk("select int_col from functional.alltypes union " +
1941  "select int_col from functional.alltypes");
1942  // Longer union chain.
1943  AnalyzesOk("select int_col from functional.alltypes union " +
1944  "select int_col from functional.alltypes " +
1945  "union select int_col from functional.alltypes union " +
1946  "select int_col from functional.alltypes");
1947  // All columns, perfectly compatible.
1948  AnalyzesOk("select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
1949  "float_col, double_col, date_string_col, string_col, timestamp_col, year," +
1950  "month from functional.alltypes union " +
1951  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
1952  "float_col, double_col, date_string_col, string_col, timestamp_col, year," +
1953  "month from functional.alltypes");
1954  // Make sure table aliases aren't visible across union operands.
1955  AnalyzesOk("select a.smallint_col from functional.alltypes a " +
1956  "union select a.int_col from functional.alltypessmall a");
1957  // All columns compatible with NULL.
1958  AnalyzesOk("select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
1959  "float_col, double_col, date_string_col, string_col, timestamp_col, year," +
1960  "month from functional.alltypes union " +
1961  "select NULL, NULL, NULL, NULL, NULL, NULL, " +
1962  "NULL, NULL, NULL, NULL, NULL, NULL," +
1963  "NULL from functional.alltypes");
1964 
1965  // No from clause. Has literals and NULLs. Requires implicit casts.
1966  AnalyzesOk("select 1, 2, 3 " +
1967  "union select NULL, NULL, NULL " +
1968  "union select 1.0, NULL, 3 " +
1969  "union select NULL, 10, NULL");
1970  // Implicit casts on integer types.
1971  AnalyzesOk("select tinyint_col from functional.alltypes " +
1972  "union select smallint_col from functional.alltypes " +
1973  "union select int_col from functional.alltypes " +
1974  "union select bigint_col from functional.alltypes");
1975  // Implicit casts on float types.
1976  AnalyzesOk("select float_col from functional.alltypes union " +
1977  "select double_col from functional.alltypes");
1978  // Implicit casts on all numeric types with two columns from each select.
1979  AnalyzesOk("select tinyint_col, double_col from functional.alltypes " +
1980  "union select smallint_col, float_col from functional.alltypes " +
1981  "union select int_col, bigint_col from functional.alltypes " +
1982  "union select bigint_col, int_col from functional.alltypes " +
1983  "union select float_col, smallint_col from functional.alltypes " +
1984  "union select double_col, tinyint_col from functional.alltypes");
1985 
1986  // With order by, offset and limit.
1987  AnalyzesOk("(select int_col from functional.alltypes) " +
1988  "union (select tinyint_col from functional.alltypessmall) " +
1989  "order by int_col limit 1");
1990  AnalyzesOk("(select int_col from functional.alltypes) " +
1991  "union (select tinyint_col from functional.alltypessmall) " +
1992  "order by int_col");
1993  AnalyzesOk("(select int_col from functional.alltypes) " +
1994  "union (select tinyint_col from functional.alltypessmall) " +
1995  "order by int_col offset 5");
1996  // Order by w/o limit is ignored in the union operand below.
1997  AnalyzesOk("select int_col from functional.alltypes order by int_col " +
1998  "union (select tinyint_col from functional.alltypessmall) ");
1999  AnalysisError("select int_col from functional.alltypes order by int_col offset 5 " +
2000  "union (select tinyint_col from functional.alltypessmall) ",
2001  "Order-by with offset without limit not supported in nested queries");
2002  AnalysisError("select int_col from functional.alltypes offset 5 " +
2003  "union (select tinyint_col from functional.alltypessmall) ",
2004  "OFFSET requires an ORDER BY clause: OFFSET 5");
2005  // Order by w/o limit is ignored in the union operand below.
2006  AnalyzesOk("select int_col from functional.alltypes " +
2007  "union (select tinyint_col from functional.alltypessmall " +
2008  "order by tinyint_col) ");
2009  AnalysisError("select int_col from functional.alltypes " +
2010  "union (select tinyint_col from functional.alltypessmall " +
2011  "order by tinyint_col offset 5) ",
2012  "Order-by with offset without limit not supported in nested queries");
2013  AnalysisError("select int_col from functional.alltypes " +
2014  "union (select tinyint_col from functional.alltypessmall offset 5) ",
2015  "OFFSET requires an ORDER BY clause: OFFSET 5");
2016  // Bigger order by.
2017  AnalyzesOk("(select tinyint_col, double_col from functional.alltypes) " +
2018  "union (select smallint_col, float_col from functional.alltypes) " +
2019  "union (select int_col, bigint_col from functional.alltypes) " +
2020  "union (select bigint_col, int_col from functional.alltypes) " +
2021  "order by double_col, tinyint_col");
2022  // Multiple union operands with valid order by clauses.
2023  AnalyzesOk("select int_col from functional.alltypes order by int_col " +
2024  "union select int_col from functional.alltypes order by int_col limit 10 " +
2025  "union (select int_col from functional.alltypes " +
2026  "order by int_col limit 10 offset 5) order by int_col offset 5");
2027  // Bigger order by with ordinals.
2028  AnalyzesOk("(select tinyint_col, double_col from functional.alltypes) " +
2029  "union (select smallint_col, float_col from functional.alltypes) " +
2030  "union (select int_col, bigint_col from functional.alltypes) " +
2031  "union (select bigint_col, int_col from functional.alltypes) " +
2032  "order by 2, 1");
2033 
2034  // Unequal number of columns.
2035  AnalysisError("select int_col from functional.alltypes " +
2036  "union select int_col, float_col from functional.alltypes",
2037  "Operands have unequal number of columns:\n" +
2038  "'SELECT int_col FROM functional.alltypes' has 1 column(s)\n" +
2039  "'SELECT int_col, float_col FROM functional.alltypes' has 2 column(s)");
2040  // Unequal number of columns, longer union chain.
2041  AnalysisError("select int_col from functional.alltypes " +
2042  "union select tinyint_col from functional.alltypes " +
2043  "union select smallint_col from functional.alltypes " +
2044  "union select smallint_col, bigint_col from functional.alltypes",
2045  "Operands have unequal number of columns:\n" +
2046  "'SELECT int_col FROM functional.alltypes' has 1 column(s)\n" +
2047  "'SELECT smallint_col, bigint_col FROM functional.alltypes' has 2 column(s)");
2048  // Incompatible types.
2049  AnalysisError("select bool_col from functional.alltypes " +
2050  "union select lag(string_col) over(order by int_col) from functional.alltypes",
2051  "Incompatible return types 'BOOLEAN' and 'STRING' of exprs " +
2052  "'bool_col' and 'lag(string_col, 1, NULL)'.");
2053  // Incompatible types, longer union chain.
2054  AnalysisError("select int_col, string_col from functional.alltypes " +
2055  "union select tinyint_col, bool_col from functional.alltypes " +
2056  "union select smallint_col, int_col from functional.alltypes " +
2057  "union select smallint_col, bool_col from functional.alltypes",
2058  "Incompatible return types 'STRING' and 'BOOLEAN' of " +
2059  "exprs 'string_col' and 'bool_col'.");
2060  // Invalid ordinal in order by.
2061  AnalysisError("(select int_col from functional.alltypes) " +
2062  "union (select int_col from functional.alltypessmall) order by 2",
2063  "ORDER BY: ordinal exceeds number of items in select list: 2");
2064  // Ambiguous order by.
2065  AnalysisError("(select int_col a, string_col a from functional.alltypes) " +
2066  "union (select int_col a, string_col a " +
2067  "from functional.alltypessmall) order by a",
2068  "Column 'a' in ORDER BY clause is ambiguous");
2069  // Ambiguous alias in the second union operand should work.
2070  AnalyzesOk("(select int_col a, string_col b from functional.alltypes) " +
2071  "union (select int_col a, string_col a " +
2072  "from functional.alltypessmall) order by a");
2073  // Ambiguous alias even though the exprs of the first operand are identical
2074  // (the corresponding in exprs in the other operand are different)
2075  AnalysisError("select int_col a, int_col a from functional.alltypes " +
2076  "union all (select 1, bigint_col from functional.alltypessmall) order by a",
2077  "Column 'a' in ORDER BY clause is ambiguous");
2078 
2079  // Column labels are inherited from first select block.
2080  // Order by references an invalid column
2081  AnalysisError("(select smallint_col from functional.alltypes) " +
2082  "union (select int_col from functional.alltypessmall) order by int_col",
2083  "Could not resolve column/field reference: 'int_col'");
2084  // Make sure table aliases aren't visible across union operands.
2085  AnalysisError("select a.smallint_col from functional.alltypes a " +
2086  "union select a.int_col from functional.alltypessmall",
2087  "Could not resolve column/field reference: 'a.int_col'");
2088 
2089  // Regression test for IMPALA-1128, union of decimal and an int type that converts
2090  // to the identical decimal.
2091  AnalyzesOk("select cast(1 as bigint) union select cast(1 as decimal(19, 0))");
2092  }
2093 
2094  @Test
2095  public void TestValuesStmt() throws AnalysisException {
2096  // Values stmt with a single row.
2097  AnalyzesOk("values(1, 2, 3)");
2098  AnalyzesOk("select * from (values('a', NULL, 'c')) as t");
2099  AnalyzesOk("values(1.0, 2, NULL) union all values(1, 2.0, 3)");
2100  AnalyzesOk("insert overwrite table functional.alltypes " +
2101  "partition (year=2009, month=10)" +
2102  "values(1, true, 1, 1, 1, 1, 1.0, 1.0, 'a', 'a', cast(0 as timestamp))");
2103  AnalyzesOk("insert overwrite table functional.alltypes " +
2104  "partition (year, month) " +
2105  "values(1, true, 1, 1, 1, 1, 1.0, 1.0, 'a', 'a', cast(0 as timestamp)," +
2106  "2009, 10)");
2107  // Values stmt with multiple rows.
2108  AnalyzesOk("values((1, 2, 3), (4, 5, 6))");
2109  AnalyzesOk("select * from (values('a', 'b', 'c')) as t");
2110  AnalyzesOk("select * from (values(('a', 'b', 'c'), ('d', 'e', 'f'))) as t");
2111  AnalyzesOk("values((1.0, 2, NULL), (2.0, 3, 4)) union all values(1, 2.0, 3)");
2112  AnalyzesOk("insert overwrite table functional.alltypes " +
2113  "partition (year=2009, month=10) " +
2114  "values(" +
2115  "(1, true, 1, 1, 1, 1, 1.0, 1.0, 'a', 'a', cast(0 as timestamp))," +
2116  "(2, false, 2, 2, NULL, 2, 2.0, 2.0, 'b', 'b', cast(0 as timestamp))," +
2117  "(3, true, 3, 3, 3, 3, 3.0, 3.0, 'c', 'c', cast(0 as timestamp)))");
2118  AnalyzesOk("insert overwrite table functional.alltypes " +
2119  "partition (year, month) " +
2120  "values(" +
2121  "(1, true, 1, 1, 1, 1, 1.0, 1.0, 'a', 'a', cast(0 as timestamp), 2009, 10)," +
2122  "(2, false, 2, 2, NULL, 2, 2.0, 2.0, 'b', 'b', cast(0 as timestamp), 2009, 2)," +
2123  "(3, true, 3, 3, 3, 3, 3.0, 3.0, 'c', 'c', cast(0 as timestamp), 2009, 3))");
2124  // Test multiple aliases. Values() is like union, the column labels are 'x' and 'y'.
2125  AnalyzesOk("values((1 as x, 'a' as y), (2 as k, 'b' as j))");
2126  // Test order by, offset and limit.
2127  AnalyzesOk("values(1 as x, 'a') order by 2 limit 10");
2128  AnalyzesOk("values(1 as x, 'a' as y), (2, 'b') order by y limit 10");
2129  AnalyzesOk("values((1, 'a'), (2, 'b')) order by 1 limit 10");
2130  AnalyzesOk("values((1, 'a'), (2, 'b')) order by 2");
2131  AnalyzesOk("values((1, 'a'), (2, 'b')) order by 1 offset 5");
2132  AnalysisError("values((1, 'a'), (2, 'b')) offset 5",
2133  "OFFSET requires an ORDER BY clause: OFFSET 5");
2134 
2135  AnalysisError("values(1, 'a', 1.0, *)",
2136  "'*' expression in select list requires FROM clause.");
2137  AnalysisError("values(sum(1), 'a', 1.0)",
2138  "aggregation without a FROM clause is not allowed");
2139  AnalysisError("values(1, id, 2)",
2140  "Could not resolve column/field reference: 'id'");
2141  AnalysisError("values((1 as x, 'a' as y), (2, 'b')) order by c limit 1",
2142  "Could not resolve column/field reference: 'c'");
2143  AnalysisError("values((1, 2), (3, 4, 5))",
2144  "Operands have unequal number of columns:\n" +
2145  "'(1, 2)' has 2 column(s)\n" +
2146  "'(3, 4, 5)' has 3 column(s)");
2147  AnalysisError("values((1, 'a'), (3, 4))",
2148  "Incompatible return types 'STRING' and 'TINYINT' of exprs ''a'' and '4'");
2149  AnalysisError("insert overwrite table functional.alltypes " +
2150  "partition (year, month) " +
2151  "values(1, true, 'a', 1, 1, 1, 1.0, 1.0, 'a', 'a', cast(0 as timestamp)," +
2152  "2009, 10)",
2153  "Target table 'functional.alltypes' is incompatible with SELECT / PARTITION " +
2154  "expressions.\n" +
2155  "Expression ''a'' (type: STRING) is not compatible with column " +
2156  "'tinyint_col' (type: TINYINT)");
2157  }
2158 
2159  @Test
2160  public void TestWithClause() throws AnalysisException {
2161  // Single view in WITH clause.
2162  AnalyzesOk("with t as (select int_col x, bigint_col y from functional.alltypes) " +
2163  "select x, y from t");
2164  // Multiple views in WITH clause. Only one view is used.
2165  AnalyzesOk("with t1 as (select int_col x, bigint_col y from functional.alltypes), " +
2166  "t2 as (select 1 x , 10 y), t3 as (values(2 x , 20 y), (3, 30)), " +
2167  "t4 as (select 4 x, 40 y union all select 5, 50), " +
2168  "t5 as (select * from (values(6 x, 60 y)) as a) " +
2169  "select x, y from t3");
2170  // Multiple views in WITH clause. All views used in a union.
2171  AnalyzesOk("with t1 as (select int_col x, bigint_col y from functional.alltypes), " +
2172  "t2 as (select 1 x , 10 y), t3 as (values(2 x , 20 y), (3, 30)), " +
2173  "t4 as (select 4 x, 40 y union all select 5, 50), " +
2174  "t5 as (select * from (values(6 x, 60 y)) as a) " +
2175  "select * from t1 union all select * from t2 union all select * from t3 " +
2176  "union all select * from t4 union all select * from t5");
2177  // Multiple views in WITH clause. All views used in a join.
2178  AnalyzesOk("with t1 as (select int_col x, bigint_col y from functional.alltypes), " +
2179  "t2 as (select 1 x , 10 y), t3 as (values(2 x , 20 y), (3, 30)), " +
2180  "t4 as (select 4 x, 40 y union all select 5, 50), " +
2181  "t5 as (select * from (values(6 x, 60 y)) as a) " +
2182  "select t1.y, t2.y, t3.y, t4.y, t5.y from t1, t2, t3, t4, t5 " +
2183  "where t1.y = t2.y and t2.y = t3.y and t3.y = t4.y and t4.y = t5.y");
2184  // WITH clause in insert statement.
2185  AnalyzesOk("with t1 as (select * from functional.alltypestiny)" +
2186  "insert into functional.alltypes partition(year, month) select * from t1");
2187  // WITH clause in insert statement with a select statement that has a WITH
2188  // clause and an inline view (IMPALA-1100)
2189  AnalyzesOk("with test_ctas_1 as (select * from functional.alltypestiny) insert " +
2190  "into functional.alltypes partition (year, month) with with_1 as " +
2191  "(select t1.* from test_ctas_1 as t1 right join (select 1 as int_col " +
2192  "from functional.alltypestiny as t1) as t2 ON t2.int_col = t1.int_col) " +
2193  "select * from with_1 limit 10");
2194  // Insert with a select statement containing a WITH clause and an inline
2195  // view
2196  AnalyzesOk("insert into functional.alltypes partition (year, month) with " +
2197  "with_1 as (select t1.* from functional.alltypes as t1 right " +
2198  "join (select * from functional.alltypestiny as t1) t2 on t1.int_col = " +
2199  "t2.int_col) select * from with_1 limit 10");
2200  // WITH-clause views belong to different scopes.
2201  AnalyzesOk("with t1 as (select id from functional.alltypestiny) " +
2202  "insert into functional.alltypes partition(year, month) " +
2203  "with t1 as (select * from functional.alltypessmall) select * from t1");
2204  // WITH-clause view used in inline view.
2205  AnalyzesOk("with t1 as (select 'a') select * from (select * from t1) as t2");
2206  AnalyzesOk("with t1 as (select 'a') " +
2207  "select * from (select * from (select * from t1) as t2) as t3");
2208  // WITH-clause inside inline view.
2209  AnalyzesOk("select * from (with t1 as (values(1 x, 10 y)) select * from t1) as t2");
2210 
2211  // Test case-insensitive matching of WITH-clause views to base table refs.
2212  AnalyzesOk("with T1 as (select int_col x, bigint_col y from functional.alltypes)," +
2213  "t2 as (select 1 x , 10 y), T3 as (values(2 x , 20 y), (3, 30)), " +
2214  "t4 as (select 4 x, 40 y union all select 5, 50), " +
2215  "T5 as (select * from (values(6 x, 60 y)) as a) " +
2216  "select * from t1 union all select * from T2 union all select * from t3 " +
2217  "union all select * from T4 union all select * from t5");
2218 
2219  // Multiple WITH clauses. One for the UnionStmt and one for each union operand.
2220  AnalyzesOk("with t1 as (values('a', 'b')) " +
2221  "(with t2 as (values('c', 'd')) select * from t2) union all" +
2222  "(with t3 as (values('e', 'f')) select * from t3) order by 1 limit 1");
2223  // Multiple WITH clauses. One before the insert and one inside the query statement.
2224  AnalyzesOk("with t1 as (select * from functional.alltypestiny) " +
2225  "insert into functional.alltypes partition(year, month) " +
2226  "with t2 as (select * from functional.alltypessmall) select * from t1");
2227 
2228  // Table aliases do not conflict because they are in different scopes.
2229  // Aliases are resolved from inner-most to the outer-most scope.
2230  AnalyzesOk("with t1 as (select 'a') " +
2231  "select t2.* from (with t1 as (select 'b') select * from t1) as t2");
2232  // Table aliases do not conflict because t1 from the inline view is never used.
2233  AnalyzesOk("with t1 as (select 1), t2 as (select 2)" +
2234  "select * from functional.alltypes as t1");
2235  AnalyzesOk("with t1 as (select 1), t2 as (select 2) select * from t2 as t1");
2236  AnalyzesOk("with t1 as (select 1) select * from (select 2) as t1");
2237  // Fully-qualified table does not conflict with WITH-clause table.
2238  AnalyzesOk("with alltypes as (select * from functional.alltypes) " +
2239  "select * from functional.alltypes union all select * from alltypes");
2240 
2241  // Use a custom analyzer to change the default db to functional.
2242  // Recursion is prevented because 'alltypes' in t1 refers to the table
2243  // functional.alltypes, and 'alltypes' in the final query refers to the
2244  // view 'alltypes'.
2245  AnalyzesOk("with t1 as (select int_col x, bigint_col y from alltypes), " +
2246  "alltypes as (select x a, y b from t1)" +
2247  "select a, b from alltypes",
2248  createAnalyzer("functional"));
2249  // Recursion is prevented because of scoping rules. The inner 'complex_view'
2250  // refers to a view in the catalog.
2251  AnalyzesOk("with t1 as (select abc x, xyz y from complex_view), " +
2252  "complex_view as (select x a, y b from t1)" +
2253  "select a, b from complex_view",
2254  createAnalyzer("functional"));
2255  // Nested WITH clauses. Scoping prevents recursion.
2256  AnalyzesOk("with t1 as (with t1 as (select int_col x, bigint_col y from alltypes) " +
2257  "select x, y from t1), " +
2258  "alltypes as (select x a, y b from t1) " +
2259  "select a, b from alltypes",
2260  createAnalyzer("functional"));
2261  // Nested WITH clause inside a subquery.
2262  AnalyzesOk("with t1 as " +
2263  "(select * from (with t2 as (select * from functional.alltypes) " +
2264  "select * from t2) t3) " +
2265  "select * from t1");
2266  // Nested WITH clause inside a union stmt.
2267  AnalyzesOk("with t1 as " +
2268  "(with t2 as (values('a', 'b')) select * from t2 union all select * from t2) " +
2269  "select * from t1");
2270  // Nested WITH clause inside a union stmt's operand.
2271  AnalyzesOk("with t1 as " +
2272  "(select 'x', 'y' union all (with t2 as (values('a', 'b')) select * from t2)) " +
2273  "select * from t1");
2274 
2275  // Single WITH clause. Multiple references to same view.
2276  AnalyzesOk("with t as (select 1 x)" +
2277  "select x from t union all select x from t");
2278  // Multiple references in same select statement require aliases.
2279  AnalyzesOk("with t as (select 'a' x)" +
2280  "select t1.x, t2.x, t.x from t as t1, t as t2, t " +
2281  "where t1.x = t2.x and t2.x = t.x");
2282 
2283  // Test column labels in WITH-clause view for non-SlotRef exprs.
2284  AnalyzesOk("with t as (select int_col + 2, !bool_col from functional.alltypes) " +
2285  "select `int_col + 2`, `NOT bool_col` from t");
2286 
2287  // Test analysis of WITH clause after subquery rewrite does not pollute
2288  // global state (IMPALA-1357).
2289  AnalyzesOk("select 1 from (with w as (select 1 from functional.alltypes " +
2290  "where exists (select 1 from functional.alltypes)) select 1 from w) tt");
2291  AnalyzesOk("create table test_with as select 1 from (with w as " +
2292  "(select 1 from functional.alltypes where exists " +
2293  "(select 1 from functional.alltypes)) select 1 from w) tt");
2294  AnalyzesOk("insert into functional.alltypesnopart (id) select 1 from " +
2295  "(with w as (select 1 from functional.alltypes where exists " +
2296  "(select 1 from functional.alltypes)) select 1 from w) tt");
2297 
2298  // Conflicting table aliases in WITH clause.
2299  AnalysisError("with t1 as (select 1), t1 as (select 2) select * from t1",
2300  "Duplicate table alias: 't1'");
2301  // Check that aliases from WITH-clause views conflict with other table aliases.
2302  AnalysisError("with t1 as (select 1 x), t2 as (select 2 y)" +
2303  "select * from functional.alltypes as t1 inner join t1",
2304  "Duplicate table alias: 't1'");
2305  AnalysisError("with t1 as (select 1), t2 as (select 2) " +
2306  "select * from t2 as t1 inner join t1",
2307  "Duplicate table alias: 't1'");
2308  AnalysisError("with t1 as (select 1) select * from (select 2) as t1 inner join t1",
2309  "Duplicate table alias: 't1'");
2310  // Multiple references in same select statement require aliases.
2311  AnalysisError("with t1 as (select 'a' x) select * from t1 inner join t1",
2312  "Duplicate table alias: 't1'");
2313  // If one was given, we must use the explicit alias for column references.
2314  AnalysisError("with t1 as (select 'a' x) select t1.x from t1 as t2",
2315  "Could not resolve column/field reference: 't1.x'");
2316  // WITH-clause tables cannot be inserted into.
2317  AnalysisError("with t1 as (select 'a' x) insert into t1 values('b' x)",
2318  "Table does not exist: default.t1");
2319 
2320  // The inner alltypes_view gets resolved to the catalog view.
2321  AnalyzesOk("with alltypes_view as (select int_col x from alltypes_view) " +
2322  "select x from alltypes_view",
2323  createAnalyzer("functional"));
2324  // The inner 't' is resolved to a non-existent base table.
2325  AnalysisError("with t as (select int_col x, bigint_col y from t1) " +
2326  "select x, y from t",
2327  "Could not resolve table reference: 't1'");
2328  AnalysisError("with t as (select 1 as x, 2 as y union all select * from t) " +
2329  "select x, y from t",
2330  "Could not resolve table reference: 't'");
2331  AnalysisError("with t as (select a.* from (select * from t) as a) " +
2332  "select x, y from t",
2333  "Could not resolve table reference: 't'");
2334  // The inner 't1' in a nested WITH clause gets resolved to a non-existent base table.
2335  AnalysisError("with t1 as (with t2 as (select * from t1) select * from t2) " +
2336  "select * from t1 ",
2337  "Could not resolve table reference: 't1'");
2338  AnalysisError("with t1 as " +
2339  "(select * from (with t2 as (select * from t1) select * from t2) t3) " +
2340  "select * from t1",
2341  "Could not resolve table reference: 't1'");
2342  // The inner 't1' in the gets resolved to a non-existent base table.
2343  AnalysisError("with t1 as " +
2344  "(with t2 as (select * from t1) select * from t2 union all select * from t2)" +
2345  "select * from t1",
2346  "Could not resolve table reference: 't1'");
2347  AnalysisError("with t1 as " +
2348  "(select 'x', 'y' union all (with t2 as (select * from t1) select * from t2))" +
2349  "select * from t1",
2350  "Could not resolve table reference: 't1'");
2351  // The 't2' inside 't1's definition gets resolved to a non-existent base table.
2352  AnalysisError("with t1 as (select int_col x, bigint_col y from t2), " +
2353  "t2 as (select int_col x, bigint_col y from t1) select x, y from t1",
2354  "Could not resolve table reference: 't2'");
2355 
2356  // WITH clause with subqueries
2357  AnalyzesOk("with t as (select * from functional.alltypesagg where id in " +
2358  "(select id from functional.alltypes)) select int_col from t");
2359  AnalyzesOk("with t as (select * from functional.alltypes) select * from " +
2360  "functional.alltypesagg a where exists (select id from t where t.id = a.id)");
2361  AnalyzesOk("with t as (select * from functional.alltypes) select * from " +
2362  "functional.alltypesagg where 10 > (select count(*) from t) and " +
2363  "100 < (select max(int_col) from t)");
2364  AnalyzesOk("with t as (select * from functional.alltypes a where exists " +
2365  "(select * from functional.alltypesagg t where t.id = 1 and a.id = t.id) " +
2366  "and not exists (select * from functional.alltypesagg b where b.id = 1 " +
2367  "and b.int_col = a.int_col)) select * from t");
2368 
2369  // Deeply nested WITH clauses (see IMPALA-1106)
2370  AnalyzesOk("with with_1 as (select 1 as int_col_1), with_2 as " +
2371  "(select 1 as int_col_1 from (with with_3 as (select 1 as int_col_1 from " +
2372  "with_1) select 1 as int_col_1 from with_3) as t1) select 1 as int_col_1 " +
2373  "from with_2");
2374  AnalyzesOk("with with_1 as (select 1 as int_col_1), with_2 as (select 1 as " +
2375  "int_col_1 from (with with_3 as (select 1 as int_col_1 from with_1) " +
2376  "select 1 as int_col_1 from with_3) as t1), with_4 as (select 1 as " +
2377  "int_col_1 from with_2) select 1 as int_col_1 from with_4");
2378  AnalyzesOk("with with_1 as (select 1 as int_col_1), with_2 as (with with_3 " +
2379  "as (select 1 as int_col_1 from (with with_4 as (select 1 as int_col_1 " +
2380  "from with_1) select 1 as int_col_1 from with_4) as t1) select 1 as " +
2381  "int_col_1 from with_3) select 1 as int_col_1 from with_2");
2382 
2383  // WITH clasue with a between predicate
2384  AnalyzesOk("with with_1 as (select int_col from functional.alltypestiny " +
2385  "where int_col between 0 and 10) select * from with_1");
2386  // WITH clause with a between predicate in the select list
2387  AnalyzesOk("with with_1 as (select int_col between 0 and 10 " +
2388  "from functional.alltypestiny) select * from with_1");
2389  // WITH clause with a between predicate in the select list that
2390  // uses casting
2391  AnalyzesOk("with with_1 as (select timestamp_col between " +
2392  "cast('2001-01-01' as timestamp) and " +
2393  "(cast('2001-01-01' as timestamp) + interval 10 days) " +
2394  "from functional.alltypestiny) select * from with_1");
2395  // WITH clause with a between predicate that uses explicit casting
2396  AnalyzesOk("with with_1 as (select * from functional.alltypestiny " +
2397  "where timestamp_col between cast('2001-01-01' as timestamp) and " +
2398  "(cast('2001-01-01' as timestamp) + interval 10 days)) " +
2399  "select * from with_1");
2400  }
2401 
2402  @Test
2403  public void TestViews() throws AnalysisException {
2404  // Simple selects on our pre-defined views.
2405  AnalyzesOk("select * from functional.alltypes_view");
2406  AnalyzesOk("select x, y, z from functional.alltypes_view_sub");
2407  AnalyzesOk("select abc, xyz from functional.complex_view");
2408  // Test a view on a view.
2409  AnalyzesOk("select * from functional.view_view");
2410  // Aliases of views.
2411  AnalyzesOk("select t.x, t.y, t.z from functional.alltypes_view_sub t");
2412 
2413  // Views in a union.
2414  AnalyzesOk("select * from functional.alltypes_view_sub union all " +
2415  "select * from functional.alltypes_view_sub");
2416  // View in a subquery.
2417  AnalyzesOk("select t.* from (select * from functional.alltypes_view_sub) t");
2418  // View in a WITH-clause view.
2419  AnalyzesOk("with t as (select * from functional.complex_view) " +
2420  "select abc, xyz from t");
2421 
2422  // Complex query on a complex view with a join and an aggregate.
2423  AnalyzesOk("select sum(t1.abc), t2.xyz from functional.complex_view t1 " +
2424  "inner join functional.complex_view t2 on (t1.abc = t2.abc) " +
2425  "group by t2.xyz");
2426 
2427  // Cannot insert into a view.
2428  AnalysisError("insert into functional.alltypes_view partition(year, month) " +
2429  "select * from functional.alltypes",
2430  "Impala does not support inserting into views: functional.alltypes_view");
2431  // Cannot load into a view.
2432  AnalysisError("load data inpath '/test-warehouse/tpch.lineitem/lineitem.tbl' " +
2433  "into table functional.alltypes_view",
2434  "LOAD DATA only supported for HDFS tables: functional.alltypes_view");
2435  // Need to give view-references an explicit alias.
2436  AnalysisError("select * from functional.alltypes_view_sub " +
2437  "inner join functional.alltypes_view_sub",
2438  "Duplicate table alias: 'functional.alltypes_view_sub'");
2439  // Column names were redefined in view.
2440  AnalysisError("select int_col from functional.alltypes_view_sub",
2441  "Could not resolve column/field reference: 'int_col'");
2442  }
2443 
2444  @Test
2445  public void TestLoadData() throws AnalysisException {
2446  for (String overwrite: Lists.newArrayList("", "overwrite")) {
2447  // Load specific data file.
2448  AnalyzesOk(String.format("load data inpath '%s' %s into table tpch.lineitem",
2449  "/test-warehouse/tpch.lineitem/lineitem.tbl", overwrite));
2450 
2451  // Load files from a data directory.
2452  AnalyzesOk(String.format("load data inpath '%s' %s into table tpch.lineitem",
2453  "/test-warehouse/tpch.lineitem/", overwrite));
2454 
2455  // Load files from a data directory into a partition.
2456  AnalyzesOk(String.format("load data inpath '%s' %s into table " +
2457  "functional.alltypes partition(year=2009, month=12)",
2458  "/test-warehouse/tpch.lineitem/", overwrite));
2459 
2460  // Source directory cannot contain subdirs.
2461  AnalysisError(String.format("load data inpath '%s' %s into table tpch.lineitem",
2462  "/test-warehouse/", overwrite),
2463  "INPATH location 'hdfs://localhost:20500/test-warehouse' cannot " +
2464  "contain subdirectories.");
2465 
2466  // Source directory cannot be empty.
2467  AnalysisError(String.format("load data inpath '%s' %s into table tpch.lineitem",
2468  "/test-warehouse/emptytable", overwrite),
2469  "INPATH location 'hdfs://localhost:20500/test-warehouse/emptytable' " +
2470  "contains no visible files.");
2471 
2472  // Cannot load a hidden files.
2473  AnalysisError(String.format("load data inpath '%s' %s into table tpch.lineitem",
2474  "/test-warehouse/alltypessmall/year=2009/month=1/.hidden", overwrite),
2475  "INPATH location 'hdfs://localhost:20500/test-warehouse/alltypessmall/" +
2476  "year=2009/month=1/.hidden' points to a hidden file.");
2477  AnalysisError(String.format("load data inpath '%s' %s into table tpch.lineitem",
2478  "/test-warehouse/alltypessmall/year=2009/month=1/_hidden", overwrite),
2479  "INPATH location 'hdfs://localhost:20500/test-warehouse/alltypessmall/" +
2480  "year=2009/month=1/_hidden' points to a hidden file.");
2481 
2482  // Source directory does not exist.
2483  AnalysisError(String.format("load data inpath '%s' %s into table tpch.lineitem",
2484  "/test-warehouse/does_not_exist", overwrite),
2485  "INPATH location 'hdfs://localhost:20500/test-warehouse/does_not_exist' " +
2486  "does not exist.");
2487  // Empty source directory string
2488  AnalysisError(String.format("load data inpath '%s' %s into table tpch.lineitem",
2489  "", overwrite), "URI path cannot be empty.");
2490 
2491  // Partition spec does not exist in table.
2492  AnalysisError(String.format("load data inpath '%s' %s into table " +
2493  "functional.alltypes partition(year=123, month=10)",
2494  "/test-warehouse/tpch.lineitem/", overwrite),
2495  "Partition spec does not exist: (year=123, month=10)");
2496 
2497  // Cannot load into non-HDFS tables.
2498  AnalysisError(String.format("load data inpath '%s' %s into table " +
2499  "functional_hbase.alltypessmall",
2500  "/test-warehouse/tpch.lineitem/", overwrite),
2501  "LOAD DATA only supported for HDFS tables: functional_hbase.alltypessmall");
2502 
2503  // Load into partitioned table without specifying a partition spec.
2504  AnalysisError(String.format("load data inpath '%s' %s into table " +
2505  "functional.alltypes",
2506  "/test-warehouse/tpch.lineitem/", overwrite),
2507  "Table is partitioned but no partition spec was specified: " +
2508  "functional.alltypes");
2509 
2510  // Database/table do not exist.
2511  AnalysisError(String.format("load data inpath '%s' %s into table " +
2512  "nodb.alltypes",
2513  "/test-warehouse/tpch.lineitem/", overwrite),
2514  "Database does not exist: nodb");
2515  AnalysisError(String.format("load data inpath '%s' %s into table " +
2516  "functional.notbl",
2517  "/test-warehouse/tpch.lineitem/", overwrite),
2518  "Table does not exist: functional.notbl");
2519 
2520  // Source must be HDFS.
2521  AnalysisError(String.format("load data inpath '%s' %s into table " +
2522  "tpch.lineitem", "file:///test-warehouse/test.out", overwrite),
2523  "INPATH location 'file:/test-warehouse/test.out' must point to an " +
2524  "HDFS filesystem");
2525  AnalysisError(String.format("load data inpath '%s' %s into table " +
2526  "tpch.lineitem", "s3n://bucket/test-warehouse/test.out", overwrite),
2527  "INPATH location 's3n://bucket/test-warehouse/test.out' must point to an " +
2528  "HDFS filesystem");
2529 
2530  // File type / table type mismatch.
2531  AnalyzesOk(String.format("load data inpath '%s' %s into table " +
2532  "tpch.lineitem",
2533  "/test-warehouse/alltypes_text_lzo/year=2009/month=4", overwrite));
2534  // When table type matches, analysis passes for partitioned and unpartitioned
2535  // tables.
2536  AnalyzesOk(String.format("load data inpath '%s' %s into table " +
2537  "functional_text_lzo.alltypes partition(year=2009, month=4)",
2538  "/test-warehouse/alltypes_text_lzo/year=2009/month=4", overwrite));
2539  AnalyzesOk(String.format("load data inpath '%s' %s into table " +
2540  "functional_text_lzo.jointbl",
2541  "/test-warehouse/alltypes_text_lzo/year=2009/month=4", overwrite));
2542 
2543  // Verify with a read-only table
2544  AnalysisError(String.format("load data inpath '%s' into table " +
2545  "functional_seq.alltypes partition(year=2009, month=3)",
2546  "/test-warehouse/alltypes_seq/year=2009/month=5", overwrite),
2547  "Unable to LOAD DATA into target table (functional_seq.alltypes) because " +
2548  "Impala does not have WRITE access to HDFS location: " +
2549  "hdfs://localhost:20500/test-warehouse/alltypes_seq/year=2009/month=3");
2550  }
2551  }
2552 
2553  @Test
2554  public void TestInsert() throws AnalysisException {
2555  for (String qualifier: ImmutableList.of("INTO", "OVERWRITE")) {
2556  testInsertStatic(qualifier);
2557  testInsertDynamic(qualifier);
2558  testInsertUnpartitioned(qualifier);
2559  testInsertWithPermutation(qualifier);
2560  }
2561 
2562  // Test INSERT into a table that Impala does not have WRITE access to.
2563  AnalysisError("insert into functional_seq.alltypes partition(year, month)" +
2564  "select * from functional.alltypes",
2565  "Unable to INSERT into target table (functional_seq.alltypes) because Impala " +
2566  "does not have WRITE access to at least one HDFS path: " +
2567  "hdfs://localhost:20500/test-warehouse/alltypes_seq/year=2009/month=");
2568 
2569  // Test plan hints for partitioned Hdfs tables.
2570  AnalyzesOk("insert into functional.alltypessmall " +
2571  "partition (year, month) [shuffle] select * from functional.alltypes");
2572  AnalyzesOk("insert into table functional.alltypessmall " +
2573  "partition (year, month) [noshuffle] select * from functional.alltypes");
2574  // Multiple non-conflicting hints and case insensitivity of hints.
2575  AnalyzesOk("insert into table functional.alltypessmall " +
2576  "partition (year, month) [shuffle, ShUfFlE] select * from functional.alltypes");
2577  // Unknown plan hint. Expect a warning but no error.
2578  AnalyzesOk("insert into functional.alltypessmall " +
2579  "partition (year, month) [badhint] select * from functional.alltypes",
2580  "INSERT hint not recognized: badhint");
2581  // Conflicting plan hints.
2582  AnalysisError("insert into table functional.alltypessmall " +
2583  "partition (year, month) [shuffle, noshuffle] select * from functional.alltypes",
2584  "Conflicting INSERT hint: noshuffle");
2585  // Plan hints require a partition clause.
2586  AnalysisError("insert into table functional.alltypesnopart [shuffle] " +
2587  "select * from functional.alltypesnopart",
2588  "INSERT hints are only supported for inserting into partitioned Hdfs tables.");
2589  // Plan hints do not make sense for inserting into HBase tables.
2590  AnalysisError("insert into table functional_hbase.alltypes [shuffle] " +
2591  "select * from functional_hbase.alltypes",
2592  "INSERT hints are only supported for inserting into partitioned Hdfs tables.");
2593  }
2594 
2598  private void testInsertDynamic(String qualifier) throws AnalysisException {
2599  // Fully dynamic partitions.
2600  AnalyzesOk("insert " + qualifier + " table functional.alltypessmall " +
2601  "partition (year, month)" +
2602  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2603  "float_col, double_col, date_string_col, string_col, timestamp_col, year, " +
2604  "month from functional.alltypes");
2605  // Fully dynamic partitions with NULL literals as partitioning columns.
2606  AnalyzesOk("insert " + qualifier + " table functional.alltypessmall " +
2607  "partition (year, month)" +
2608  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2609  "float_col, double_col, date_string_col, " +
2610  "string_col, timestamp_col, NULL, NULL from functional.alltypes");
2611  // Fully dynamic partitions with NULL partition keys and column values.
2612  AnalyzesOk("insert " + qualifier + " table functional.alltypessmall " +
2613  "partition (year, month)" +
2614  "select NULL, NULL, NULL, NULL, NULL, NULL, " +
2615  "NULL, NULL, NULL, NULL, NULL, NULL, " +
2616  "NULL from functional.alltypes");
2617  // Fully dynamic partitions. Order of corresponding select list items doesn't matter,
2618  // as long as they appear at the very end of the select list.
2619  AnalyzesOk("insert " + qualifier + " table functional.alltypessmall " +
2620  "partition (year, month)" +
2621  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2622  "float_col, double_col, date_string_col, string_col, timestamp_col, month, " +
2623  "year from functional.alltypes");
2624  // Partially dynamic partitions.
2625  AnalyzesOk("insert " + qualifier + " table functional.alltypessmall " +
2626  "partition (year=2009, month)" +
2627  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2628  "float_col, double_col, date_string_col, string_col, timestamp_col, month " +
2629  "from functional.alltypes");
2630  // Partially dynamic partitions with NULL static partition key value.
2631  AnalyzesOk("insert " + qualifier + " table functional.alltypessmall " +
2632  "partition (year=NULL, month)" +
2633  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2634  "float_col, double_col, date_string_col, string_col, timestamp_col, year from " +
2635  "functional.alltypes");
2636  // Partially dynamic partitions.
2637  AnalyzesOk("insert " + qualifier + " table functional.alltypessmall " +
2638  "partition (year, month=4)" +
2639  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2640  "float_col, double_col, date_string_col, string_col, timestamp_col, year from " +
2641  "functional.alltypes");
2642  // Partially dynamic partitions with NULL static partition key value.
2643  AnalyzesOk("insert " + qualifier + " table functional.alltypessmall " +
2644  "partition (year, month=NULL)" +
2645  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2646  "float_col, double_col, date_string_col, string_col, timestamp_col, year from " +
2647  "functional.alltypes");
2648  // Partially dynamic partitions with NULL literal as column.
2649  AnalyzesOk("insert " + qualifier + " table functional.alltypessmall " +
2650  "partition (year=2009, month)" +
2651  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2652  "float_col, double_col, date_string_col, string_col, timestamp_col, NULL from " +
2653  "functional.alltypes");
2654  // Partially dynamic partitions with NULL literal as column.
2655  AnalyzesOk("insert " + qualifier + " table functional.alltypessmall " +
2656  "partition (year, month=4)" +
2657  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2658  "float_col, double_col, date_string_col, string_col, timestamp_col, NULL from " +
2659  "functional.alltypes");
2660  // Partially dynamic partitions with NULL literal in partition clause.
2661  AnalyzesOk("insert " + qualifier + " table functional.alltypessmall " +
2662  "Partition (year=2009, month=NULL)" +
2663  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2664  "float_col, double_col, date_string_col, string_col, timestamp_col " +
2665  "from functional.alltypes");
2666  // Partially dynamic partitions with NULL literal in partition clause.
2667  AnalyzesOk("insert " + qualifier + " table functional.alltypessmall " +
2668  "partition (year=NULL, month=4)" +
2669  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2670  "float_col, double_col, date_string_col, string_col, timestamp_col " +
2671  "from functional.alltypes");
2672 
2673  // Select '*' includes partitioning columns at the end.
2674  AnalyzesOk("insert " + qualifier +
2675  " table functional.alltypessmall partition (year, month)" +
2676  "select * from functional.alltypes");
2677  // No corresponding select list items of fully dynamic partitions.
2678  AnalysisError("insert " + qualifier + " table functional.alltypessmall " +
2679  "partition (year, month)" +
2680  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2681  "float_col, double_col, date_string_col, string_col, timestamp_col " +
2682  "from functional.alltypes",
2683  "Target table 'functional.alltypessmall' has more columns (13) than the " +
2684  "SELECT / VALUES clause and PARTITION clause return (11)");
2685  // No corresponding select list items of partially dynamic partitions.
2686  AnalysisError("insert " + qualifier + " table functional.alltypessmall " +
2687  "partition (year=2009, month)" +
2688  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2689  "float_col, double_col, date_string_col, string_col, timestamp_col " +
2690  "from functional.alltypes",
2691  "Target table 'functional.alltypessmall' has more columns (13) than the " +
2692  "SELECT / VALUES clause and PARTITION clause return (12)");
2693  // Non-const partition value
2694  AnalysisError("insert " + qualifier + " table functional.alltypessmall " +
2695  "partition (year=rank() over(order by int_col), month)" +
2696  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2697  "float_col, double_col, date_string_col, string_col, timestamp_col, month " +
2698  "from functional.alltypes",
2699  "Non-constant expressions are not supported as static partition-key values " +
2700  "in 'year=rank() OVER (ORDER BY int_col ASC)'");
2701 
2702  // No corresponding select list items of partially dynamic partitions.
2703  AnalysisError("insert " + qualifier + " table functional.alltypessmall " +
2704  "partition (year, month=4)" +
2705  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2706  "float_col, double_col, date_string_col, string_col, timestamp_col " +
2707  "from functional.alltypes",
2708  "Target table 'functional.alltypessmall' has more columns (13) than the " +
2709  "SELECT / VALUES clause and PARTITION clause return (12)");
2710  // Select '*' includes partitioning columns, and hence, is not union compatible.
2711  AnalysisError("insert " + qualifier + " table functional.alltypessmall " +
2712  "partition (year=2009, month=4)" +
2713  "select * from functional.alltypes",
2714  "Target table 'functional.alltypessmall' has fewer columns (13) than the " +
2715  "SELECT / VALUES clause and PARTITION clause return (15)");
2716  }
2717 
2721  private void testInsertUnpartitioned(String qualifier) throws AnalysisException {
2722  // Wrong number of columns.
2723  AnalysisError(
2724  "insert " + qualifier + " table functional.alltypesnopart " +
2725  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2726  "float_col, double_col, date_string_col, string_col from functional.alltypes",
2727  "Target table 'functional.alltypesnopart' has more columns (11) than the SELECT" +
2728  " / VALUES clause returns (10)");
2729 
2730  // Wrong number of columns.
2731  if (!qualifier.contains("OVERWRITE")) {
2732  AnalysisError("INSERT " + qualifier + " TABLE functional_hbase.alltypes " +
2733  "SELECT * FROM functional.alltypesagg",
2734  "Target table 'functional_hbase.alltypes' has fewer columns (13) than the " +
2735  "SELECT / VALUES clause returns (14)");
2736  }
2737  // Unpartitioned table without partition clause.
2738  AnalyzesOk("insert " + qualifier + " table functional.alltypesnopart " +
2739  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2740  "float_col, double_col, date_string_col, string_col, timestamp_col from " +
2741  "functional.alltypes");
2742  // All NULL column values.
2743  AnalyzesOk("insert " + qualifier + " table functional.alltypesnopart " +
2744  "select NULL, NULL, NULL, NULL, NULL, NULL, " +
2745  "NULL, NULL, NULL, NULL, NULL " +
2746  "from functional.alltypes");
2747 
2748  String hbaseQuery = "INSERT " + qualifier + " TABLE " +
2749  "functional_hbase.insertalltypesagg select id, bigint_col, bool_col, " +
2750  "date_string_col, day, double_col, float_col, int_col, month, smallint_col, " +
2751  "string_col, timestamp_col, tinyint_col, year from functional.alltypesagg";
2752 
2753  // HBase doesn't support OVERWRITE so error out if the query is
2754  // trying to do that.
2755  if (!qualifier.contains("OVERWRITE")) {
2756  AnalyzesOk(hbaseQuery);
2757  } else {
2758  AnalysisError(hbaseQuery, "HBase doesn't have a way to perform INSERT OVERWRITE");
2759  }
2760 
2761  // Unpartitioned table with partition clause
2762  AnalysisError("INSERT " + qualifier +
2763  " TABLE functional.alltypesnopart PARTITION(year=2009) " +
2764  "SELECT * FROM functional.alltypes", "PARTITION clause is only valid for INSERT" +
2765  " into partitioned table. 'functional.alltypesnopart' is not partitioned");
2766 
2767  // Unknown target DB
2768  AnalysisError("INSERT " + qualifier + " table UNKNOWNDB.alltypesnopart SELECT * " +
2769  "from functional.alltypesnopart", "Database does not exist: UNKNOWNDB");
2770  }
2771 
2775  private void testInsertStatic(String qualifier) throws AnalysisException {
2776  // Static partition.
2777  AnalyzesOk("insert " + qualifier + " table functional.alltypessmall " +
2778  "partition (year=2009, month=4)" +
2779  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2780  "float_col, double_col, date_string_col, string_col, timestamp_col " +
2781  "from functional.alltypes");
2782 
2783  // Static partition with NULL partition keys
2784  AnalyzesOk("insert " + qualifier + " table functional.alltypessmall " +
2785  "partition (year=NULL, month=NULL)" +
2786  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2787  "float_col, double_col, date_string_col, string_col, timestamp_col " +
2788  "from functional.alltypes");
2789  // Static partition with NULL column values
2790  AnalyzesOk("insert " + qualifier + " table functional.alltypessmall " +
2791  "partition (year=NULL, month=NULL)" +
2792  "select NULL, NULL, NULL, NULL, NULL, NULL, " +
2793  "NULL, NULL, NULL, NULL, NULL " +
2794  "from functional.alltypes");
2795  // Static partition with NULL partition keys.
2796  AnalyzesOk("insert " + qualifier + " table functional.alltypessmall " +
2797  "partition (year=NULL, month=NULL)" +
2798  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2799  "float_col, double_col, date_string_col, string_col, timestamp_col " +
2800  "from functional.alltypes");
2801  // Static partition with partial NULL partition keys.
2802  AnalyzesOk("insert " + qualifier + " table functional.alltypessmall " +
2803  "partition (year=2009, month=NULL)" +
2804  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2805  "float_col, double_col, date_string_col, string_col, timestamp_col " +
2806  "from functional.alltypes");
2807  // Static partition with partial NULL partition keys.
2808  AnalyzesOk("insert " + qualifier + " table functional.alltypessmall " +
2809  "partition (year=NULL, month=4)" +
2810  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2811  "float_col, double_col, date_string_col, string_col, timestamp_col " +
2812  "from functional.alltypes");
2813  // Arbitrary exprs as partition key values. Constant exprs are ok.
2814  AnalyzesOk("insert " + qualifier + " table functional.alltypessmall " +
2815  "partition (year=-1, month=cast(100*20+10 as INT))" +
2816  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2817  "float_col, double_col, date_string_col, string_col, timestamp_col " +
2818  "from functional.alltypes");
2819 
2820  // Union compatibility requires cast of select list expr in column 5
2821  // (int_col -> bigint).
2822  AnalyzesOk("insert " + qualifier + " table functional.alltypessmall " +
2823  "partition (year=2009, month=4)" +
2824  "select id, bool_col, tinyint_col, smallint_col, int_col, int_col, " +
2825  "float_col, float_col, date_string_col, string_col, timestamp_col " +
2826  "from functional.alltypes");
2827  // No partition clause given for partitioned table.
2828  AnalysisError("insert " + qualifier + " table functional.alltypessmall " +
2829  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2830  "float_col, double_col, date_string_col, string_col, timestamp_col " +
2831  "from functional.alltypes",
2832  "Not enough partition columns mentioned in query. Missing columns are: year, " +
2833  "month");
2834  // Not union compatible, unequal number of columns.
2835  AnalysisError("insert " + qualifier + " table functional.alltypessmall " +
2836  "partition (year=2009, month=4)" +
2837  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2838  "float_col, double_col, date_string_col, timestamp_col from functional.alltypes",
2839  "Target table 'functional.alltypessmall' has more columns (13) than the " +
2840  "SELECT / VALUES clause and PARTITION clause return (12)");
2841  // Not union compatible, incompatible type in last column (bool_col -> string).
2842  AnalysisError("insert " + qualifier + " table functional.alltypessmall " +
2843  "partition (year=2009, month=4)" +
2844  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2845  "float_col, double_col, date_string_col, bool_col, timestamp_col " +
2846  "from functional.alltypes",
2847  "Target table 'functional.alltypessmall' is incompatible with SELECT / " +
2848  "PARTITION expressions.\nExpression 'bool_col' (type: BOOLEAN) is not " +
2849  "compatible with column 'string_col' (type: STRING)");
2850  // Duplicate partition columns
2851  AnalysisError("insert " + qualifier + " table functional.alltypessmall " +
2852  "partition (year=2009, month=4, year=10)" +
2853  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2854  "float_col, double_col, date_string_col, string_col, timestamp_col " +
2855  "from functional.alltypes",
2856  "Duplicate column 'year' in partition clause");
2857  // Too few partitioning columns.
2858  AnalysisError("insert " + qualifier + " table functional.alltypessmall " +
2859  "partition (year=2009)" +
2860  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2861  "float_col, double_col, date_string_col, string_col, timestamp_col " +
2862  "from functional.alltypes",
2863  "Not enough partition columns mentioned in query. Missing columns are: month");
2864  // Non-partitioning column in partition clause.
2865  AnalysisError("insert " + qualifier + " table functional.alltypessmall " +
2866  "partition (year=2009, bigint_col=10)" +
2867  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2868  "float_col, double_col, date_string_col, string_col, timestamp_col " +
2869  "from functional.alltypes",
2870  "Column 'bigint_col' is not a partition column");
2871  // Loss of precision when casting in column 6 (double_col -> float).
2872  AnalysisError("insert " + qualifier + " table functional.alltypessmall " +
2873  "partition (year=2009, month=4)" +
2874  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2875  "double_col, double_col, date_string_col, string_col, timestamp_col " +
2876  "from functional.alltypes",
2877  "Possible loss of precision for target table 'functional.alltypessmall'.\n" +
2878  "Expression 'double_col' (type: DOUBLE) would need to be cast to FLOAT for " +
2879  "column 'float_col'");
2880  // Select '*' includes partitioning columns, and hence, is not union compatible.
2881  AnalysisError("insert " + qualifier + " table functional.alltypessmall " +
2882  "partition (year=2009, month=4)" +
2883  "select * from functional.alltypes",
2884  "Target table 'functional.alltypessmall' has fewer columns (13) than the " +
2885  "SELECT / VALUES clause and PARTITION clause return (15)");
2886  // Partition columns should be type-checked
2887  AnalysisError("insert " + qualifier + " table functional.alltypessmall " +
2888  "partition (year=\"should be an int\", month=4)" +
2889  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2890  "float_col, double_col, date_string_col, string_col, timestamp_col " +
2891  "from functional.alltypes",
2892  "Target table 'functional.alltypessmall' is incompatible with " +
2893  "SELECT / PARTITION expressions.");
2894  // Arbitrary exprs as partition key values. Non-constant exprs should fail.
2895  AnalysisError("insert " + qualifier + " table functional.alltypessmall " +
2896  "partition (year=-1, month=int_col)" +
2897  "select id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2898  "float_col, double_col, date_string_col, string_col, timestamp_col " +
2899  "from functional.alltypes",
2900  "Non-constant expressions are not supported as static partition-key values " +
2901  "in 'month=int_col'.");
2902 
2903  if (qualifier.contains("OVERWRITE")) {
2904  AnalysisError("insert " + qualifier + " table functional_hbase.alltypessmall " +
2905  "partition(year, month) select * from functional.alltypessmall",
2906  "PARTITION clause is not valid for INSERT into HBase tables. " +
2907  "'functional_hbase.alltypessmall' is an HBase table");
2908  }
2909  }
2910 
2911  private void testInsertWithPermutation(String qualifier) throws AnalysisException {
2912  // Duplicate column in permutation
2913  AnalysisError("insert " + qualifier + " table functional.tinytable(a, a, b)" +
2914  "values(1, 2, 3)", "Duplicate column 'a' in column permutation");
2915 
2916  // Unknown column in permutation
2917  AnalysisError("insert " + qualifier + " table functional.tinytable" +
2918  "(a, c) values(1, 2)", "Unknown column 'c' in column permutation");
2919 
2920  // Too few columns in permutation - fill with NULL values
2921  AnalyzesOk("insert " + qualifier + " table functional.tinytable(a) values('hello')");
2922 
2923  // Too many columns in select list
2924  AnalysisError("insert " + qualifier + " table functional.tinytable(a, b)" +
2925  " select 'a', 'b', 'c' from functional.alltypes",
2926  "Column permutation mentions fewer columns (2) than the SELECT / VALUES clause" +
2927  " returns (3)");
2928 
2929  // Too few columns in select list
2930  AnalysisError("insert " + qualifier + " table functional.tinytable(a, b)" +
2931  " select 'a' from functional.alltypes",
2932  "Column permutation mentions more columns (2) than the SELECT / VALUES clause" +
2933  " returns (1)");
2934 
2935  // Type error in select clause brought on by permutation. tinyint_col and string_col
2936  // are swapped in the permutation clause
2937  AnalysisError("insert " + qualifier + " table functional.alltypesnopart" +
2938  "(id, bool_col, string_col, smallint_col, int_col, bigint_col, " +
2939  "float_col, double_col, date_string_col, tinyint_col, timestamp_col)" +
2940  " select * from functional.alltypesnopart",
2941  "Target table 'functional.alltypesnopart' is incompatible with SELECT / " +
2942  "PARTITION expressions.\nExpression 'functional.alltypesnopart.tinyint_col' " +
2943  "(type: TINYINT) is not compatible with column 'string_col' (type: STRING)");
2944 
2945  // Above query should work fine if select list also permuted
2946  AnalyzesOk("insert " + qualifier + " table functional.alltypesnopart" +
2947  "(id, bool_col, string_col, smallint_col, int_col, bigint_col, " +
2948  "float_col, double_col, date_string_col, tinyint_col, timestamp_col)" +
2949  " select id, bool_col, string_col, smallint_col, int_col, bigint_col, " +
2950  "float_col, double_col, date_string_col, tinyint_col, timestamp_col" +
2951  " from functional.alltypesnopart");
2952 
2953  // Mentioning partition keys (year, month) in permutation
2954  AnalyzesOk("insert " + qualifier + " table functional.alltypes" +
2955  "(id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2956  "float_col, double_col, date_string_col, string_col, timestamp_col, " +
2957  "year, month) select * from functional.alltypes");
2958 
2959  // Duplicate mention of partition column
2960  AnalysisError("insert " + qualifier + " table functional.alltypes" +
2961  "(id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2962  "float_col, double_col, date_string_col, string_col, timestamp_col, " +
2963  "year, month) PARTITION(year) select * from functional.alltypes",
2964  "Duplicate column 'year' in partition clause");
2965 
2966  // Split partition columns between permutation and PARTITION clause. Also confirm
2967  // that dynamic columns in PARTITION clause are looked for at the end of the select
2968  // list.
2969  AnalyzesOk("insert " + qualifier + " table functional.alltypes" +
2970  "(id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
2971  "float_col, double_col, date_string_col, string_col, timestamp_col, " +
2972  "year) PARTITION(month) select * from functional.alltypes");
2973 
2974  // Split partition columns, one dynamic in permutation clause, one static in PARTITION
2975  // clause
2976  AnalyzesOk("insert " + qualifier + " table functional.alltypes(id, year)" +
2977  "PARTITION(month=2009) select 1, 2 from functional.alltypes");
2978 
2979  // Omit most columns, should default to NULL
2980  AnalyzesOk("insert " + qualifier + " table functional.alltypesnopart" +
2981  "(id, bool_col) select id, bool_col from functional.alltypesnopart");
2982 
2983  // Can't omit partition keys, they have to be mentioned somewhere
2984  AnalysisError("insert " + qualifier + " table functional.alltypes(id)" +
2985  " select id from functional.alltypes",
2986  "Not enough partition columns mentioned in query. " +
2987  "Missing columns are: year, month");
2988 
2989  // Duplicate partition columns, one with partition key
2990  AnalysisError("insert " + qualifier + " table functional.alltypes(year)" +
2991  " partition(year=2012, month=3) select 1 from functional.alltypes",
2992  "Duplicate column 'year' in partition clause");
2993 
2994  // Type error between dynamic partition column mentioned in PARTITION column and
2995  // select list (confirm that dynamic partition columns are mapped to the last select
2996  // list expressions)
2997  AnalysisError("insert " + qualifier + " table functional.alltypes" +
2998  "(id, bool_col, string_col, smallint_col, int_col, bigint_col, " +
2999  "float_col, double_col, date_string_col, tinyint_col, timestamp_col) " +
3000  "PARTITION (year, month)" +
3001  " select id, bool_col, month, smallint_col, int_col, bigint_col, " +
3002  "float_col, double_col, date_string_col, tinyint_col, timestamp_col, " +
3003  "year, string_col from functional.alltypes",
3004  "Target table 'functional.alltypes' is incompatible with SELECT / PARTITION " +
3005  "expressions.\n" +
3006  "Expression 'month' (type: INT) is not compatible with column 'string_col' " +
3007  "(type: STRING)");
3008 
3009  // Empty permutation and no query statement
3010  AnalyzesOk("insert " + qualifier + " table functional.alltypesnopart()");
3011  // Empty permutation can't receive any select list exprs
3012  AnalysisError("insert " + qualifier + " table functional.alltypesnopart() select 1",
3013  "Column permutation mentions fewer columns (0) than the SELECT / VALUES clause " +
3014  "returns (1)");
3015  // Empty permutation with static partition columns can omit query statement
3016  AnalyzesOk("insert " + qualifier + " table functional.alltypes() " +
3017  "partition(year=2012, month=1)");
3018  // No mentioned columns to receive select-list exprs
3019  AnalysisError("insert " + qualifier + " table functional.alltypes() " +
3020  "partition(year=2012, month=1) select 1",
3021  "Column permutation and PARTITION clause mention fewer columns (0) than the " +
3022  "SELECT / VALUES clause and PARTITION clause return (1)");
3023  // Can't have dynamic partition columns with no query statement
3024  AnalysisError("insert " + qualifier + " table functional.alltypes() " +
3025  "partition(year, month)",
3026  "Column permutation and PARTITION clause mention more columns (2) than the " +
3027  "SELECT / VALUES clause and PARTITION clause return (0)");
3028  // If there are select-list exprs for dynamic partition columns, empty permutation is
3029  // ok
3030  AnalyzesOk("insert " + qualifier + " table functional.alltypes() " +
3031  "partition(year, month) select 1,2 from functional.alltypes");
3032 
3033  if (!qualifier.contains("OVERWRITE")) {
3034  // Simple permutation
3035  AnalyzesOk("insert " + qualifier + " table functional_hbase.alltypesagg" +
3036  "(id, bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
3037  "float_col, double_col, date_string_col, string_col, timestamp_col) " +
3038  "select * from functional.alltypesnopart");
3039  // Too few columns in permutation
3040  AnalysisError("insert " + qualifier + " table functional_hbase.alltypesagg" +
3041  "(id, tinyint_col, smallint_col, int_col, bigint_col, " +
3042  "float_col, double_col, date_string_col, string_col) " +
3043  "select * from functional.alltypesnopart",
3044  "Column permutation mentions fewer columns (9) than the SELECT /" +
3045  " VALUES clause returns (11)");
3046  // Omitting the row-key column is an error
3047  AnalysisError("insert " + qualifier + " table functional_hbase.alltypesagg" +
3048  "(bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
3049  "float_col, double_col, date_string_col, string_col, timestamp_col) " +
3050  "select bool_col, tinyint_col, smallint_col, int_col, bigint_col, " +
3051  "float_col, double_col, date_string_col, string_col, timestamp_col from " +
3052  "functional.alltypesnopart",
3053  "Row-key column 'id' must be explicitly mentioned in column permutation.");
3054  }
3055  }
3056 
3064  @Test
3065  public void TestClone() {
3066  testNumberOfMembers(QueryStmt.class, 10);
3067  testNumberOfMembers(UnionStmt.class, 8);
3068  testNumberOfMembers(ValuesStmt.class, 0);
3069 
3070  // Also check TableRefs.
3071  testNumberOfMembers(TableRef.class, 14);
3074  }
3075 
3076  @SuppressWarnings("rawtypes")
3077  private void testNumberOfMembers(Class cl, int expectedNumMembers) {
3078  int actualNumMembers = 0;
3079  for (Field f: cl.getDeclaredFields()) {
3080  // Exclude synthetic fields such as enum jump tables that may be added at runtime.
3081  if (!f.isSynthetic()) ++actualNumMembers;
3082  }
3083  if (actualNumMembers != expectedNumMembers) {
3084  fail(String.format("The number of members in %s have changed.\n" +
3085  "Expected %s but found %s. Please modify clone() accordingly and " +
3086  "change the expected number of members in this test.",
3087  cl.getSimpleName(), expectedNumMembers, actualNumMembers));
3088  }
3089  }
3090 
3091  @Test
3092  public void TestSetQueryOption() {
3093  AnalyzesOk("set foo=true");
3094  AnalyzesOk("set");
3095  }
3096 }
void testCollectionTableRefs(String collectionTable, String collectionField)
void testStarPath(String sql, List< Integer >...expectedPhysPaths)
void TblsAnalyzeOk(String query, TableName tbl)
static final ScalarType BIGINT
Definition: Type.java:50
static final ScalarType STRING
Definition: Type.java:53
static Map< ScalarType, String > typeToLiteralValue_
Analyzer createAnalyzer(String defaultDb)
void checkExprType(String query, Type type)
void TblsAnalysisError(String query, TableName tbl, String expectedError)
void addTestUda(String name, Type retType, Type...argTypes)
PrimitiveType
Definition: types.h:27
static final ScalarType DOUBLE
Definition: Type.java:52
Table addTestTable(String createTableSql)
static final ScalarType INT
Definition: Type.java:49
uint64_t Test(T *ht, const ProbeTuple *input, uint64_t num_tuples)
static final String MAP_VALUE_FIELD_NAME
Definition: Path.java:79
void testAllTableAliases(String[] tables, String[] columns)
void testSlotRefPath(String sql, List< Integer > expectedPhysPath)
static final String ARRAY_POS_FIELD_NAME
Definition: Path.java:77
void testNumberOfMembers(Class cl, int expectedNumMembers)
static final String ARRAY_ITEM_FIELD_NAME
Definition: Path.java:76
void testTableRefPath(String sql, List< Integer > expectedPhysPath)
static final String MAP_KEY_FIELD_NAME
Definition: Path.java:78