View Javadoc

1   /*
2    * Copyright (c) 2010.  The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  
21  package org.apache.expreval.expr.compare;
22  
23  import org.apache.commons.logging.Log;
24  import org.apache.commons.logging.LogFactory;
25  import org.apache.expreval.client.InternalErrorException;
26  import org.apache.expreval.client.NullColumnValueException;
27  import org.apache.expreval.client.ResultMissingColumnException;
28  import org.apache.expreval.expr.GenericExpression;
29  import org.apache.expreval.expr.Operator;
30  import org.apache.expreval.expr.literal.BooleanLiteral;
31  import org.apache.expreval.expr.node.BooleanValue;
32  import org.apache.expreval.expr.node.GenericValue;
33  import org.apache.hadoop.hbase.filter.WritableByteArrayComparable;
34  import org.apache.hadoop.hbase.hbql.client.HBqlException;
35  import org.apache.hadoop.hbase.hbql.impl.HConnectionImpl;
36  import org.apache.hadoop.hbase.hbql.impl.InvalidServerFilterException;
37  import org.apache.hadoop.hbase.hbql.impl.InvalidTypeException;
38  import org.apache.hadoop.hbase.hbql.impl.Utils;
39  import org.apache.hadoop.hbase.hbql.io.IO;
40  import org.apache.hadoop.hbase.hbql.mapping.FieldType;
41  import org.apache.hadoop.hbase.util.Bytes;
42  
43  import java.io.IOException;
44  
45  public abstract class GenericCompare extends GenericExpression implements BooleanValue {
46  
47      private static final Log LOG = LogFactory.getLog(GenericCompare.class);
48  
49      private final Operator operator;
50  
51      protected GenericCompare(final GenericValue arg0, final Operator operator, final GenericValue arg1) {
52          super(null, arg0, arg1);
53          this.operator = operator;
54      }
55  
56      protected Operator getOperator() {
57          return this.operator;
58      }
59  
60      protected Object getValue(final int pos,
61                                final HConnectionImpl conn,
62                                final Object object) throws HBqlException,
63                                                            ResultMissingColumnException,
64                                                            NullColumnValueException {
65          return this.getExprArg(pos).getValue(conn, object);
66      }
67  
68      protected void validateArgsForCompareFilter() throws InvalidServerFilterException {
69          // One of the values must be a single column reference and the other a constant
70          if ((this.getExprArg(0).isAColumnReference() && this.getExprArg(1).isAConstant())
71              || this.getExprArg(1).isAColumnReference() && (this.getExprArg(0).isAConstant()))
72              return;
73  
74          throw new InvalidServerFilterException("Filter require a column reference and a constant");
75      }
76  
77      public GenericValue getOptimizedValue() throws HBqlException {
78          this.optimizeAllArgs();
79          if (!this.isAConstant())
80              return this;
81          else
82              try {
83                  return new BooleanLiteral(this.getValue(null, null));
84              }
85              catch (ResultMissingColumnException e) {
86                  throw new InternalErrorException("Missing column: " + e.getMessage());
87              }
88              catch (NullColumnValueException e) {
89                  throw new InternalErrorException("Null value: " + e.getMessage());
90              }
91      }
92  
93      protected Class<? extends GenericValue> validateType(final Class<? extends GenericValue> clazz) throws InvalidTypeException {
94          try {
95              this.validateParentClass(clazz,
96                                       this.getExprArg(0).validateTypes(this, false),
97                                       this.getExprArg(1).validateTypes(this, false));
98          }
99          catch (HBqlException e) {
100             e.printStackTrace();
101         }
102 
103         return BooleanValue.class;
104     }
105 
106     public String asString() {
107         final StringBuilder sbuf = new StringBuilder();
108         sbuf.append(this.getExprArg(0).asString());
109         sbuf.append(" " + this.getOperator() + " ");
110         sbuf.append(this.getExprArg(1).asString());
111         return sbuf.toString();
112     }
113 
114     protected abstract static class GenericComparable<T> extends WritableByteArrayComparable {
115 
116         private byte[] valueInBytes = null;
117         private T value;
118 
119         protected T getTypedValue() {
120             return this.value;
121         }
122 
123         protected void setTypedValue(final T value) {
124             this.value = value;
125         }
126 
127         private byte[] getValueInBytes() {
128             return this.valueInBytes;
129         }
130 
131         protected void setValueInBytes(final byte[] b) {
132             this.valueInBytes = b;
133         }
134 
135         protected void setValueInBytes(final FieldType fieldType, final Object val) throws IOException {
136             try {
137                 this.setValueInBytes(IO.getSerialization().getScalarAsBytes(fieldType, val));
138             }
139             catch (HBqlException e) {
140                 e.printStackTrace();
141                 Utils.logException(LOG, e);
142                 throw new IOException("HBqlException: " + e.getCause());
143             }
144         }
145 
146         protected boolean equalValues(final byte[] bytes) {
147             return Bytes.equals(bytes, this.getValueInBytes());
148         }
149     }
150 }