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:32 UTC

[16/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/SelectStatementRewriter.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/SelectStatementRewriter.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/SelectStatementRewriter.java
new file mode 100644
index 0000000..1d18154
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/SelectStatementRewriter.java
@@ -0,0 +1,188 @@
+/*
+ * 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.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+
+
+/**
+ * 
+ * Class that creates a new select statement by filtering out nodes.
+ * Currently only supports filtering out boolean nodes (i.e. nodes
+ * that may be ANDed and ORed together.
+ *
+ * TODO: generize this
+ * @author jtaylor
+ * @since 0.1
+ */
+public class SelectStatementRewriter extends ParseNodeRewriter {
+    
+    /**
+     * Rewrite the select statement by filtering out expression nodes from the WHERE clause
+     * @param statement the select statement from which to filter.
+     * @param removeNodes expression nodes to filter out of WHERE clause.
+     * @return new select statement
+     * @throws SQLException 
+     */
+    public static SelectStatement removeFromWhereClause(SelectStatement statement, Set<ParseNode> removeNodes) throws SQLException {
+        if (removeNodes.isEmpty()) {
+            return statement;
+        }
+        ParseNode where = statement.getWhere();
+        SelectStatementRewriter rewriter = new SelectStatementRewriter(removeNodes);
+        where = where.accept(rewriter);
+        // Return new SELECT statement with updated WHERE clause
+        return NODE_FACTORY.select(statement, where, statement.getHaving());
+    }
+    
+    /**
+     * Rewrite the select statement by filtering out expression nodes from the HAVING clause
+     * and anding them with the WHERE clause.
+     * @param statement the select statement from which to move the nodes.
+     * @param moveNodes expression nodes to filter out of HAVING clause and add to WHERE clause.
+     * @return new select statement
+     * @throws SQLException 
+     */
+    public static SelectStatement moveFromHavingToWhereClause(SelectStatement statement, Set<ParseNode> moveNodes) throws SQLException {
+        if (moveNodes.isEmpty()) {
+            return statement;
+        }
+        ParseNode andNode = NODE_FACTORY.and(new ArrayList<ParseNode>(moveNodes));
+        ParseNode having = statement.getHaving();
+        SelectStatementRewriter rewriter = new SelectStatementRewriter(moveNodes);
+        having = having.accept(rewriter);
+        ParseNode where = statement.getWhere();
+        if (where == null) {
+            where = andNode;
+        } else {
+            where = NODE_FACTORY.and(Arrays.asList(where,andNode));
+        }
+        // Return new SELECT statement with updated WHERE and HAVING clauses
+        return NODE_FACTORY.select(statement, where, having);
+    }
+    
+    private static final ParseNodeFactory NODE_FACTORY = new ParseNodeFactory();
+
+    private final Set<ParseNode> removeNodes;
+    
+    private SelectStatementRewriter(Set<ParseNode> removeNodes) {
+        this.removeNodes = removeNodes;
+    }
+    
+    private static interface CompoundNodeFactory {
+        ParseNode createNode(List<ParseNode> children);
+    }
+    
+    private boolean enterCompoundNode(ParseNode node) {
+        if (removeNodes.contains(node)) {
+            return false;
+        }
+        return true;
+    }
+    
+    private ParseNode leaveCompoundNode(CompoundParseNode node, List<ParseNode> children, CompoundNodeFactory factory) {
+        int newSize = children.size();
+        int oldSize = node.getChildren().size();
+        if (newSize == oldSize) {
+            return node;
+        } else if (newSize > 1) {
+            return factory.createNode(children);
+        } else if (newSize == 1) {
+            // TODO: keep or collapse? Maybe be helpful as context of where a problem occurs if a node could not be consumed
+            return(children.get(0));
+        } else {
+            return null;
+        }
+    }
+    
+    @Override
+    public boolean visitEnter(AndParseNode node) throws SQLException {
+        return enterCompoundNode(node);
+    }
+
+    @Override
+    public ParseNode visitLeave(AndParseNode node, List<ParseNode> nodes) throws SQLException {
+        return leaveCompoundNode(node, nodes, new CompoundNodeFactory() {
+            @Override
+            public ParseNode createNode(List<ParseNode> children) {
+                return NODE_FACTORY.and(children);
+            }
+        });
+    }
+
+    @Override
+    public boolean visitEnter(OrParseNode node) throws SQLException {
+        return enterCompoundNode(node);
+    }
+
+    @Override
+    public ParseNode visitLeave(OrParseNode node, List<ParseNode> nodes) throws SQLException {
+        return leaveCompoundNode(node, nodes, new CompoundNodeFactory() {
+            @Override
+            public ParseNode createNode(List<ParseNode> children) {
+                return NODE_FACTORY.or(children);
+            }
+        });
+    }
+    
+    @Override
+    public boolean visitEnter(ComparisonParseNode node) throws SQLException {
+        if (removeNodes.contains(node)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public ParseNode visitLeave(ComparisonParseNode node, List<ParseNode> c) throws SQLException {
+        return c.isEmpty() ? null : node;
+    }
+    
+    @Override
+    public boolean visitEnter(LikeParseNode node) throws SQLException {
+        if (removeNodes.contains(node)) {
+            return false;
+        }
+        return true;
+    }
+    
+    @Override
+    public ParseNode visitLeave(LikeParseNode node, List<ParseNode> c) throws SQLException {
+        return c.isEmpty() ? null : node;
+    }
+    
+    @Override
+    public boolean visitEnter(InListParseNode node) throws SQLException {
+        if (removeNodes.contains(node)) {
+            return false;
+        }
+        return true;
+    }
+    
+    @Override
+    public ParseNode visitLeave(InListParseNode node, List<ParseNode> c) throws SQLException {
+        return c.isEmpty() ? null : node;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/SequenceValueParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/SequenceValueParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/SequenceValueParseNode.java
new file mode 100644
index 0000000..f72d60d
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/SequenceValueParseNode.java
@@ -0,0 +1,33 @@
+package org.apache.phoenix.parse;
+
+import java.sql.SQLException;
+
+
+public class SequenceValueParseNode extends TerminalParseNode {
+    public enum Op {NEXT_VALUE, CURRENT_VALUE};
+	private final TableName tableName;
+	private final Op op;
+
+	public SequenceValueParseNode(TableName tableName, Op op) {
+		this.tableName = tableName;
+		this.op = op;
+	}
+
+	@Override
+	public <T> T accept(ParseNodeVisitor<T> visitor) throws SQLException {
+		return visitor.visit(this);
+	}
+
+	public TableName getTableName() {
+		return tableName;
+	}
+
+    @Override
+    public boolean isStateless() {
+        return true;
+    }
+
+    public Op getOp() {
+        return op;
+    }
+}
\ 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/SingleTableSQLStatement.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/SingleTableSQLStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/SingleTableSQLStatement.java
new file mode 100644
index 0000000..ec5976e
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/SingleTableSQLStatement.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;
+
+public abstract class SingleTableSQLStatement implements BindableStatement {
+    private final NamedTableNode table;
+    private final int bindCount;
+
+    public SingleTableSQLStatement(NamedTableNode table, int bindCount) {
+        this.table = table;
+        this.bindCount = bindCount;
+    }
+    
+    public NamedTableNode getTable() {
+        return table;
+    }
+
+    @Override
+    public int getBindCount() {
+        return bindCount;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/StatelessTraverseAllParseNodeVisitor.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/StatelessTraverseAllParseNodeVisitor.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/StatelessTraverseAllParseNodeVisitor.java
new file mode 100644
index 0000000..beaa2df
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/StatelessTraverseAllParseNodeVisitor.java
@@ -0,0 +1,91 @@
+package org.apache.phoenix.parse;
+
+import java.sql.SQLException;
+import java.util.List;
+
+public class StatelessTraverseAllParseNodeVisitor extends TraverseAllParseNodeVisitor<Void> {
+    @Override
+    public Void visitLeave(LikeParseNode node, List<Void> l) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public Void visitLeave(AndParseNode node, List<Void> l) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public Void visitLeave(OrParseNode node, List<Void> l) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public Void visitLeave(FunctionParseNode node, List<Void> l) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public Void visitLeave(ComparisonParseNode node, List<Void> l) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public Void visitLeave(CaseParseNode node, List<Void> l) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public Void visitLeave(AddParseNode node, List<Void> l) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public Void visitLeave(MultiplyParseNode node, List<Void> l) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public Void visitLeave(DivideParseNode node, List<Void> l) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public Void visitLeave(SubtractParseNode node, List<Void> l) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public Void visitLeave(NotParseNode node, List<Void> l) throws SQLException {
+        return null;
+    }
+    
+    @Override
+    public Void visitLeave(CastParseNode node, List<Void> l) throws SQLException {
+        return null;
+    }
+    
+    @Override
+    public Void visitLeave(InListParseNode node, List<Void> l) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public Void visitLeave(StringConcatParseNode node, List<Void> l) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public Void visitLeave(BetweenParseNode node, List<Void> l) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public Void visitLeave(RowValueConstructorParseNode node, List<Void> l) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public Void visitLeave(ArrayConstructorNode node, List<Void> l) throws SQLException {
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/StringConcatParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/StringConcatParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/StringConcatParseNode.java
new file mode 100644
index 0000000..b5134d2
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/StringConcatParseNode.java
@@ -0,0 +1,51 @@
+/*
+ * 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 || String concatenation in a SQL expression
+ *
+ * @author kmahadik
+ * @since 0.1
+ */
+public class StringConcatParseNode extends CompoundParseNode {
+
+    StringConcatParseNode(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/SubqueryParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/SubqueryParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/SubqueryParseNode.java
new file mode 100644
index 0000000..b2073df
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/SubqueryParseNode.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;
+
+
+
+/**
+ * 
+ * Node representing a subquery in SQL
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public class SubqueryParseNode extends TerminalParseNode {
+    private final SelectStatement select;
+
+    SubqueryParseNode(SelectStatement select) {
+        this.select = select;
+    }
+    
+    public SelectStatement getSelectNode() {
+        return select;
+    }
+
+    @Override
+    public <T> T accept(ParseNodeVisitor<T> visitor) throws SQLException {
+        return visitor.visit(this);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/SubtractParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/SubtractParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/SubtractParseNode.java
new file mode 100644
index 0000000..c12efef
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/SubtractParseNode.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 java.sql.SQLException;
+import java.util.Collections;
+import java.util.List;
+
+
+
+/**
+ * 
+ * Node representing subtraction in a SQL expression
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public class SubtractParseNode extends ArithmeticParseNode {
+    SubtractParseNode(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/SumAggregateParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/SumAggregateParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/SumAggregateParseNode.java
new file mode 100644
index 0000000..8669b8d
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/SumAggregateParseNode.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.SumAggregateFunction;
+
+
+public class SumAggregateParseNode extends DelegateConstantToCountParseNode {
+
+    public SumAggregateParseNode(String name, List<ParseNode> children, BuiltInFunctionInfo info) {
+        super(name, children, info);
+    }
+    
+    @Override
+    public FunctionExpression create(List<Expression> children, StatementContext context) throws SQLException {
+        return new SumAggregateFunction(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/TableName.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/TableName.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/TableName.java
new file mode 100644
index 0000000..e552592
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/TableName.java
@@ -0,0 +1,89 @@
+/*
+ * 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.phoenix.query.QueryConstants;
+import org.apache.phoenix.util.SchemaUtil;
+
+public class TableName {
+    private final String tableName;
+    private final String schemaName;
+    
+    public static TableName createNormalized(String schemaName, String tableName) {
+        schemaName = schemaName == null ? null : SchemaUtil.normalizeIdentifier(schemaName);
+        tableName = SchemaUtil.normalizeIdentifier(tableName);
+        return new TableName(schemaName, tableName);
+    }
+    
+    public static TableName create(String schemaName, String tableName) {
+        return new TableName(schemaName,tableName);
+    }
+    
+    private TableName(String schemaName, String tableName) {
+        this.schemaName = schemaName;
+        this.tableName = tableName;
+    }
+
+    public String getTableName() {
+        return tableName;
+    }
+
+    public String getSchemaName() {
+        return schemaName;
+    }
+    
+    @Override
+    public String toString() {
+        return (schemaName == null ? "" : schemaName + QueryConstants.NAME_SEPARATOR)  + tableName;
+    }
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result
+				+ ((schemaName == null) ? 0 : schemaName.hashCode());
+		result = prime * result
+				+ ((tableName == null) ? 0 : tableName.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		TableName other = (TableName) obj;
+		if (schemaName == null) {
+			if (other.schemaName != null)
+				return false;
+		} else if (!schemaName.equals(other.schemaName))
+			return false;
+		if (tableName == null) {
+			if (other.tableName != null)
+				return false;
+		} else if (!tableName.equals(other.tableName))
+			return false;
+		return true;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/TableNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/TableNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/TableNode.java
new file mode 100644
index 0000000..0eaf140
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/TableNode.java
@@ -0,0 +1,45 @@
+/*
+ * 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;
+
+
+
+/**
+ * 
+ * Abstract base class for FROM clause data sources
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public abstract class TableNode {
+    private final String alias;
+
+    TableNode(String alias) {
+        this.alias = alias;
+    }
+
+    public String getAlias() {
+        return alias;
+    }
+
+    public abstract void accept(TableNodeVisitor visitor) throws SQLException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/TableNodeVisitor.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/TableNodeVisitor.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/TableNodeVisitor.java
new file mode 100644
index 0000000..6a14da8
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/TableNodeVisitor.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;
+
+import java.sql.SQLException;
+
+
+/**
+ * 
+ * Visitor for nodes in the FROM clause
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public interface TableNodeVisitor {
+    void visit(BindTableNode boundTableNode) throws SQLException;
+    void visit(JoinTableNode joinNode) throws SQLException;
+    void visit(NamedTableNode namedTableNode) throws SQLException;
+    void visit(DerivedTableNode subselectNode) throws SQLException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/TerminalParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/TerminalParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/TerminalParseNode.java
new file mode 100644
index 0000000..2c31341
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/TerminalParseNode.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;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * 
+ * Abstract node for expressions that have no children
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public abstract class TerminalParseNode extends ParseNode {
+    @Override
+    public final List<ParseNode> getChildren() {
+        return Collections.emptyList();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/ToCharParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/ToCharParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/ToCharParseNode.java
new file mode 100644
index 0000000..ef4d390
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ToCharParseNode.java
@@ -0,0 +1,67 @@
+/*
+ * 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.text.Format;
+import java.util.List;
+
+import org.apache.phoenix.compile.StatementContext;
+import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.expression.LiteralExpression;
+import org.apache.phoenix.expression.function.FunctionArgumentType;
+import org.apache.phoenix.expression.function.FunctionExpression;
+import org.apache.phoenix.expression.function.ToCharFunction;
+import org.apache.phoenix.schema.PDataType;
+
+
+public class ToCharParseNode extends FunctionParseNode {
+
+    public ToCharParseNode(String name, List<ParseNode> children, BuiltInFunctionInfo info) {
+        super(name, children, info);
+    }
+
+    @Override
+    public FunctionExpression create(List<Expression> children, StatementContext context) throws SQLException {
+        PDataType dataType = children.get(0).getDataType();
+        String formatString = (String)((LiteralExpression)children.get(1)).getValue(); // either date or number format string
+        Format formatter;
+        FunctionArgumentType type;
+        if (dataType.isCoercibleTo(PDataType.TIMESTAMP)) {
+            if (formatString == null) {
+                formatString = context.getDateFormat();
+                formatter = context.getDateFormatter();
+            } else {
+                formatter = FunctionArgumentType.TEMPORAL.getFormatter(formatString);
+            }
+            type = FunctionArgumentType.TEMPORAL;
+        }
+        else if (dataType.isCoercibleTo(PDataType.DECIMAL)) {
+            if (formatString == null)
+                formatString = context.getNumberFormat();
+            formatter = FunctionArgumentType.NUMERIC.getFormatter(formatString);
+            type = FunctionArgumentType.NUMERIC;
+        }
+        else {
+            throw new SQLException(dataType + " type is unsupported for TO_CHAR().  Numeric and temporal types are supported.");
+        }
+        return new ToCharFunction(children, type, formatString, formatter);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/ToDateParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/ToDateParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/ToDateParseNode.java
new file mode 100644
index 0000000..9863902
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ToDateParseNode.java
@@ -0,0 +1,51 @@
+/*
+ * 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.text.Format;
+import java.util.List;
+
+import org.apache.phoenix.compile.StatementContext;
+import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.expression.LiteralExpression;
+import org.apache.phoenix.expression.function.FunctionExpression;
+import org.apache.phoenix.expression.function.ToDateFunction;
+import org.apache.phoenix.util.DateUtil;
+
+
+public class ToDateParseNode extends FunctionParseNode {
+    public ToDateParseNode(String name, List<ParseNode> children, BuiltInFunctionInfo info) {
+        super(name, children, info);
+    }
+
+    @Override
+    public FunctionExpression create(List<Expression> children, StatementContext context) throws SQLException {
+        Format dateParser;
+        String dateFormat = (String)((LiteralExpression)children.get(1)).getValue();
+        if (dateFormat == null) {
+            dateFormat = context.getDateFormat();
+            dateParser = context.getDateParser();
+        } else {
+            dateParser = DateUtil.getDateParser(dateFormat);
+        }
+        return new ToDateFunction(children, dateFormat, dateParser);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/ToNumberParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/ToNumberParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/ToNumberParseNode.java
new file mode 100644
index 0000000..cb2d149
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ToNumberParseNode.java
@@ -0,0 +1,49 @@
+package org.apache.phoenix.parse;
+
+import java.sql.SQLException;
+import java.text.Format;
+import java.util.List;
+
+import org.apache.phoenix.compile.StatementContext;
+import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.expression.LiteralExpression;
+import org.apache.phoenix.expression.function.FunctionArgumentType;
+import org.apache.phoenix.expression.function.FunctionExpression;
+import org.apache.phoenix.expression.function.ToNumberFunction;
+import org.apache.phoenix.schema.PDataType;
+
+public class ToNumberParseNode extends FunctionParseNode {
+
+    ToNumberParseNode(String name, List<ParseNode> children,
+            BuiltInFunctionInfo info) {
+        super(name, children, info);
+    }
+
+    @Override
+    public FunctionExpression create(List<Expression> children, StatementContext context) throws SQLException {
+        PDataType dataType = children.get(0).getDataType();
+        String formatString = (String)((LiteralExpression)children.get(1)).getValue(); // either date or number format string
+        Format formatter =  null;
+        FunctionArgumentType type;
+        
+        if (dataType.isCoercibleTo(PDataType.TIMESTAMP)) {
+            if (formatString == null) {
+                formatString = context.getDateFormat();
+                formatter = context.getDateFormatter();
+            } else {
+                formatter = FunctionArgumentType.TEMPORAL.getFormatter(formatString);
+            }
+            type = FunctionArgumentType.TEMPORAL;
+        }
+        else if (dataType.isCoercibleTo(PDataType.CHAR)) {
+            if (formatString != null) {
+                formatter = FunctionArgumentType.CHAR.getFormatter(formatString);
+            }
+            type = FunctionArgumentType.CHAR;
+        }
+        else {
+            throw new SQLException(dataType + " type is unsupported for TO_NUMBER().  Numeric and temporal types are supported.");
+        }
+        return new ToNumberFunction(children, type, formatString, formatter);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/TraverseAllParseNodeVisitor.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/TraverseAllParseNodeVisitor.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/TraverseAllParseNodeVisitor.java
new file mode 100644
index 0000000..1a4a4e6
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/TraverseAllParseNodeVisitor.java
@@ -0,0 +1,158 @@
+/*
+ * 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;
+
+
+/**
+ * 
+ * Visitor that traverses into all parse nodes
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public abstract class TraverseAllParseNodeVisitor<T> extends BaseParseNodeVisitor<T> {
+    @Override
+    public boolean visitEnter(AndParseNode node) throws SQLException {
+        return true;
+    }
+
+    @Override
+    public boolean visitEnter(OrParseNode node) throws SQLException {
+        return true;
+    }
+
+    @Override
+    public boolean visitEnter(FunctionParseNode node) throws SQLException {
+        return true;
+    }
+
+    @Override
+    public boolean visitEnter(CaseParseNode node) throws SQLException {
+        return true;
+    }
+
+    @Override
+    public boolean visitEnter(ComparisonParseNode node) throws SQLException {
+        return true;
+    }
+    
+    @Override
+    public boolean visitEnter(LikeParseNode node) throws SQLException {
+        return true;
+    }
+    
+    @Override
+    public boolean visitEnter(NotParseNode node) throws SQLException {
+        return true;
+    }
+    
+    @Override
+    public boolean visitEnter(CastParseNode node) throws SQLException {
+        return true;
+    }
+    
+    @Override
+    public boolean visitEnter(InListParseNode node) throws SQLException {
+        return true;
+    }
+    
+    @Override
+    public boolean visitEnter(IsNullParseNode node) throws SQLException {
+        return true;
+    }
+    
+    @Override
+    public boolean visitEnter(MultiplyParseNode node) throws SQLException {
+        return true;
+    }
+    
+    @Override
+    public boolean visitEnter(SubtractParseNode node) throws SQLException {
+        return true;
+    }
+    
+    @Override
+    public boolean visitEnter(AddParseNode node) throws SQLException {
+        return true;
+    }
+    
+    @Override
+    public boolean visitEnter(DivideParseNode node) throws SQLException {
+        return true;
+    }
+
+    @Override
+    public boolean visitEnter(BetweenParseNode node) throws SQLException {
+        return true;
+    }
+    
+    @Override
+    public T visit(ColumnParseNode node) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public T visitLeave(IsNullParseNode node, List<T> l) throws SQLException {
+        return null;
+    }
+    
+    @Override
+    public T visit(LiteralParseNode node) throws SQLException {
+        return null;
+    }
+    
+    @Override
+    public T visit(BindParseNode node) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public T visit(WildcardParseNode node) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public T visit(FamilyWildcardParseNode node) throws SQLException {
+        return null;
+    }
+    
+    @Override
+    public boolean visitEnter(StringConcatParseNode node) throws SQLException {
+        return true;
+    }
+    
+    @Override
+    public boolean visitEnter(RowValueConstructorParseNode node) throws SQLException {
+        return true;
+    }
+    
+    @Override
+    public T visit(SequenceValueParseNode node) throws SQLException {			
+		return null;
+	}
+    
+    @Override
+    public boolean visitEnter(ArrayConstructorNode node) throws SQLException {
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/TraverseNoParseNodeVisitor.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/TraverseNoParseNodeVisitor.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/TraverseNoParseNodeVisitor.java
new file mode 100644
index 0000000..c3d62fd
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/TraverseNoParseNodeVisitor.java
@@ -0,0 +1,242 @@
+/*
+ * 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;
+
+
+/**
+ * 
+ * Visitor that traverses into no parse nodes
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public abstract class TraverseNoParseNodeVisitor<T> extends BaseParseNodeVisitor<T> {
+    @Override
+    public boolean visitEnter(AndParseNode node) throws SQLException {
+        return false;
+    }
+
+    @Override
+    public boolean visitEnter(OrParseNode node) throws SQLException {
+        return false;
+    }
+
+    @Override
+    public boolean visitEnter(FunctionParseNode node) throws SQLException {
+        return false;
+    }
+
+    @Override
+    public boolean visitEnter(ComparisonParseNode node) throws SQLException {
+        return false;
+    }
+    
+    @Override
+    public boolean visitEnter(CaseParseNode node) throws SQLException {
+        return false;
+    }
+
+    @Override
+    public boolean visitEnter(LikeParseNode node) throws SQLException {
+        return false;
+    }
+    
+    @Override
+    public boolean visitEnter(BetweenParseNode node) throws SQLException {
+        return false;
+    }
+    
+    @Override
+    public T visitLeave(LikeParseNode node, List<T> l) throws SQLException {
+        return null;
+    }
+    
+    @Override
+    public boolean visitEnter(NotParseNode node) throws SQLException {
+        return false;
+    }
+    
+    @Override
+    public boolean visitEnter(CastParseNode node) throws SQLException {
+        return false;
+    }
+    
+    @Override
+    public T visitLeave(NotParseNode node, List<T> l) throws SQLException {
+        return null;
+    }
+    
+    @Override
+    public T visitLeave(CastParseNode node, List<T> l) throws SQLException {
+        return null;
+    }
+    
+    @Override
+    public boolean visitEnter(InListParseNode node) throws SQLException {
+        return false;
+    }
+    
+    @Override
+    public T visitLeave(InListParseNode node, List<T> l) throws SQLException {
+        return null;
+    }
+    
+    @Override
+    public boolean visitEnter(IsNullParseNode node) throws SQLException {
+        return false;
+    }
+    
+    @Override
+    public T visitLeave(IsNullParseNode node, List<T> l) throws SQLException {
+        return null;
+    }
+    
+    @Override
+    public T visit(ColumnParseNode node) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public T visit(LiteralParseNode node) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public T visit(BindParseNode node) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public T visit(WildcardParseNode node) throws SQLException {
+        return null;
+    }
+    
+    @Override
+    public T visit(FamilyWildcardParseNode node) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public T visitLeave(AndParseNode node, List<T> l) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public T visitLeave(OrParseNode node, List<T> l) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public T visitLeave(FunctionParseNode node, List<T> l) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public T visitLeave(ComparisonParseNode node, List<T> l) throws SQLException {
+        return null;
+    }
+    
+    @Override
+    public T visitLeave(CaseParseNode node, List<T> l) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public boolean visitEnter(MultiplyParseNode node) throws SQLException {
+        return false;
+    }
+
+    @Override
+    public T visitLeave(MultiplyParseNode node, List<T> l) throws SQLException {
+        return null;
+    }
+    
+    @Override
+    public boolean visitEnter(SubtractParseNode node) throws SQLException {
+        return false;
+    }
+
+    @Override
+    public T visitLeave(SubtractParseNode node, List<T> l) throws SQLException {
+        return null;
+    }
+    
+    @Override
+    public boolean visitEnter(AddParseNode node) throws SQLException {
+        return false;
+    }
+
+    @Override
+    public T visitLeave(AddParseNode node, List<T> l) throws SQLException {
+        return null;
+    }
+    
+    @Override
+    public boolean visitEnter(DivideParseNode node) throws SQLException {
+        return false;
+    }
+
+    @Override
+    public T visitLeave(DivideParseNode node, List<T> l) throws SQLException {
+        return null;
+    }
+    @Override
+    public boolean visitEnter(StringConcatParseNode node) throws SQLException {
+        return false;
+    }
+
+    @Override
+    public T visitLeave(StringConcatParseNode node, List<T> l) throws SQLException {
+        return null;
+    }
+    
+    @Override
+    public T visitLeave(BetweenParseNode node, List<T> l) throws SQLException {
+        return null;
+    }
+    
+    @Override
+    public boolean visitEnter(RowValueConstructorParseNode node) throws SQLException {
+        return false;
+    }
+
+    @Override
+    public T visitLeave(RowValueConstructorParseNode node, List<T> l) throws SQLException {
+        return null;
+    }
+    
+    @Override
+    public T visit(SequenceValueParseNode node) throws SQLException {			
+		return null;
+	}
+
+    @Override
+    public boolean visitEnter(ArrayConstructorNode node) throws SQLException {
+        return false;
+    }
+
+    @Override
+    public T visitLeave(ArrayConstructorNode node, List<T> l) throws SQLException {
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/UnaryParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/UnaryParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/UnaryParseNode.java
new file mode 100644
index 0000000..356d047
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/UnaryParseNode.java
@@ -0,0 +1,35 @@
+/*
+ * 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.Collections;
+
+/**
+ * 
+ * Abstract node representing an expression that has a single child in SQL
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public abstract class UnaryParseNode extends CompoundParseNode {
+    UnaryParseNode(ParseNode expr) {
+        super(Collections.singletonList(expr));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/UnsupportedAllParseNodeVisitor.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/UnsupportedAllParseNodeVisitor.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/UnsupportedAllParseNodeVisitor.java
new file mode 100644
index 0000000..24bfcf5
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/UnsupportedAllParseNodeVisitor.java
@@ -0,0 +1,228 @@
+/*
+ * 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.sql.SQLFeatureNotSupportedException;
+import java.util.List;
+
+
+/**
+ * 
+ * Visitor that throws UnsupportedOperationException for every
+ * node.  Meant to be sub-classed for the case of a small subset
+ * of nodes being supported, in which case only those applicable
+ * methods would be overridden.
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+abstract public class UnsupportedAllParseNodeVisitor<E> extends BaseParseNodeVisitor<E> {
+
+    @Override
+    public E visit(ColumnParseNode node) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+
+    @Override
+    public E visit(LiteralParseNode node) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+
+	@Override
+	public boolean visitEnter(ArrayConstructorNode node) throws SQLException {
+		throw new SQLFeatureNotSupportedException(node.toString());
+	}
+
+	@Override
+	public E visitLeave(ArrayConstructorNode node, List<E> l)
+			throws SQLException {
+		throw new SQLFeatureNotSupportedException(node.toString());
+	}
+
+    @Override
+    public E visit(BindParseNode node) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+
+    @Override
+    public E visit(WildcardParseNode node) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+
+    @Override
+    public E visit(FamilyWildcardParseNode node) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+
+    @Override
+    public boolean visitEnter(AndParseNode node) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+
+    @Override
+    public boolean visitEnter(OrParseNode node) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+
+    @Override
+    public boolean visitEnter(FunctionParseNode node) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+
+    @Override
+    public boolean visitEnter(ComparisonParseNode node) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+    
+    @Override
+    public boolean visitEnter(BetweenParseNode node) throws SQLException{
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+    
+    @Override
+    public E visitLeave(AndParseNode node, List<E> l) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+    
+    @Override
+    public E visitLeave(OrParseNode node, List<E> l) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+
+    @Override
+    public E visitLeave(FunctionParseNode node, List<E> l) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+
+    @Override
+    public E visitLeave(ComparisonParseNode node, List<E> l) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+
+    @Override
+    public boolean visitEnter(LikeParseNode node) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+
+    @Override
+    public E visitLeave(LikeParseNode node, List<E> l) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+
+    @Override
+    public E visitLeave(NotParseNode node, List<E> l) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+    
+    @Override
+    public boolean visitEnter(NotParseNode node) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+    
+    @Override
+    public E visitLeave(CastParseNode node, List<E> l) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+    
+    @Override
+    public boolean visitEnter(CastParseNode node) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+    
+    @Override
+    public E visitLeave(InListParseNode node, List<E> l) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+
+    @Override
+    public E visitLeave(BetweenParseNode node, List<E> l) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+    
+    @Override
+    public boolean visitEnter(InListParseNode node) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+
+    @Override
+    public boolean visitEnter(IsNullParseNode node) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+
+    @Override
+    public E visitLeave(IsNullParseNode node, List<E> l) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+
+    @Override
+    public boolean visitEnter(AddParseNode node) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+
+    @Override
+    public E visitLeave(AddParseNode node, List<E> l) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+
+    @Override
+    public boolean visitEnter(SubtractParseNode node) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+
+    @Override
+    public E visitLeave(SubtractParseNode node, List<E> l) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+
+    @Override
+    public boolean visitEnter(MultiplyParseNode node) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+
+    @Override
+    public E visitLeave(MultiplyParseNode node, List<E> l) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+
+    @Override
+    public boolean visitEnter(DivideParseNode node) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+
+    @Override
+    public E visitLeave(DivideParseNode node, List<E> l) throws SQLException {
+        throw new SQLFeatureNotSupportedException(node.toString());
+    }
+
+    @Override
+    public List<E> newElementList(int size) {
+        return null;
+    }
+
+    @Override
+    public void addElement(List<E> a, E element) {
+    }
+    
+    @Override
+    public E visit(SequenceValueParseNode node) throws SQLException {			
+		return null;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/UpsertStatement.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/UpsertStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/UpsertStatement.java
new file mode 100644
index 0000000..777a64c
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/UpsertStatement.java
@@ -0,0 +1,54 @@
+/*
+ * 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.Collections;
+import java.util.List;
+
+public class UpsertStatement extends SingleTableSQLStatement { 
+    private final List<ColumnName> columns;
+    private final List<ParseNode> values;
+    private final SelectStatement select;
+    private final HintNode hint;
+
+    public UpsertStatement(NamedTableNode table, HintNode hint, List<ColumnName> columns, List<ParseNode> values, SelectStatement select, int bindCount) {
+        super(table, bindCount);
+        this.columns = columns == null ? Collections.<ColumnName>emptyList() : columns;
+        this.values = values;
+        this.select = select;
+        this.hint = hint == null ? HintNode.EMPTY_HINT_NODE : hint;
+    }
+
+    public List<ColumnName> getColumns() {
+        return columns;
+    }
+
+    public List<ParseNode> getValues() {
+        return values;
+    }
+
+    public SelectStatement getSelect() {
+        return select;
+    }
+
+    public HintNode getHint() {
+        return hint;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/parse/WildcardParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/WildcardParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/WildcardParseNode.java
new file mode 100644
index 0000000..1ae27fc
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/WildcardParseNode.java
@@ -0,0 +1,58 @@
+/*
+ * 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 (*) in the SELECT clause of SQL
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public class WildcardParseNode extends TerminalParseNode {
+    public static final String NAME = "*";
+    public static final WildcardParseNode INSTANCE = new WildcardParseNode(false);
+    public static final WildcardParseNode REWRITE_INSTANCE = new WildcardParseNode(true);
+
+    private final boolean isRewrite;
+
+    private WildcardParseNode(boolean isRewrite) {
+        this.isRewrite = isRewrite;
+    }
+
+    @Override
+    public <T> T accept(ParseNodeVisitor<T> visitor) throws SQLException {
+        return visitor.visit(this);
+    }
+
+    @Override
+    public String toString() {
+        return NAME;
+    }
+
+    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/query/BaseQueryServicesImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/BaseQueryServicesImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/query/BaseQueryServicesImpl.java
new file mode 100644
index 0000000..27fa10e
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/BaseQueryServicesImpl.java
@@ -0,0 +1,80 @@
+/*
+ * 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.query;
+
+import java.util.concurrent.ExecutorService;
+
+import org.apache.phoenix.job.JobManager;
+import org.apache.phoenix.memory.GlobalMemoryManager;
+import org.apache.phoenix.memory.MemoryManager;
+import org.apache.phoenix.optimize.QueryOptimizer;
+import org.apache.phoenix.util.ReadOnlyProps;
+
+
+
+/**
+ * 
+ * Base class for QueryService implementors.
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public abstract class BaseQueryServicesImpl implements QueryServices {
+    private final ExecutorService executor;
+    private final MemoryManager memoryManager;
+    private final ReadOnlyProps props;
+    private final QueryOptimizer queryOptimizer;
+    
+    public BaseQueryServicesImpl(QueryServicesOptions options) {
+        this.executor =  JobManager.createThreadPoolExec(
+                options.getKeepAliveMs(), 
+                options.getThreadPoolSize(), 
+                options.getQueueSize());
+        this.memoryManager = new GlobalMemoryManager(
+                Runtime.getRuntime().totalMemory() * options.getMaxMemoryPerc() / 100,
+                options.getMaxMemoryWaitMs());
+        this.props = options.getProps();
+        this.queryOptimizer = new QueryOptimizer(this);
+    }
+    
+    @Override
+    public ExecutorService getExecutor() {
+        return executor;
+    }
+
+    @Override
+    public MemoryManager getMemoryManager() {
+        return memoryManager;
+    }
+
+    @Override
+    public final ReadOnlyProps getProps() {
+        return props;
+    }
+
+    @Override
+    public void close() {
+    }
+
+    @Override
+    public QueryOptimizer getOptimizer() {
+        return queryOptimizer;
+    }   
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/query/ChildQueryServices.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ChildQueryServices.java b/phoenix-core/src/main/java/org/apache/phoenix/query/ChildQueryServices.java
new file mode 100644
index 0000000..93613d6
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ChildQueryServices.java
@@ -0,0 +1,47 @@
+/*
+ * 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.query;
+
+import org.apache.phoenix.memory.ChildMemoryManager;
+import org.apache.phoenix.memory.MemoryManager;
+
+/**
+ * 
+ * Child QueryServices that delegates through to global QueryService.
+ * Used to track memory used by each org to allow a max percentage threshold.
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public class ChildQueryServices extends DelegateConnectionQueryServices {
+    private final MemoryManager memoryManager;
+    private static final int DEFAULT_MAX_ORG_MEMORY_PERC = 30;
+    
+    public ChildQueryServices(ConnectionQueryServices services) {
+        super(services);
+        int maxOrgMemPerc = getProps().getInt(MAX_TENANT_MEMORY_PERC_ATTRIB, DEFAULT_MAX_ORG_MEMORY_PERC);
+        this.memoryManager = new ChildMemoryManager(services.getMemoryManager(), maxOrgMemPerc);
+    }
+
+    @Override
+    public MemoryManager getMemoryManager() {
+        return memoryManager;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/query/ConfigurationFactory.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ConfigurationFactory.java b/phoenix-core/src/main/java/org/apache/phoenix/query/ConfigurationFactory.java
new file mode 100644
index 0000000..77d737e
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ConfigurationFactory.java
@@ -0,0 +1,46 @@
+/*
+ * 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.query;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HBaseConfiguration;
+
+/**
+ * Creates {@link Configuration} instances that contain HBase/Hadoop settings.
+ *
+ * @author aaraujo
+ * @since 2.0
+ */
+public interface ConfigurationFactory {
+    /**
+     * @return Configuration containing HBase/Hadoop settings
+     */
+    Configuration getConfiguration();
+
+    /**
+     * Default implementation uses {@link org.apache.hadoop.hbase.HBaseConfiguration#create()}.
+     */
+    static class ConfigurationFactoryImpl implements ConfigurationFactory {
+        @Override
+        public Configuration getConfiguration() {
+            return HBaseConfiguration.create();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/50d523f6/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java
new file mode 100644
index 0000000..47eae18
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java
@@ -0,0 +1,102 @@
+/*
+ * 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.query;
+
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.hadoop.hbase.HRegionLocation;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.hadoop.hbase.client.HTableInterface;
+import org.apache.hadoop.hbase.client.Mutation;
+import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
+import org.apache.hadoop.hbase.util.Pair;
+import org.apache.phoenix.client.KeyValueBuilder;
+import org.apache.phoenix.compile.MutationPlan;
+import org.apache.phoenix.coprocessor.MetaDataProtocol.MetaDataMutationResult;
+import org.apache.phoenix.execute.MutationState;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.schema.PTableType;
+import org.apache.phoenix.schema.SequenceKey;
+
+
+public interface ConnectionQueryServices extends QueryServices, MetaDataMutated {
+    /**
+     * Get (and create if necessary) a child QueryService for a given tenantId.
+     * The QueryService will be cached for the lifetime of the parent QueryService
+     * @param tenantId the organization ID
+     * @return the child QueryService
+     */
+    public ConnectionQueryServices getChildQueryServices(ImmutableBytesWritable tenantId);
+
+    /**
+     * Get an HTableInterface by the given name. It is the callers
+     * responsibility to close the returned HTableInterface.
+     * @param tableName the name of the HTable
+     * @return the HTableInterface
+     * @throws SQLException 
+     */
+    public HTableInterface getTable(byte[] tableName) throws SQLException;
+
+    public HTableDescriptor getTableDescriptor(byte[] tableName) throws SQLException;
+
+    public StatsManager getStatsManager();
+
+    public List<HRegionLocation> getAllTableRegions(byte[] tableName) throws SQLException;
+
+    public PhoenixConnection connect(String url, Properties info) throws SQLException;
+
+    public MetaDataMutationResult getTable(byte[] tenantId, byte[] schemaName, byte[] tableName, long tableTimestamp, long clientTimetamp) throws SQLException;
+    public MetaDataMutationResult createTable(List<Mutation> tableMetaData, byte[] tableName, PTableType tableType, Map<String,Object> tableProps, List<Pair<byte[],Map<String,Object>>> families, byte[][] splits) throws SQLException;
+    public MetaDataMutationResult dropTable(List<Mutation> tableMetadata, PTableType tableType) throws SQLException;
+    public MetaDataMutationResult addColumn(List<Mutation> tableMetaData, PTableType tableType, List<Pair<byte[],Map<String,Object>>> families) throws SQLException;
+    public MetaDataMutationResult dropColumn(List<Mutation> tableMetadata, PTableType tableType) throws SQLException;
+    public MetaDataMutationResult updateIndexState(List<Mutation> tableMetadata, String parentTableName) throws SQLException;
+    public MutationState updateData(MutationPlan plan) throws SQLException;
+
+    public void init(String url, Properties props) throws SQLException;
+
+    public int getLowestClusterHBaseVersion();
+    public HBaseAdmin getAdmin() throws SQLException;
+
+    void clearTableRegionCache(byte[] tableName) throws SQLException;
+
+    boolean hasInvalidIndexConfiguration();
+    
+    long createSequence(String tenantId, String schemaName, String sequenceName, long startWith, long incrementBy, int batchSize, long timestamp) throws SQLException;
+    long dropSequence(String tenantId, String schemaName, String sequenceName, long timestamp) throws SQLException;
+    void reserveSequenceValues(List<SequenceKey> sequenceKeys, long timestamp, long[] values, SQLException[] exceptions) throws SQLException;
+    void incrementSequenceValues(List<SequenceKey> sequenceKeys, long timestamp, long[] values, SQLException[] exceptions) throws SQLException;
+    long getSequenceValue(SequenceKey sequenceKey, long timestamp) throws SQLException;
+    void returnSequenceValues(List<SequenceKey> sequenceKeys, long timestamp, SQLException[] exceptions) throws SQLException;
+    void addConnection(PhoenixConnection connection) throws SQLException;
+    void removeConnection(PhoenixConnection connection) throws SQLException;
+
+    /**
+     * @return the {@link KeyValueBuilder} that is valid for the locally installed version of HBase.
+     */
+    public KeyValueBuilder getKeyValueBuilder();
+    
+    public enum Feature {REVERSE_SCAN};
+    public boolean supportsFeature(Feature feature);
+}
\ No newline at end of file