Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ExtractFromExpr.java
Go to the documentation of this file.
1 // Copyright 2014 Cloudera Inc.
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 java.util.Set;
18 
22 import com.cloudera.impala.thrift.TExtractField;
23 import com.google.common.base.Joiner;
24 import com.google.common.base.Preconditions;
25 import com.google.common.collect.ImmutableSet;
26 import com.google.common.collect.Lists;
27 
32 public class ExtractFromExpr extends FunctionCallExpr {
33 
34  // Behaves like an immutable linked hash set containing the TExtractFields in the same
35  // order as declared.
36  private static final Set<String> EXTRACT_FIELDS;
37  static {
38  ImmutableSet.Builder<String> builder = new ImmutableSet.Builder<String>();
39  for (TExtractField extractField: TExtractField.values()) {
40  if (extractField != TExtractField.INVALID_FIELD) {
41  builder.add(extractField.name());
42  }
43  }
44  EXTRACT_FIELDS = builder.build();
45  }
46 
47  public ExtractFromExpr(FunctionName fnName, String extractFieldIdent, Expr e) {
48  // Note that the arguments are swapped so that they align with the EXTRACT function.
49  // There is no EXTRACT(STRING, TIMESTAMP) function because it conflicts with
50  // EXTRACT(TIMESTAMP, STRING) if STRINGs are used for TIMESTAMPs with implicit
51  // casting.
52  super(fnName, Lists.newArrayList(e, new StringLiteral(extractFieldIdent)));
53  type_ = Type.INT;
54  }
55 
59  protected ExtractFromExpr(ExtractFromExpr other) {
60  super(other);
61  }
62 
63  @Override
64  public void analyze(Analyzer analyzer) throws AnalysisException {
65  getFnName().analyze(analyzer);
66  if (!getFnName().getFunction().equals("extract")) {
67  throw new AnalysisException("Function " + getFnName().getFunction().toUpperCase()
68  + " does not accept the keyword FROM.");
69  }
70  if ((getFnName().getDb() != null)
71  && !getFnName().getDb().equals(Catalog.BUILTINS_DB)) {
72  throw new AnalysisException("Function " + getFnName().toString() + " conflicts " +
73  "with the EXTRACT builtin.");
74  }
75  if (isAnalyzed_) return;
76  super.analyze(analyzer);
77 
78  String extractFieldIdent = ((StringLiteral)children_.get(1)).getValue();
79  Preconditions.checkNotNull(extractFieldIdent);
80  if (!EXTRACT_FIELDS.contains(extractFieldIdent.toUpperCase())) {
81  throw new AnalysisException("Time unit '" + extractFieldIdent + "' in expression '"
82  + toSql() + "' is invalid. Expected one of "
83  + Joiner.on(", ").join(EXTRACT_FIELDS) + ".");
84  }
85  }
86 
87  @Override
88  protected String getFunctionNotFoundError(Type[] argTypes) {
89  Expr e = children_.get(0);
90  return "Expression '" + e.toSql() + "' in '" + toSql() + "' has a return type of "
91  + e.getType().toSql() + " but a TIMESTAMP is required.";
92  }
93 
94  @Override
95  public String toSqlImpl() {
96  StringBuilder strBuilder = new StringBuilder();
97  strBuilder.append(getFnName().getFunction().toUpperCase());
98  strBuilder.append("(");
99  strBuilder.append(((StringLiteral)getChild(1)).getValue());
100  strBuilder.append(" FROM ");
101  strBuilder.append(getChild(0).toSql());
102  strBuilder.append(")");
103  return strBuilder.toString();
104  }
105 
106  @Override
107  public Expr clone() { return new ExtractFromExpr(this); }
108 }
static final String BUILTINS_DB
Definition: Catalog.java:61
static final ScalarType INT
Definition: Type.java:49
ExtractFromExpr(FunctionName fnName, String extractFieldIdent, Expr e)