You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ja...@apache.org on 2014/01/27 23:15:34 UTC
[18/51] [partial] Initial commit of master branch from github
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/ExistsParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/ExistsParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/ExistsParseNode.java
new file mode 100644
index 0000000..aaa1a73
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ExistsParseNode.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+import java.sql.SQLException;
+import java.util.Collections;
+import java.util.List;
+
+
+
+/**
+ *
+ * Node representing EXISTS and NOT EXISTS expressions in SQL
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public class ExistsParseNode extends BinaryParseNode {
+ private final boolean negate;
+
+ ExistsParseNode(ParseNode l, ParseNode r, boolean negate) {
+ super(l, r);
+ this.negate = negate;
+ }
+
+ public boolean isNegate() {
+ return negate;
+ }
+
+ @Override
+ public <T> T accept(ParseNodeVisitor<T> visitor) throws SQLException {
+ List<T> l = Collections.emptyList();
+ if (visitor.visitEnter(this)) {
+ l = acceptChildren(visitor);
+ }
+ return visitor.visitLeave(this, l);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/ExplainStatement.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/ExplainStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/ExplainStatement.java
new file mode 100644
index 0000000..fc437c5
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ExplainStatement.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+public class ExplainStatement implements BindableStatement {
+ private final BindableStatement statement;
+
+ public ExplainStatement(BindableStatement statement) {
+ this.statement = statement;
+ }
+
+ public BindableStatement getStatement() {
+ return statement;
+ }
+
+ @Override
+ public int getBindCount() {
+ return statement.getBindCount();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/FamilyWildcardParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/FamilyWildcardParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/FamilyWildcardParseNode.java
new file mode 100644
index 0000000..438146c
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/FamilyWildcardParseNode.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.phoenix.parse;
+
+import java.sql.SQLException;
+
+/**
+ *
+ * Node representing the selection of all columns of a family (cf.*) in the SELECT clause of SQL
+ *
+ * @author nmaillard
+ * @since 1.2
+ */
+
+public class FamilyWildcardParseNode extends NamedParseNode {
+ private final boolean isRewrite;
+
+ public FamilyWildcardParseNode(String familyName, boolean isRewrite){
+ super(familyName);
+ this.isRewrite = isRewrite;
+ }
+
+ public FamilyWildcardParseNode(FamilyWildcardParseNode familyName, boolean isRewrite){
+ super(familyName);
+ this.isRewrite = isRewrite;
+ }
+
+ @Override
+ public <T> T accept(ParseNodeVisitor<T> visitor) throws SQLException {
+ return visitor.visit(this);
+ }
+
+ public boolean isRewrite() {
+ return isRewrite;
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/FilterableStatement.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/FilterableStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/FilterableStatement.java
new file mode 100644
index 0000000..47969d9
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/FilterableStatement.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+import java.util.List;
+
+public interface FilterableStatement extends BindableStatement {
+ public HintNode getHint();
+ public ParseNode getWhere();
+ public boolean isDistinct();
+ public boolean isAggregate();
+ public List<OrderByNode> getOrderBy();
+ public LimitNode getLimit();
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/FloorParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/FloorParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/FloorParseNode.java
new file mode 100644
index 0000000..2f88bf2
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/FloorParseNode.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+import java.sql.SQLException;
+import java.util.List;
+
+import org.apache.phoenix.compile.StatementContext;
+import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.expression.function.FloorDateExpression;
+import org.apache.phoenix.expression.function.FloorDecimalExpression;
+import org.apache.phoenix.expression.function.FloorFunction;
+import org.apache.phoenix.schema.PDataType;
+import org.apache.phoenix.schema.TypeMismatchException;
+
+/**
+ * Parse node corresponding to {@link FloorFunction}.
+ * It also acts as a factory for creating the right kind of
+ * floor expression according to the data type of the
+ * first child.
+ *
+ * @author samarth.jain
+ * @since 3.0.0
+ */
+public class FloorParseNode extends FunctionParseNode {
+
+ FloorParseNode(String name, List<ParseNode> children, BuiltInFunctionInfo info) {
+ super(name, children, info);
+ }
+
+ @Override
+ public Expression create(List<Expression> children, StatementContext context) throws SQLException {
+ return getFloorExpression(children);
+ }
+
+ public static Expression getFloorExpression(List<Expression> children) throws SQLException {
+ final Expression firstChild = children.get(0);
+ final PDataType firstChildDataType = firstChild.getDataType();
+
+ //FLOOR on timestamp doesn't really care about the nanos part i.e. it just sets it to zero.
+ //Which is exactly what FloorDateExpression does too.
+ if(firstChildDataType.isCoercibleTo(PDataType.TIMESTAMP)) {
+ return FloorDateExpression.create(children);
+ } else if(firstChildDataType.isCoercibleTo(PDataType.DECIMAL)) {
+ return new FloorDecimalExpression(children);
+ } else {
+ throw TypeMismatchException.newException(firstChildDataType, "1");
+ }
+ }
+
+ /**
+ * When rounding off decimals, user need not specify the scale. In such cases,
+ * we need to prevent the function from getting evaluated as null. This is really
+ * a hack. A better way would have been if {@link org.apache.phoenix.parse.FunctionParseNode.BuiltInFunctionInfo} provided a
+ * way of associating default values for each permissible data type.
+ * Something like: @ Argument(allowedTypes={PDataType.VARCHAR, PDataType.INTEGER}, defaultValues = {"null", "1"} isConstant=true)
+ * Till then, this will have to do.
+ */
+ @Override
+ public boolean evalToNullIfParamIsNull(StatementContext context, int index) throws SQLException {
+ return index == 0;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/FunctionParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/FunctionParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/FunctionParseNode.java
new file mode 100644
index 0000000..e31a19e
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/FunctionParseNode.java
@@ -0,0 +1,422 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.http.annotation.Immutable;
+
+import com.google.common.collect.ImmutableSet;
+import org.apache.phoenix.compile.StatementContext;
+import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.expression.LiteralExpression;
+import org.apache.phoenix.expression.function.AggregateFunction;
+import org.apache.phoenix.expression.function.FunctionExpression;
+import org.apache.phoenix.schema.ArgumentTypeMismatchException;
+import org.apache.phoenix.schema.PDataType;
+import org.apache.phoenix.schema.ValueRangeExcpetion;
+import org.apache.phoenix.util.SchemaUtil;
+
+
+
+/**
+ *
+ * Node representing a function expression in SQL
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public class FunctionParseNode extends CompoundParseNode {
+ private final String name;
+ private final BuiltInFunctionInfo info;
+
+ FunctionParseNode(String name, List<ParseNode> children, BuiltInFunctionInfo info) {
+ super(children);
+ this.name = SchemaUtil.normalizeIdentifier(name);
+ this.info = info;
+ }
+
+ public BuiltInFunctionInfo getInfo() {
+ return info;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public <T> T accept(ParseNodeVisitor<T> visitor) throws SQLException {
+ List<T> l = Collections.emptyList();
+ if (visitor.visitEnter(this)) {
+ l = acceptChildren(visitor);
+ }
+ return visitor.visitLeave(this, l);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder buf = new StringBuilder(name + "(");
+ for (ParseNode child : getChildren()) {
+ buf.append(child.toString());
+ buf.append(',');
+ }
+ buf.setLength(buf.length()-1);
+ buf.append(')');
+ return buf.toString();
+ }
+
+ public boolean isAggregate() {
+ return getInfo().isAggregate();
+ }
+
+ /**
+ * Determines whether or not we can collapse a function expression to null if a required
+ * parameter is null.
+ * @param context
+ * @param index index of parameter
+ * @return true if when the parameter at index is null, the function always evaluates to null
+ * and false otherwise.
+ * @throws SQLException
+ */
+ public boolean evalToNullIfParamIsNull(StatementContext context, int index) throws SQLException {
+ return true;
+ }
+
+
+ private static Constructor<? extends FunctionParseNode> getParseNodeCtor(Class<? extends FunctionParseNode> clazz) {
+ Constructor<? extends FunctionParseNode> ctor;
+ try {
+ ctor = clazz.getDeclaredConstructor(String.class, List.class, BuiltInFunctionInfo.class);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ ctor.setAccessible(true);
+ return ctor;
+ }
+
+ private static Constructor<? extends FunctionExpression> getExpressionCtor(Class<? extends FunctionExpression> clazz) {
+ Constructor<? extends FunctionExpression> ctor;
+ try {
+ ctor = clazz.getDeclaredConstructor(List.class);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ ctor.setAccessible(true);
+ return ctor;
+ }
+
+ public List<Expression> validate(List<Expression> children, StatementContext context) throws SQLException {
+ BuiltInFunctionInfo info = this.getInfo();
+ BuiltInFunctionArgInfo[] args = info.getArgs();
+ if (args.length > children.size()) {
+ List<Expression> moreChildren = new ArrayList<Expression>(children);
+ for (int i = children.size(); i < info.getArgs().length; i++) {
+ moreChildren.add(LiteralExpression.newConstant(null, args[i].allowedTypes.length == 0 ? null : args[i].allowedTypes[0], true));
+ }
+ children = moreChildren;
+ }
+ List<ParseNode> nodeChildren = this.getChildren();
+ for (int i = 0; i < children.size(); i++) {
+ BindParseNode bindNode = null;
+ PDataType[] allowedTypes = args[i].getAllowedTypes();
+ // Check if the node is a bind parameter, and set the parameter
+ // metadata based on the function argument annotation. Check to
+ // make sure we're not looking past the end of the list of
+ // child expression nodes, which can happen if the function
+ // invocation hasn't specified all arguments and is using default
+ // values.
+ if (i < nodeChildren.size() && nodeChildren.get(i) instanceof BindParseNode) {
+ bindNode = (BindParseNode)nodeChildren.get(i);
+ }
+ // If the child type is null, then the expression is unbound.
+ // Skip any validation, since we either 1) have a default value
+ // which has already been validated, 2) attempting to get the
+ // parameter metadata, or 3) have an unbound parameter which
+ // will be detected futher downstream.
+ Expression child = children.get(i);
+ if (child.getDataType() == null /* null used explicitly in query */ || i >= nodeChildren.size() /* argument left off */) {
+ // Replace the unbound expression with the default value expression if specified
+ if (args[i].getDefaultValue() != null) {
+ Expression defaultValue = args[i].getDefaultValue();
+ children.set(i, defaultValue);
+ // Set the parameter metadata if this is a bind parameter
+ if (bindNode != null) {
+ context.getBindManager().addParamMetaData(bindNode, defaultValue);
+ }
+ } else if (bindNode != null) {
+ // Otherwise if the node is a bind parameter and we have type information
+ // based on the function argument annonation set the parameter meta data.
+ if (child.getDataType() == null) {
+ if (allowedTypes.length > 0) {
+ context.getBindManager().addParamMetaData(bindNode, LiteralExpression.newConstant(null, allowedTypes[0], true));
+ }
+ } else { // Use expression as is, since we already have the data type set
+ context.getBindManager().addParamMetaData(bindNode, child);
+ }
+ }
+ } else {
+ if (allowedTypes.length > 0) {
+ boolean isCoercible = false;
+ for (PDataType type : allowedTypes) {
+ if (child.getDataType().isCoercibleTo(type)) {
+ isCoercible = true;
+ break;
+ }
+ }
+ if (!isCoercible) {
+ throw new ArgumentTypeMismatchException(Arrays.toString(args[i].getAllowedTypes()),
+ child.getDataType().toString(), info.getName() + " argument " + (i + 1));
+ }
+ if (child instanceof LiteralExpression) {
+ LiteralExpression valueExp = (LiteralExpression) child;
+ LiteralExpression minValue = args[i].getMinValue();
+ LiteralExpression maxValue = args[i].getMaxValue();
+ if (minValue != null && minValue.getDataType().compareTo(minValue.getValue(), valueExp.getValue(), valueExp.getDataType()) > 0) {
+ throw new ValueRangeExcpetion(minValue, maxValue == null ? "" : maxValue, valueExp.getValue(), info.getName() + " argument " + (i + 1));
+ }
+ if (maxValue != null && maxValue.getDataType().compareTo(maxValue.getValue(), valueExp.getValue(), valueExp.getDataType()) < 0) {
+ throw new ValueRangeExcpetion(minValue == null ? "" : minValue, maxValue, valueExp.getValue(), info.getName() + " argument " + (i + 1));
+ }
+ }
+ }
+ if (args[i].isConstant() && ! (child instanceof LiteralExpression) ) {
+ throw new ArgumentTypeMismatchException("constant", child.toString(), info.getName() + " argument " + (i + 1));
+ }
+ if (!args[i].getAllowedValues().isEmpty()) {
+ Object value = ((LiteralExpression)child).getValue();
+ if (!args[i].getAllowedValues().contains(value.toString().toUpperCase())) {
+ throw new ArgumentTypeMismatchException(Arrays.toString(args[i].getAllowedValues().toArray(new String[0])),
+ value.toString(), info.getName() + " argument " + (i + 1));
+ }
+ }
+ }
+ }
+ return children;
+ }
+
+ /**
+ * Entry point for parser to instantiate compiled representation of built-in function
+ * @param children Compiled expressions for child nodes
+ * @param context Query context for accessing state shared across the processing of multiple clauses
+ * @return compiled representation of built-in function
+ * @throws SQLException
+ */
+ public Expression create(List<Expression> children, StatementContext context) throws SQLException {
+ try {
+ return info.getFuncCtor().newInstance(children);
+ } catch (InstantiationException e) {
+ throw new SQLException(e);
+ } catch (IllegalAccessException e) {
+ throw new SQLException(e);
+ } catch (IllegalArgumentException e) {
+ throw new SQLException(e);
+ } catch (InvocationTargetException e) {
+ if (e.getTargetException() instanceof SQLException) {
+ throw (SQLException) e.getTargetException();
+ }
+ throw new SQLException(e);
+ }
+ }
+
+ /**
+ * Marker used to indicate that a class should be used by DirectFunctionExpressionExec below
+ */
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.TYPE)
+ public
+ @interface BuiltInFunction {
+ String name();
+ Argument[] args() default {};
+ Class<? extends FunctionParseNode> nodeClass() default FunctionParseNode.class;
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.TYPE)
+ public
+ @interface Argument {
+ PDataType[] allowedTypes() default {};
+ boolean isConstant() default false;
+ String defaultValue() default "";
+ String enumeration() default "";
+ String minValue() default "";
+ String maxValue() default "";
+ }
+
+ /**
+ * Structure used to hold parse-time information about Function implementation classes
+ */
+ @Immutable
+ public static final class BuiltInFunctionInfo {
+ private final String name;
+ private final Constructor<? extends FunctionExpression> funcCtor;
+ private final Constructor<? extends FunctionParseNode> nodeCtor;
+ private final BuiltInFunctionArgInfo[] args;
+ private final boolean isAggregate;
+ private final int requiredArgCount;
+
+ BuiltInFunctionInfo(Class<? extends FunctionExpression> f, BuiltInFunction d) {
+ this.name = SchemaUtil.normalizeIdentifier(d.name());
+ this.funcCtor = d.nodeClass() == FunctionParseNode.class ? getExpressionCtor(f) : null;
+ this.nodeCtor = d.nodeClass() == FunctionParseNode.class ? null : getParseNodeCtor(d.nodeClass());
+ this.args = new BuiltInFunctionArgInfo[d.args().length];
+ int requiredArgCount = 0;
+ for (int i = 0; i < args.length; i++) {
+ this.args[i] = new BuiltInFunctionArgInfo(d.args()[i]);
+ if (requiredArgCount < i && this.args[i].getDefaultValue() != null) {
+ requiredArgCount = i;
+ }
+ }
+ this.requiredArgCount = requiredArgCount;
+ this.isAggregate = AggregateFunction.class.isAssignableFrom(f);
+ }
+
+ public int getRequiredArgCount() {
+ return requiredArgCount;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Constructor<? extends FunctionExpression> getFuncCtor() {
+ return funcCtor;
+ }
+
+ public Constructor<? extends FunctionParseNode> getNodeCtor() {
+ return nodeCtor;
+ }
+
+ public boolean isAggregate() {
+ return isAggregate;
+ }
+
+ public BuiltInFunctionArgInfo[] getArgs() {
+ return args;
+ }
+ }
+
+ @Immutable
+ public static class BuiltInFunctionArgInfo {
+ private static final PDataType[] ENUMERATION_TYPES = new PDataType[] {PDataType.VARCHAR};
+ private final PDataType[] allowedTypes;
+ private final boolean isConstant;
+ private final Set<String> allowedValues; // Enumeration of possible values
+ private final LiteralExpression defaultValue;
+ private final LiteralExpression minValue;
+ private final LiteralExpression maxValue;
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ BuiltInFunctionArgInfo(Argument argument) {
+
+ if (argument.enumeration().length() > 0) {
+ this.isConstant = true;
+ this.defaultValue = null;
+ this.minValue = null;
+ this.maxValue = null;
+ this.allowedTypes = ENUMERATION_TYPES;
+ Class<?> clazz = null;
+ String packageName = FunctionExpression.class.getPackage().getName();
+ try {
+ clazz = Class.forName(packageName + "." + argument.enumeration());
+ } catch (ClassNotFoundException e) {
+ try {
+ clazz = Class.forName(argument.enumeration());
+ } catch (ClassNotFoundException e1) {
+ }
+ }
+ if (clazz == null || !clazz.isEnum()) {
+ throw new IllegalStateException("The enumeration annotation '" + argument.enumeration() + "' does not resolve to a enumeration class");
+ }
+ Class<? extends Enum> enumClass = (Class<? extends Enum>)clazz;
+ Enum[] enums = enumClass.getEnumConstants();
+ ImmutableSet.Builder<String> builder = ImmutableSet.builder();
+ for (Enum en : enums) {
+ builder.add(en.name());
+ }
+ allowedValues = builder.build();
+ } else {
+ this.allowedValues = Collections.emptySet();
+ this.isConstant = argument.isConstant();
+ this.allowedTypes = argument.allowedTypes();
+ this.defaultValue = getExpFromConstant(argument.defaultValue());
+ this.minValue = getExpFromConstant(argument.minValue());
+ this.maxValue = getExpFromConstant(argument.maxValue());
+ }
+ }
+
+ private LiteralExpression getExpFromConstant(String strValue) {
+ LiteralExpression exp = null;
+ if (strValue.length() > 0) {
+ SQLParser parser = new SQLParser(strValue);
+ try {
+ LiteralParseNode node = parser.parseLiteral();
+ LiteralExpression defaultValue = LiteralExpression.newConstant(node.getValue(), this.allowedTypes[0], true);
+ if (this.getAllowedTypes().length > 0) {
+ for (PDataType type : this.getAllowedTypes()) {
+ if (defaultValue.getDataType() == null || defaultValue.getDataType().isCoercibleTo(type, node.getValue())) {
+ return LiteralExpression.newConstant(node.getValue(), type, true);
+ }
+ }
+ throw new IllegalStateException("Unable to coerce default value " + strValue + " to any of the allowed types of " + Arrays.toString(this.getAllowedTypes()));
+ }
+ exp = defaultValue;
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return exp;
+ }
+
+ public boolean isConstant() {
+ return isConstant;
+ }
+
+ public LiteralExpression getDefaultValue() {
+ return defaultValue;
+ }
+
+ public LiteralExpression getMinValue() {
+ return minValue;
+ }
+
+ public LiteralExpression getMaxValue() {
+ return maxValue;
+ }
+
+ public PDataType[] getAllowedTypes() {
+ return allowedTypes;
+ }
+
+ public Set<String> getAllowedValues() {
+ return allowedValues;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/GreaterThanOrEqualParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/GreaterThanOrEqualParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/GreaterThanOrEqualParseNode.java
new file mode 100644
index 0000000..4780d56
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/GreaterThanOrEqualParseNode.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+import org.apache.hadoop.hbase.filter.CompareFilter;
+import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
+
+
+/**
+ *
+ * Node representing the greater than or equal to operator (>=) in SQL
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public class GreaterThanOrEqualParseNode extends ComparisonParseNode {
+
+ GreaterThanOrEqualParseNode(ParseNode lhs, ParseNode rhs) {
+ super(lhs, rhs);
+ }
+
+ @Override
+ public CompareOp getFilterOp() {
+ return CompareFilter.CompareOp.GREATER_OR_EQUAL;
+ }
+
+
+ @Override
+ public CompareOp getInvertFilterOp() {
+ return CompareOp.LESS_OR_EQUAL;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/GreaterThanParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/GreaterThanParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/GreaterThanParseNode.java
new file mode 100644
index 0000000..ff0442b
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/GreaterThanParseNode.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+import org.apache.hadoop.hbase.filter.CompareFilter;
+import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
+
+
+/**
+ *
+ * Node representing the greater than operator (>) in SQL
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public class GreaterThanParseNode extends ComparisonParseNode {
+
+ GreaterThanParseNode(ParseNode lhs, ParseNode rhs) {
+ super(lhs, rhs);
+ }
+
+ @Override
+ public CompareOp getFilterOp() {
+ return CompareFilter.CompareOp.GREATER;
+ }
+
+ @Override
+ public CompareOp getInvertFilterOp() {
+ return CompareOp.LESS;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/HintNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/HintNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/HintNode.java
new file mode 100644
index 0000000..fa82382
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/HintNode.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.google.common.collect.ImmutableMap;
+import org.apache.phoenix.util.SchemaUtil;
+
+
+/**
+ * Node representing optimizer hints in SQL
+ */
+public class HintNode {
+ public static final HintNode EMPTY_HINT_NODE = new HintNode();
+
+ public static final char SEPARATOR = ' ';
+ public static final String PREFIX = "(";
+ public static final String SUFFIX = ")";
+ // Split on whitespace and parenthesis, keeping the parenthesis in the token array
+ private static final String SPLIT_REGEXP = "\\s+|((?<=\\" + PREFIX + ")|(?=\\" + PREFIX + "))|((?<=\\" + SUFFIX + ")|(?=\\" + SUFFIX + "))";
+
+ public enum Hint {
+ /**
+ * Forces a range scan to be used to process the query.
+ */
+ RANGE_SCAN,
+ /**
+ * Forces a skip scan to be used to process the query.
+ */
+ SKIP_SCAN,
+ /**
+ * Prevents the spawning of multiple threads during
+ * query processing.
+ */
+ NO_INTRA_REGION_PARALLELIZATION,
+ /**
+ * Prevents the usage of indexes, forcing usage
+ * of the data table for a query.
+ */
+ NO_INDEX,
+ /**
+ * Hint of the form INDEX(<table_name> <index_name>...)
+ * to suggest usage of the index if possible. The first
+ * usable index in the list of indexes will be choosen.
+ * Table and index names may be surrounded by double quotes
+ * if they are case sensitive.
+ */
+ INDEX,
+ /**
+ * All things being equal, use the data table instead of
+ * the index table when optimizing.
+ */
+ USE_DATA_OVER_INDEX_TABLE,
+ /**
+ * All things being equal, use the index table instead of
+ * the data table when optimizing.
+ */
+ USE_INDEX_OVER_DATA_TABLE,
+ };
+
+ private final Map<Hint,String> hints;
+
+ public static HintNode create(HintNode hintNode, Hint hint) {
+ return create(hintNode, hint, "");
+ }
+
+ public static HintNode create(HintNode hintNode, Hint hint, String value) {
+ Map<Hint,String> hints = new HashMap<Hint,String>(hintNode.hints);
+ hints.put(hint, value);
+ return new HintNode(hints);
+ }
+
+ private HintNode() {
+ hints = new HashMap<Hint,String>();
+ }
+
+ private HintNode(Map<Hint,String> hints) {
+ this.hints = ImmutableMap.copyOf(hints);
+ }
+
+ public HintNode(String hint) {
+ Map<Hint,String> hints = new HashMap<Hint,String>();
+ // Split on whitespace or parenthesis. We do not need to handle escaped or
+ // embedded whitespace/parenthesis, since we are parsing what will be HBase
+ // table names which are not allowed to contain whitespace or parenthesis.
+ String[] hintWords = hint.split(SPLIT_REGEXP);
+ for (int i = 0; i < hintWords.length; i++) {
+ String hintWord = hintWords[i];
+ if (hintWord.isEmpty()) {
+ continue;
+ }
+ try {
+ Hint key = Hint.valueOf(hintWord.toUpperCase());
+ String hintValue = "";
+ if (i+1 < hintWords.length && PREFIX.equals(hintWords[i+1])) {
+ StringBuffer hintValueBuf = new StringBuffer(hint.length());
+ hintValueBuf.append(PREFIX);
+ i+=2;
+ while (i < hintWords.length && !SUFFIX.equals(hintWords[i])) {
+ hintValueBuf.append(SchemaUtil.normalizeIdentifier(hintWords[i++]));
+ hintValueBuf.append(SEPARATOR);
+ }
+ // Replace trailing separator with suffix
+ hintValueBuf.replace(hintValueBuf.length()-1, hintValueBuf.length(), SUFFIX);
+ hintValue = hintValueBuf.toString();
+ }
+ String oldValue = hints.put(key, hintValue);
+ // Concatenate together any old value with the new value
+ if (oldValue != null) {
+ hints.put(key, oldValue + hintValue);
+ }
+ } catch (IllegalArgumentException e) { // Ignore unknown/invalid hints
+ }
+ }
+ this.hints = ImmutableMap.copyOf(hints);
+ }
+
+ public boolean isEmpty() {
+ return hints.isEmpty();
+ }
+
+ /**
+ * Gets the value of the hint or null if the hint is not present.
+ * @param hint the hint
+ * @return the value specified in parenthesis following the hint or null
+ * if the hint is not present.
+ *
+ */
+ public String getHint(Hint hint) {
+ return hints.get(hint);
+ }
+
+ /**
+ * Tests for the presence of a hint in a query
+ * @param hint the hint
+ * @return true if the hint is present and false otherwise
+ */
+ public boolean hasHint(Hint hint) {
+ return hints.containsKey(hint);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/InListParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/InListParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/InListParseNode.java
new file mode 100644
index 0000000..7632de7
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/InListParseNode.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+import java.sql.SQLException;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.exception.SQLExceptionInfo;
+
+
+
+/**
+ *
+ * Node representing the IN literal list expression in SQL
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public class InListParseNode extends CompoundParseNode {
+ private final boolean negate;
+
+ InListParseNode(List<ParseNode> children, boolean negate) {
+ super(children);
+ // All values in the IN must be constant. First child is the LHS
+ for (int i = 1; i < children.size(); i++) {
+ ParseNode child = children.get(i);
+ if (!child.isStateless()) {
+ throw new ParseException(new SQLExceptionInfo.Builder(SQLExceptionCode.VALUE_IN_LIST_NOT_CONSTANT)
+ .build().buildException());
+ }
+ }
+ this.negate = negate;
+ }
+
+ public boolean isNegate() {
+ return negate;
+ }
+
+ @Override
+ public <T> T accept(ParseNodeVisitor<T> visitor) throws SQLException {
+ List<T> l = Collections.emptyList();
+ if (visitor.visitEnter(this)) {
+ l = acceptChildren(visitor);
+ }
+ return visitor.visitLeave(this, l);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/InParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/InParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/InParseNode.java
new file mode 100644
index 0000000..d7708fc
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/InParseNode.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+import java.sql.SQLException;
+import java.util.Collections;
+import java.util.List;
+
+
+
+/**
+ *
+ * Node representing IN subquery expression in SQL
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public class InParseNode extends BinaryParseNode {
+ private final boolean negate;
+
+ InParseNode(ParseNode l, ParseNode r, boolean negate) {
+ super(l, r);
+ this.negate = negate;
+ }
+
+ public boolean isNegate() {
+ return negate;
+ }
+
+ @Override
+ public <T> T accept(ParseNodeVisitor<T> visitor) throws SQLException {
+ List<T> l = Collections.emptyList();
+ if (visitor.visitEnter(this)) {
+ l = acceptChildren(visitor);
+ }
+ return visitor.visitLeave(this, l);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/IndexKeyConstraint.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/IndexKeyConstraint.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/IndexKeyConstraint.java
new file mode 100644
index 0000000..6dfc744
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/IndexKeyConstraint.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+import java.util.List;
+
+import org.apache.hadoop.hbase.util.Pair;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.phoenix.schema.ColumnModifier;
+
+public class IndexKeyConstraint {
+ private final List<Pair<ColumnParseNode, ColumnModifier>> columnNameToModifier;
+
+ IndexKeyConstraint(List<Pair<ColumnParseNode, ColumnModifier>> columnNameAndModifier) {
+ this.columnNameToModifier = ImmutableList.copyOf(columnNameAndModifier);
+ }
+
+ public List<Pair<ColumnParseNode, ColumnModifier>> getColumns() {
+ return columnNameToModifier;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/IsNullParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/IsNullParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/IsNullParseNode.java
new file mode 100644
index 0000000..a1afc2e
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/IsNullParseNode.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+import java.sql.SQLException;
+import java.util.Collections;
+import java.util.List;
+
+
+
+/**
+ *
+ * Node representing the IS NULL and IS NOT NULL expressions in SQL
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public class IsNullParseNode extends UnaryParseNode {
+ private final boolean negate;
+
+ IsNullParseNode(ParseNode expr, boolean negate) {
+ super(expr);
+ this.negate = negate;
+ }
+
+ public boolean isNegate() {
+ return negate;
+ }
+
+ @Override
+ public <T> T accept(ParseNodeVisitor<T> visitor) throws SQLException {
+ List<T> l = Collections.emptyList();
+ if (visitor.visitEnter(this)) {
+ l = acceptChildren(visitor);
+ }
+ return visitor.visitLeave(this, l);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/JoinTableNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/JoinTableNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/JoinTableNode.java
new file mode 100644
index 0000000..d6f7f82
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/JoinTableNode.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+import java.sql.SQLException;
+
+
+
+/**
+ *
+ * Node representing the join specified in the FROM clause of SQL
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public class JoinTableNode extends TableNode {
+ public enum JoinType {Inner, Left, Right, Full};
+
+ private final JoinType type;
+ private final ParseNode on;
+ private final TableNode table;
+
+ JoinTableNode(JoinType type, ParseNode on, TableNode table) {
+ super(table.getAlias());
+ this.type = type;
+ this.on = on;
+ this.table = table;
+ }
+
+ public JoinType getType() {
+ return type;
+ }
+
+ public ParseNode getOnNode() {
+ return on;
+ }
+
+ public TableNode getTable() {
+ return table;
+ }
+
+ @Override
+ public void accept(TableNodeVisitor visitor) throws SQLException {
+ visitor.visit(this);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/LessThanOrEqualParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/LessThanOrEqualParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/LessThanOrEqualParseNode.java
new file mode 100644
index 0000000..4fb91dd
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/LessThanOrEqualParseNode.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+import org.apache.hadoop.hbase.filter.CompareFilter;
+import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
+
+
+/**
+ *
+ * Node representing the less than or equal to operator (<=) in SQL
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public class LessThanOrEqualParseNode extends ComparisonParseNode {
+
+ LessThanOrEqualParseNode(ParseNode lhs, ParseNode rhs) {
+ super(lhs, rhs);
+ }
+
+ @Override
+ public CompareOp getFilterOp() {
+ return CompareFilter.CompareOp.LESS_OR_EQUAL;
+ }
+
+ @Override
+ public CompareOp getInvertFilterOp() {
+ return CompareOp.GREATER_OR_EQUAL;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/LessThanParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/LessThanParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/LessThanParseNode.java
new file mode 100644
index 0000000..c9f69dc
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/LessThanParseNode.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+import org.apache.hadoop.hbase.filter.CompareFilter;
+import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
+
+
+/**
+ *
+ * Node representing the less than operator (<) in SQL
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public class LessThanParseNode extends ComparisonParseNode {
+
+ LessThanParseNode(ParseNode lhs, ParseNode rhs) {
+ super(lhs, rhs);
+ }
+
+ @Override
+ public CompareOp getFilterOp() {
+ return CompareFilter.CompareOp.LESS;
+ }
+
+ @Override
+ public CompareOp getInvertFilterOp() {
+ return CompareOp.GREATER;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/LikeParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/LikeParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/LikeParseNode.java
new file mode 100644
index 0000000..b941d56
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/LikeParseNode.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+import java.sql.SQLException;
+import java.util.Collections;
+import java.util.List;
+
+
+
+/**
+ *
+ * Node representing LIKE and NOT LIKE in SQL
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public class LikeParseNode extends BinaryParseNode {
+ private final boolean negate;
+
+ LikeParseNode(ParseNode lhs, ParseNode rhs, boolean negate) {
+ super(lhs, rhs);
+ this.negate = negate;
+ }
+
+ public boolean isNegate() {
+ return negate;
+ }
+
+ @Override
+ public <T> T accept(ParseNodeVisitor<T> visitor) throws SQLException {
+ List<T> l = Collections.emptyList();
+ if (visitor.visitEnter(this)) {
+ l = acceptChildren(visitor);
+ }
+ return visitor.visitLeave(this, l);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/LimitNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/LimitNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/LimitNode.java
new file mode 100644
index 0000000..cd4d6a9
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/LimitNode.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+
+public class LimitNode {
+ private final BindParseNode bindNode;
+ private final LiteralParseNode limitNode;
+
+ LimitNode(BindParseNode bindNode) {
+ this.bindNode = bindNode;
+ limitNode = null;
+ }
+
+ LimitNode(LiteralParseNode limitNode) {
+ this.limitNode = limitNode;
+ this.bindNode = null;
+ }
+
+ public ParseNode getLimitParseNode() {
+ return bindNode == null ? limitNode : bindNode;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/LiteralParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/LiteralParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/LiteralParseNode.java
new file mode 100644
index 0000000..25247ee
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/LiteralParseNode.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+import java.sql.SQLException;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.phoenix.schema.PDataType;
+
+
+
+/**
+ *
+ * Node representing literal expressions such as 1,2.5,'foo', and NULL in SQL
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public class LiteralParseNode extends TerminalParseNode {
+ public static final List<ParseNode> STAR = Collections.<ParseNode>singletonList(new LiteralParseNode(1));
+ public static final ParseNode NULL = new LiteralParseNode(null);
+ public static final ParseNode ZERO = new LiteralParseNode(0);
+ public static final ParseNode ONE = new LiteralParseNode(1);
+
+ private final Object value;
+ private final PDataType type;
+
+ public LiteralParseNode(Object value) {
+ this.value = value;
+ this.type = PDataType.fromLiteral(value);
+ }
+
+ public PDataType getType() {
+ return type;
+ }
+
+ public Object getValue() {
+ return value;
+ }
+
+ @Override
+ public boolean isStateless() {
+ return true;
+ }
+
+ @Override
+ public <T> T accept(ParseNodeVisitor<T> visitor) throws SQLException {
+ return visitor.visit(this);
+ }
+
+ public byte[] getBytes() {
+ return type == null ? null : type.toBytes(value);
+ }
+
+ @Override
+ public String toString() {
+ return type == PDataType.VARCHAR ? ("'" + value.toString() + "'") : value == null ? "null" : value.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/MaxAggregateParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/MaxAggregateParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/MaxAggregateParseNode.java
new file mode 100644
index 0000000..6f59a72
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/MaxAggregateParseNode.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+import java.sql.SQLException;
+import java.util.List;
+
+import org.apache.phoenix.compile.StatementContext;
+import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.expression.function.FunctionExpression;
+import org.apache.phoenix.expression.function.MaxAggregateFunction;
+
+
+public class MaxAggregateParseNode extends DelegateConstantToCountParseNode {
+
+ public MaxAggregateParseNode(String name, List<ParseNode> children, BuiltInFunctionInfo info) {
+ super(name, children, info);
+ }
+
+ @Override
+ public FunctionExpression create(List<Expression> children, StatementContext context) throws SQLException {
+ return new MaxAggregateFunction(children, getDelegateFunction(children,context));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/MinAggregateParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/MinAggregateParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/MinAggregateParseNode.java
new file mode 100644
index 0000000..f6450dd
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/MinAggregateParseNode.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+import java.sql.SQLException;
+import java.util.List;
+
+import org.apache.phoenix.compile.StatementContext;
+import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.expression.function.FunctionExpression;
+import org.apache.phoenix.expression.function.MinAggregateFunction;
+
+
+public class MinAggregateParseNode extends DelegateConstantToCountParseNode {
+
+ public MinAggregateParseNode(String name, List<ParseNode> children, BuiltInFunctionInfo info) {
+ super(name, children, info);
+ }
+
+ @Override
+ public FunctionExpression create(List<Expression> children, StatementContext context) throws SQLException {
+ return new MinAggregateFunction(children, getDelegateFunction(children,context));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/MultiplyParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/MultiplyParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/MultiplyParseNode.java
new file mode 100644
index 0000000..1b100e9
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/MultiplyParseNode.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+import java.sql.SQLException;
+import java.util.Collections;
+import java.util.List;
+
+
+
+/**
+ *
+ * Node representing multiplication in a SQL expression
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public class MultiplyParseNode extends ArithmeticParseNode {
+
+ MultiplyParseNode(List<ParseNode> children) {
+ super(children);
+ }
+
+ @Override
+ public <T> T accept(ParseNodeVisitor<T> visitor) throws SQLException {
+ List<T> l = Collections.emptyList();
+ if (visitor.visitEnter(this)) {
+ l = acceptChildren(visitor);
+ }
+ return visitor.visitLeave(this, l);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/NamedNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/NamedNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/NamedNode.java
new file mode 100644
index 0000000..9c687aa
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/NamedNode.java
@@ -0,0 +1,45 @@
+package org.apache.phoenix.parse;
+
+import org.apache.phoenix.util.SchemaUtil;
+
+public class NamedNode {
+ private final String name;
+ private final boolean isCaseSensitive;
+
+ public static NamedNode caseSensitiveNamedNode(String name) {
+ return new NamedNode(name,true);
+ }
+
+ private NamedNode(String name, boolean isCaseSensitive) {
+ this.name = name;
+ this.isCaseSensitive = isCaseSensitive;
+ }
+
+ NamedNode(String name) {
+ this.name = SchemaUtil.normalizeIdentifier(name);
+ this.isCaseSensitive = name == null ? false : SchemaUtil.isCaseSensitive(name);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public boolean isCaseSensitive() {
+ return isCaseSensitive;
+ }
+
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null) return false;
+ if (getClass() != obj.getClass()) return false;
+ NamedNode other = (NamedNode)obj;
+ return name.equals(other.name);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/NamedParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/NamedParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/NamedParseNode.java
new file mode 100644
index 0000000..bd1c6cf
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/NamedParseNode.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+
+/**
+ *
+ * Abstract node representing named nodes such as binds and column expressions in SQL
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public abstract class NamedParseNode extends TerminalParseNode{
+ private final NamedNode namedNode;
+
+ NamedParseNode(NamedParseNode node) {
+ this.namedNode = node.namedNode;
+ }
+
+ NamedParseNode(String name) {
+ this.namedNode = new NamedNode(name);
+ }
+
+ public String getName() {
+ return namedNode.getName();
+ }
+
+ public boolean isCaseSensitive() {
+ return namedNode.isCaseSensitive();
+ }
+
+ @Override
+ public String toString() {
+ return getName();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/NamedTableNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/NamedTableNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/NamedTableNode.java
new file mode 100644
index 0000000..4be546d
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/NamedTableNode.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+import java.sql.SQLException;
+import java.util.Collections;
+import java.util.List;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Node representing an explicit table reference in the FROM clause of SQL
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public class NamedTableNode extends ConcreteTableNode {
+
+ private final List<ColumnDef> dynColumns;
+
+ public static NamedTableNode create (String alias, TableName name, List<ColumnDef> dynColumns) {
+ return new NamedTableNode(alias, name, dynColumns);
+ }
+
+ NamedTableNode(String alias, TableName name) {
+ super(alias, name);
+ dynColumns = Collections.<ColumnDef> emptyList();
+ }
+
+ NamedTableNode(String alias, TableName name, List<ColumnDef> dynColumns) {
+ super(alias, name);
+ if (dynColumns != null) {
+ this.dynColumns = ImmutableList.copyOf(dynColumns);
+ } else {
+ this.dynColumns = Collections.<ColumnDef> emptyList();
+ }
+ }
+
+ @Override
+ public void accept(TableNodeVisitor visitor) throws SQLException {
+ visitor.visit(this);
+ }
+
+ public List<ColumnDef> getDynamicColumns() {
+ return dynColumns;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/NotEqualParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/NotEqualParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/NotEqualParseNode.java
new file mode 100644
index 0000000..7872275
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/NotEqualParseNode.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
+
+
+
+/**
+ *
+ * Node representing a not equal expression (!=,<>) in SQL
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public class NotEqualParseNode extends ComparisonParseNode {
+
+ NotEqualParseNode(ParseNode lhs, ParseNode rhs) {
+ super(lhs, rhs);
+ }
+
+ @Override
+ public CompareOp getFilterOp() {
+ return CompareOp.NOT_EQUAL;
+ }
+
+ @Override
+ public CompareOp getInvertFilterOp() {
+ return CompareOp.NOT_EQUAL;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/NotParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/NotParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/NotParseNode.java
new file mode 100644
index 0000000..580e7ca
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/NotParseNode.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+import java.sql.SQLException;
+import java.util.Collections;
+import java.util.List;
+
+
+
+/**
+ *
+ * Node representing the NOT in SQL
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public class NotParseNode extends UnaryParseNode {
+
+ NotParseNode(ParseNode expr) {
+ super(expr);
+ }
+
+ @Override
+ public <T> T accept(ParseNodeVisitor<T> visitor) throws SQLException {
+ List<T> l = Collections.emptyList();
+ if (visitor.visitEnter(this)) {
+ l = acceptChildren(visitor);
+ }
+ return visitor.visitLeave(this, l);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/OrParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/OrParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/OrParseNode.java
new file mode 100644
index 0000000..0fe869f
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/OrParseNode.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+import java.sql.SQLException;
+import java.util.Collections;
+import java.util.List;
+
+
+
+/**
+ *
+ * Node representing an OR in SQL
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public class OrParseNode extends CompoundParseNode {
+
+ OrParseNode(List<ParseNode> children) {
+ super(children);
+ }
+
+ @Override
+ public <T> T accept(ParseNodeVisitor<T> visitor) throws SQLException {
+ List<T> l = Collections.emptyList();
+ if (visitor.visitEnter(this)) {
+ l = acceptChildren(visitor);
+ }
+ return visitor.visitLeave(this, l);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/OrderByNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/OrderByNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/OrderByNode.java
new file mode 100644
index 0000000..6a48d10
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/OrderByNode.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+
+/**
+ *
+ * Node representing an ORDER BY clause (including asc/desc and nulls first/last) in SQL
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public final class OrderByNode {
+ private final ParseNode child;
+ private final boolean nullsLast;
+ private final boolean orderAscending;
+
+ OrderByNode(ParseNode child, boolean nullsLast, boolean orderAscending) {
+ this.child = child;
+ this.nullsLast = nullsLast;
+ this.orderAscending = orderAscending;
+ }
+
+ public boolean isNullsLast() {
+ return nullsLast;
+ }
+
+ public boolean isAscending() {
+ return orderAscending;
+ }
+
+ public ParseNode getNode() {
+ return child;
+ }
+
+ @Override
+ public String toString() {
+ return child.toString() + (orderAscending ? " asc" : " desc") + " nulls " + (nullsLast ? "last" : "first");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/OuterJoinParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/OuterJoinParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/OuterJoinParseNode.java
new file mode 100644
index 0000000..12ed92b
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/OuterJoinParseNode.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+import java.sql.SQLException;
+import java.util.Collections;
+import java.util.List;
+
+
+
+/**
+ *
+ * Node representing an outer join qualifier (+) in SQL
+ * TODO: remove Oracle specific syntax
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public class OuterJoinParseNode extends UnaryParseNode{
+ OuterJoinParseNode(ParseNode node) {
+ super(node);
+ }
+
+ @Override
+ public <T> T accept(ParseNodeVisitor<T> visitor) throws SQLException {
+ List<T> l = Collections.emptyList();
+ if (visitor.visitEnter(this)) {
+ l = acceptChildren(visitor);
+ }
+ return visitor.visitLeave(this, l);
+ }
+}