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 20:23:15 UTC

[14/51] [partial] Initial commit

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/c5b80246/src/main/java/org/apache/phoenix/schema/ArgumentTypeMismatchException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/phoenix/schema/ArgumentTypeMismatchException.java b/src/main/java/org/apache/phoenix/schema/ArgumentTypeMismatchException.java
new file mode 100644
index 0000000..95ee870
--- /dev/null
+++ b/src/main/java/org/apache/phoenix/schema/ArgumentTypeMismatchException.java
@@ -0,0 +1,44 @@
+/*
+ * 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.schema;
+
+import java.sql.SQLException;
+
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.exception.SQLExceptionInfo;
+
+/**
+ * Exception thrown when we try to use use an argument that has the wrong type. 
+ * 
+ * @author zhuang
+ * @since 1.0
+ */
+public class ArgumentTypeMismatchException extends SQLException {
+    private static final long serialVersionUID = 1L;
+    private static SQLExceptionCode code = SQLExceptionCode.TYPE_MISMATCH;
+
+    public ArgumentTypeMismatchException(PDataType expected, PDataType actual, String location) {
+        super(new SQLExceptionInfo.Builder(code).setMessage("expected: " + expected + " but was: " + actual + " at " + location).build().toString(), code.getSQLState());
+    }
+
+    public ArgumentTypeMismatchException(String expected, String actual, String location) {
+        super(new SQLExceptionInfo.Builder(code).setMessage("expected: " + expected + " but was: " + actual + " at " + location).build().toString(), code.getSQLState());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/c5b80246/src/main/java/org/apache/phoenix/schema/ColumnAlreadyExistsException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/phoenix/schema/ColumnAlreadyExistsException.java b/src/main/java/org/apache/phoenix/schema/ColumnAlreadyExistsException.java
new file mode 100644
index 0000000..7bb9a03
--- /dev/null
+++ b/src/main/java/org/apache/phoenix/schema/ColumnAlreadyExistsException.java
@@ -0,0 +1,62 @@
+/*
+ * 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.schema;
+
+import java.sql.SQLException;
+
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.exception.SQLExceptionInfo;
+
+
+/**
+ * 
+ * Exception thrown when a column already exists.
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public class ColumnAlreadyExistsException extends SQLException {
+    private static final long serialVersionUID = 1L;
+    private static SQLExceptionCode code = SQLExceptionCode.COLUMN_EXIST_IN_DEF;
+    private final String schemaName;
+    private final String tableName;
+    private final String columnName;
+
+    public ColumnAlreadyExistsException(String schemaName, String tableName, String columnName) {
+        super(new SQLExceptionInfo.Builder(code).setColumnName(columnName)
+                .setSchemaName(schemaName).setTableName(tableName).build().toString(),
+                code.getSQLState());
+        this.schemaName = schemaName;
+        this.tableName = tableName;
+        this.columnName = columnName;
+    }
+
+    public String getTableName() {
+        return tableName;
+    }
+
+    public String getSchemaName() {
+        return schemaName;
+    }
+
+    public String getColumnName() {
+        return columnName;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/c5b80246/src/main/java/org/apache/phoenix/schema/ColumnFamilyNotFoundException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/phoenix/schema/ColumnFamilyNotFoundException.java b/src/main/java/org/apache/phoenix/schema/ColumnFamilyNotFoundException.java
new file mode 100644
index 0000000..d447f39
--- /dev/null
+++ b/src/main/java/org/apache/phoenix/schema/ColumnFamilyNotFoundException.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.schema;
+
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.exception.SQLExceptionInfo;
+
+/**
+ * 
+ * Exception thrown when a family name could not be found in the schema
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public class ColumnFamilyNotFoundException extends MetaDataEntityNotFoundException {
+    private static final long serialVersionUID = 1L;
+    private static SQLExceptionCode code = SQLExceptionCode.COLUMN_FAMILY_NOT_FOUND;
+    private final String familyName;
+
+    public ColumnFamilyNotFoundException(String familyName) {
+        super(new SQLExceptionInfo.Builder(code).setFamilyName(familyName).build().toString(),
+                code.getSQLState(), code.getErrorCode());
+        this.familyName = familyName;
+    }
+
+    public String getFamilyName() {
+        return familyName;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/c5b80246/src/main/java/org/apache/phoenix/schema/ColumnModifier.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/phoenix/schema/ColumnModifier.java b/src/main/java/org/apache/phoenix/schema/ColumnModifier.java
new file mode 100644
index 0000000..7b4bc3d
--- /dev/null
+++ b/src/main/java/org/apache/phoenix/schema/ColumnModifier.java
@@ -0,0 +1,149 @@
+/*
+ * 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.schema;
+
+import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * A ColumnModifier implementation modifies how bytes are stored in a primary key column.</p>  
+ * The {@link ColumnModifier#apply apply} method is called when the bytes for a specific column are first written to HBase and again
+ * when they are read back.  Phoenix attemps to minimize calls to apply when bytes are read out of HBase.   
+ * 
+ * @author simontoens
+ * @since 1.2
+ */
+public enum ColumnModifier {
+    /**
+     * Invert the bytes in the src byte array to support descending ordering of row keys.
+     */
+    SORT_DESC(1) {
+        @Override
+        public byte[] apply(byte[] src, int srcOffset, byte[] dest, int dstOffset, int length) {
+            Preconditions.checkNotNull(src);            
+            Preconditions.checkNotNull(dest);            
+            for (int i = 0; i < length; i++) {
+                dest[dstOffset+i] = (byte)(src[srcOffset+i] ^ 0xFF);
+            }                       
+            return dest;
+        }
+
+        @Override
+        public byte apply(byte b) {
+            return (byte)(b ^ 0xFF);
+        }
+
+        @Override
+        public CompareOp transform(CompareOp op) {
+            switch (op) {
+                case EQUAL:
+                    return op;
+                case GREATER:
+                    return CompareOp.LESS;
+                case GREATER_OR_EQUAL:
+                    return CompareOp.LESS_OR_EQUAL;
+                case LESS:
+                    return CompareOp.GREATER;
+                case LESS_OR_EQUAL:
+                    return CompareOp.GREATER_OR_EQUAL;
+                default:
+                    throw new IllegalArgumentException("Unknown operator " + op);
+            }
+        }
+
+        @Override
+        public byte[] apply(byte[] src, int srcOffset, int length) {
+            return apply(src, srcOffset, new byte[length], 0, length);
+        }
+    };
+        
+    private final int serializationId;
+    
+    ColumnModifier(int serializationId) {
+        this.serializationId = serializationId;
+    }
+    
+    public int getSerializationId() {
+        return serializationId;
+    }
+    /**
+     * Returns the ColumnModifier for the specified DDL stmt keyword.
+     */
+    public static ColumnModifier fromDDLValue(String modifier) {
+        if (modifier == null) {
+            return null;
+        } else if (modifier.equalsIgnoreCase("ASC")) {
+            return null;
+        } else if (modifier.equalsIgnoreCase("DESC")) {
+            return SORT_DESC;
+        } else {
+            return null;
+        }                       
+    }
+
+   /**
+    * Returns the ColumnModifier for the specified internal value.
+    */
+    public static ColumnModifier fromSystemValue(int value) {
+        for (ColumnModifier mod : ColumnModifier.values()) {
+            if (mod.getSerializationId() == value) {
+                return mod;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns an internal value representing the specified ColumnModifier.
+     */
+    public static int toSystemValue(ColumnModifier columnModifier) {
+        if (columnModifier == null) {
+            return 0;
+        }
+        return columnModifier.getSerializationId();
+    }
+
+    /**
+     * Copies the bytes from source array to destination array and applies the column modifier operation on the bytes
+     * starting at the specified offsets.  The column modifier is applied to the number of bytes matching the 
+     * specified length.
+     * @param src  the source byte array to copy from, cannot be null
+     * @param srcOffset the offset into the source byte array at which to begin.
+     * @param dest the destination byte array into which to transfer the modified bytes.
+     * @param dstOffset the offset into the destination byte array at which to begin
+     * @param length the number of bytes for which to apply the modification
+     * @return the destination byte array
+     */
+    public abstract byte[] apply(byte[] src, int srcOffset, byte[] dest, int dstOffset, int length);
+    /**
+     * Copies the bytes from source array to a newly allocated destination array and applies the column
+     * modifier operation on the bytes starting at the specified offsets.  The column modifier is applied
+     * to the number of bytes matching the specified length.
+     * @param src  the source byte array to copy from, cannot be null
+     * @param srcOffset the offset into the source byte array at which to begin.
+     * @param length the number of bytes for which to apply the modification
+     * @return the newly allocated destination byte array
+     */
+    public abstract byte[] apply(byte[] src, int srcOffset, int length);
+    public abstract byte apply(byte b);
+    
+    public abstract CompareOp transform(CompareOp op);
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/c5b80246/src/main/java/org/apache/phoenix/schema/ColumnNotFoundException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/phoenix/schema/ColumnNotFoundException.java b/src/main/java/org/apache/phoenix/schema/ColumnNotFoundException.java
new file mode 100644
index 0000000..6441e09
--- /dev/null
+++ b/src/main/java/org/apache/phoenix/schema/ColumnNotFoundException.java
@@ -0,0 +1,65 @@
+/*
+ * 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.schema;
+
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.exception.SQLExceptionInfo;
+
+
+/**
+ * 
+ * Exception thrown when a column name referenced in a select
+ * statement cannot be found in any table.
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public class ColumnNotFoundException extends MetaDataEntityNotFoundException {
+    private static final long serialVersionUID = 1L;
+    private static SQLExceptionCode code = SQLExceptionCode.COLUMN_NOT_FOUND;
+    private final String schemaName;
+    private final String tableName;
+    private final String columnName;
+
+    public ColumnNotFoundException(String columnName) {
+        this(null, null, null, columnName);
+    }
+
+    public ColumnNotFoundException(String schemaName, String tableName, String familyName, String columnName) {
+        super(new SQLExceptionInfo.Builder(code).setSchemaName(schemaName).setTableName(tableName)
+                .setFamilyName(familyName).setColumnName(columnName).build().toString(),
+                code.getSQLState(), code.getErrorCode());
+        this.schemaName = schemaName;
+        this.tableName = tableName;
+        this.columnName = columnName;
+    }
+
+    public String getTableName() {
+        return tableName;
+    }
+
+    public String getSchemaName() {
+        return schemaName;
+    }
+
+    public String getColumnName() {
+        return columnName;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/c5b80246/src/main/java/org/apache/phoenix/schema/ColumnRef.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/phoenix/schema/ColumnRef.java b/src/main/java/org/apache/phoenix/schema/ColumnRef.java
new file mode 100644
index 0000000..0e65974
--- /dev/null
+++ b/src/main/java/org/apache/phoenix/schema/ColumnRef.java
@@ -0,0 +1,132 @@
+/*
+ * 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.schema;
+
+import java.sql.SQLException;
+
+import org.apache.http.annotation.Immutable;
+
+import org.apache.phoenix.expression.ColumnExpression;
+import org.apache.phoenix.expression.IndexKeyValueColumnExpression;
+import org.apache.phoenix.expression.KeyValueColumnExpression;
+import org.apache.phoenix.expression.RowKeyColumnExpression;
+import org.apache.phoenix.util.IndexUtil;
+import org.apache.phoenix.util.SchemaUtil;
+
+
+/**
+ * 
+ * Class that represents a reference to a PColumn in a PTable
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+@Immutable
+public final class ColumnRef {
+    private final TableRef tableRef;
+    private final int columnPosition;
+    private final int pkSlotPosition;
+    
+    public ColumnRef(ColumnRef columnRef, long timeStamp) {
+        this.tableRef = new TableRef(columnRef.tableRef, timeStamp);
+        this.columnPosition = columnRef.columnPosition;
+        this.pkSlotPosition = columnRef.pkSlotPosition;
+    }
+
+    public ColumnRef(TableRef tableRef, int columnPosition) {
+        if (tableRef == null) {
+            throw new NullPointerException();
+        }
+        if (columnPosition < 0 || columnPosition >= tableRef.getTable().getColumns().size()) {
+            throw new IllegalArgumentException("Column position of " + columnPosition + " must be between 0 and " + tableRef.getTable().getColumns().size() + " for table " + tableRef.getTable().getName().getString());
+        }
+        this.tableRef = tableRef;
+        this.columnPosition = columnPosition;
+        PColumn column = getColumn();
+        int i = -1;
+        if (SchemaUtil.isPKColumn(column)) {
+            for (PColumn pkColumn : tableRef.getTable().getPKColumns()) {
+                i++;
+                if (pkColumn == column) {
+                    break;
+                }
+            }
+        }
+        pkSlotPosition = i;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + columnPosition;
+        result = prime * result + tableRef.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;
+        ColumnRef other = (ColumnRef)obj;
+        if (columnPosition != other.columnPosition) return false;
+        if (!tableRef.equals(other.tableRef)) return false;
+        return true;
+    }
+
+    public ColumnExpression newColumnExpression() throws SQLException {
+        boolean isIndex = tableRef.getTable().getType() == PTableType.INDEX;
+        if (SchemaUtil.isPKColumn(this.getColumn())) {
+            String name = this.getColumn().getName().getString();
+            if (isIndex) {
+                name = IndexUtil.getDataColumnName(name);
+            }
+            return new RowKeyColumnExpression(
+                    getColumn(), 
+                    new RowKeyValueAccessor(this.getTable().getPKColumns(), pkSlotPosition),
+                    name);
+        } else {
+            return isIndex 
+                    ? new IndexKeyValueColumnExpression(getColumn()) 
+                    :  new KeyValueColumnExpression(getColumn());
+        }
+    }
+
+    public int getColumnPosition() {
+        return columnPosition;
+    }
+    
+    public int getPKSlotPosition() {
+        return pkSlotPosition;
+    }
+    
+    public PColumn getColumn() {
+        return tableRef.getTable().getColumns().get(columnPosition);
+    }
+
+    public PTable getTable() {
+        return tableRef.getTable();
+    }
+    
+    public TableRef getTableRef() {
+        return tableRef;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/c5b80246/src/main/java/org/apache/phoenix/schema/ConcurrentTableMutationException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/phoenix/schema/ConcurrentTableMutationException.java b/src/main/java/org/apache/phoenix/schema/ConcurrentTableMutationException.java
new file mode 100644
index 0000000..151d637
--- /dev/null
+++ b/src/main/java/org/apache/phoenix/schema/ConcurrentTableMutationException.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.schema;
+
+import java.sql.SQLException;
+
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.exception.SQLExceptionInfo;
+
+
+public class ConcurrentTableMutationException extends SQLException {
+    private static final long serialVersionUID = 1L;
+    private static SQLExceptionCode code = SQLExceptionCode.CONCURRENT_TABLE_MUTATION;
+    private final String schemaName;
+    private final String tableName;
+
+    public ConcurrentTableMutationException(String schemaName, String tableName) {
+        super(new SQLExceptionInfo.Builder(code).setSchemaName(schemaName).setTableName(tableName).build().toString(), 
+                code.getSQLState());
+        this.schemaName = schemaName;
+        this.tableName = tableName;
+    }
+
+    public String getTableName() {
+        return tableName;
+    }
+
+    public String getSchemaName() {
+        return schemaName;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/c5b80246/src/main/java/org/apache/phoenix/schema/ConstraintViolationException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/phoenix/schema/ConstraintViolationException.java b/src/main/java/org/apache/phoenix/schema/ConstraintViolationException.java
new file mode 100644
index 0000000..5a8b260
--- /dev/null
+++ b/src/main/java/org/apache/phoenix/schema/ConstraintViolationException.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.schema;
+
+/**
+ * 
+ * Exception thrown when a schema constraint is violated at the
+ * time of data insertion.
+ *
+ * @author jtaylor
+ * @since 180
+ */
+public class ConstraintViolationException extends RuntimeException {
+	private static final long serialVersionUID = 1L;
+
+    public ConstraintViolationException() {
+    }
+
+    public ConstraintViolationException(String message) {
+        super(message);
+    }
+
+    public ConstraintViolationException(Throwable cause) {
+        super(cause);
+    }
+
+    public ConstraintViolationException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/c5b80246/src/main/java/org/apache/phoenix/schema/DelegateColumn.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/phoenix/schema/DelegateColumn.java b/src/main/java/org/apache/phoenix/schema/DelegateColumn.java
new file mode 100644
index 0000000..6290b16
--- /dev/null
+++ b/src/main/java/org/apache/phoenix/schema/DelegateColumn.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.schema;
+
+import java.io.*;
+
+public class DelegateColumn extends DelegateDatum implements PColumn {
+    
+    public DelegateColumn(PColumn delegate) {
+        super(delegate);
+    }
+    
+    @Override
+    protected PColumn getDelegate() {
+        return (PColumn)super.getDelegate();
+    }
+    
+    @Override
+    public PName getName() {
+        return getDelegate().getName();
+    }
+    
+    @Override
+    public ColumnModifier getColumnModifier() {
+    	return getDelegate().getColumnModifier();
+    }
+
+    @Override
+    public PName getFamilyName() {
+        return getDelegate().getFamilyName();
+    }
+
+    @Override
+    public void readFields(DataInput input) throws IOException {
+        getDelegate().readFields(input);
+    }
+
+    @Override
+    public void write(DataOutput output) throws IOException {
+        getDelegate().write(output);
+    }
+
+    @Override
+    public int getPosition() {
+        return getDelegate().getPosition();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/c5b80246/src/main/java/org/apache/phoenix/schema/DelegateDatum.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/phoenix/schema/DelegateDatum.java b/src/main/java/org/apache/phoenix/schema/DelegateDatum.java
new file mode 100644
index 0000000..86e4cc9
--- /dev/null
+++ b/src/main/java/org/apache/phoenix/schema/DelegateDatum.java
@@ -0,0 +1,62 @@
+/*
+ * 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.schema;
+
+public class DelegateDatum implements PDatum {
+    private final PDatum delegate;
+    
+    public DelegateDatum(PDatum delegate) {
+        this.delegate = delegate;
+    }
+    
+    @Override
+    public boolean isNullable() {
+        return delegate.isNullable();
+    }
+
+    @Override
+    public PDataType getDataType() {
+        return delegate.getDataType();
+    }
+
+    @Override
+    public Integer getByteSize() {
+        return delegate.getByteSize();
+    }
+
+    @Override
+    public Integer getMaxLength() {
+        return delegate.getByteSize();
+    }
+
+    @Override
+    public Integer getScale() {
+        return delegate.getScale();
+    }
+    
+	@Override
+	public ColumnModifier getColumnModifier() {
+		return delegate.getColumnModifier();
+	}
+
+    protected PDatum getDelegate() {
+        return delegate;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/c5b80246/src/main/java/org/apache/phoenix/schema/ExecuteQueryNotApplicableException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/phoenix/schema/ExecuteQueryNotApplicableException.java b/src/main/java/org/apache/phoenix/schema/ExecuteQueryNotApplicableException.java
new file mode 100644
index 0000000..36e2441
--- /dev/null
+++ b/src/main/java/org/apache/phoenix/schema/ExecuteQueryNotApplicableException.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.schema;
+
+import java.sql.SQLException;
+
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.exception.SQLExceptionInfo;
+
+public class ExecuteQueryNotApplicableException extends SQLException {
+    private static final long serialVersionUID = 1L;
+    private static SQLExceptionCode code = SQLExceptionCode.EXECUTE_QUERY_NOT_APPLICABLE;
+
+    public ExecuteQueryNotApplicableException(String query) {
+        super(new SQLExceptionInfo.Builder(code).setMessage("Query: " + query).build().toString(), code.getSQLState());
+    }
+
+    public ExecuteQueryNotApplicableException(String command, String statement) {
+        super(new SQLExceptionInfo.Builder(code).setMessage("Command: " + command + ". Statement: " + statement).build().toString(), code.getSQLState());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/c5b80246/src/main/java/org/apache/phoenix/schema/ExecuteUpdateNotApplicableException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/phoenix/schema/ExecuteUpdateNotApplicableException.java b/src/main/java/org/apache/phoenix/schema/ExecuteUpdateNotApplicableException.java
new file mode 100644
index 0000000..5693a01
--- /dev/null
+++ b/src/main/java/org/apache/phoenix/schema/ExecuteUpdateNotApplicableException.java
@@ -0,0 +1,38 @@
+/*
+ * 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.schema;
+
+import java.sql.SQLException;
+
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.exception.SQLExceptionInfo;
+
+public class ExecuteUpdateNotApplicableException extends SQLException {
+    private static final long serialVersionUID = 1L;
+    private static SQLExceptionCode code = SQLExceptionCode.EXECUTE_QUERY_NOT_APPLICABLE;
+
+    public ExecuteUpdateNotApplicableException(String query) {
+        super(new SQLExceptionInfo.Builder(code).setMessage("Query: " + query).build().toString(), code.getSQLState());
+    }
+
+    public ExecuteUpdateNotApplicableException(String command, String statement) {
+        super(new SQLExceptionInfo.Builder(code).setMessage("Command: " + command + ". Statement: " + statement).build().toString(), code.getSQLState());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/c5b80246/src/main/java/org/apache/phoenix/schema/IllegalDataException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/phoenix/schema/IllegalDataException.java b/src/main/java/org/apache/phoenix/schema/IllegalDataException.java
new file mode 100644
index 0000000..83ae565
--- /dev/null
+++ b/src/main/java/org/apache/phoenix/schema/IllegalDataException.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.schema;
+
+/**
+ * 
+ * Exception thrown when an invalid or illegal data value is found
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+public class IllegalDataException extends ConstraintViolationException {
+	private static final long serialVersionUID = 1L;
+
+    public IllegalDataException() {
+    }
+
+    public IllegalDataException(String message) {
+        super(message);
+    }
+
+    public IllegalDataException(Throwable cause) {
+        super(cause);
+    }
+
+    public IllegalDataException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/c5b80246/src/main/java/org/apache/phoenix/schema/KeyValueSchema.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/phoenix/schema/KeyValueSchema.java b/src/main/java/org/apache/phoenix/schema/KeyValueSchema.java
new file mode 100644
index 0000000..8537199
--- /dev/null
+++ b/src/main/java/org/apache/phoenix/schema/KeyValueSchema.java
@@ -0,0 +1,207 @@
+/*
+ * 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.schema;
+
+import java.util.List;
+
+import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
+import org.apache.hadoop.io.WritableUtils;
+import org.apache.http.annotation.Immutable;
+
+import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.util.ByteUtil;
+
+
+/**
+ * 
+ * Simple flat schema over a byte array where fields may be any of {@link PDataType}.
+ * Optimized for positional access by index.
+ *
+ * @author jtaylor
+ * @since 0.1
+ */
+@Immutable
+public class KeyValueSchema extends ValueSchema {
+    
+    protected KeyValueSchema(int minNullable, List<Field> fields) {
+        super(minNullable, fields);
+    }
+
+    public static class KeyValueSchemaBuilder extends ValueSchemaBuilder {
+
+        public KeyValueSchemaBuilder(int minNullable) {
+            super(minNullable);
+        }
+        
+        @Override
+        public KeyValueSchema build() {
+            List<Field> condensedFields = buildFields();
+            return new KeyValueSchema(this.minNullable, condensedFields);
+        }
+
+        @Override
+        public KeyValueSchemaBuilder setMaxFields(int nFields) {
+            super.setMaxFields(nFields);
+            return this;
+        }
+        
+        public KeyValueSchemaBuilder addField(PDatum datum) {
+            super.addField(datum, fields.size() <  this.minNullable, null);
+            return this;
+        }
+    }
+    
+    public boolean isNull(int position, ValueBitSet bitSet) {
+        int nBit = position - getMinNullable();
+        return (nBit >= 0 && !bitSet.get(nBit));
+    }
+    
+    private static byte[] ensureSize(byte[] b, int offset, int size) {
+        if (size > b.length) {
+            byte[] bBigger = new byte[Math.max(b.length * 2, size)];
+            System.arraycopy(b, 0, bBigger, 0, b.length);
+            return bBigger;
+        }
+        return b;
+    }
+
+    /**
+     * @return byte representation of the KeyValueSchema
+     */
+    public byte[] toBytes(Expression[] expressions, ValueBitSet valueSet, ImmutableBytesWritable ptr) {
+        int offset = 0;
+        int index = 0;
+        valueSet.clear();
+        int minNullableIndex = getMinNullable();
+        byte[] b = new byte[getEstimatedValueLength() + valueSet.getEstimatedLength()];
+        List<Field> fields = getFields();
+        // We can get away with checking if only nulls are left in the outer loop,
+        // since repeating fields will not span the non-null/null boundary.
+        for (int i = 0; i < fields.size(); i++) {
+            Field field = fields.get(i);
+            PDataType type = field.getDataType();
+            for (int j = 0; j < field.getCount(); j++) {
+                if (expressions[index].evaluate(null, ptr)) { // Skip null values
+                    if (index >= minNullableIndex) {
+                        valueSet.set(index - minNullableIndex);
+                    }
+                    if (!type.isFixedWidth()) {
+                        b = ensureSize(b, offset, offset + getVarLengthBytes(ptr.getLength()));
+                        offset = writeVarLengthField(ptr, b, offset);
+                    } else {
+                        int nBytes = ptr.getLength();
+                        b = ensureSize(b, offset, offset + nBytes);
+                        System.arraycopy(ptr.get(), ptr.getOffset(), b, offset, nBytes);
+                        offset += nBytes;
+                    }
+                }
+                index++;
+            }
+        }
+        // Add information about which values were set at end of value,
+        // so that we can quickly access them without needing to walk
+        // through the values using the schema.
+        // TODO: if there aren't any non null values, don't serialize anything
+        b = ensureSize(b, offset, offset + valueSet.getEstimatedLength());
+        offset = valueSet.toBytes(b, offset);
+
+        if (offset == b.length) {
+            return b;
+        } else {
+            byte[] bExact = new byte[offset];
+            System.arraycopy(b, 0, bExact, 0, offset);
+            return bExact;
+        }
+    }
+
+    private int getVarLengthBytes(int length) {
+        return length + WritableUtils.getVIntSize(length);
+    }
+    
+    private int writeVarLengthField(ImmutableBytesWritable ptr, byte[] b, int offset) {
+        int length = ptr.getLength();
+        offset += ByteUtil.vintToBytes(b, offset, length);
+        System.arraycopy(ptr.get(), ptr.getOffset(), b, offset, length);                        
+        offset += length;
+        return offset;
+    }
+
+    @edu.umd.cs.findbugs.annotations.SuppressWarnings(
+            value="NP_BOOLEAN_RETURN_NULL", 
+            justification="Designed to return null.")
+    public Boolean iterator(byte[] src, int srcOffset, int srcLength, ImmutableBytesWritable ptr, int position, ValueBitSet valueBitSet) {
+        ptr.set(src, srcOffset, 0);
+        int maxOffset = srcOffset + srcLength;
+        Boolean hasValue = null;
+        for (int i = 0; i < position; i++) {
+            hasValue = next(ptr, i, maxOffset, valueBitSet);
+        }
+        return hasValue;
+    }
+    
+    public Boolean iterator(ImmutableBytesWritable srcPtr, ImmutableBytesWritable ptr, int position, ValueBitSet valueSet) {
+        return iterator(srcPtr.get(),srcPtr.getOffset(),srcPtr.getLength(), ptr, position, valueSet);
+    }
+    
+    public Boolean iterator(ImmutableBytesWritable ptr, int position, ValueBitSet valueSet) {
+        return iterator(ptr, ptr, position, valueSet);
+    }
+    
+    public Boolean iterator(ImmutableBytesWritable ptr) {
+        return iterator(ptr, ptr, 0, ValueBitSet.EMPTY_VALUE_BITSET);
+    }
+    
+    /**
+     * Move the bytes ptr to the next position relative to the current ptr
+     * @param ptr bytes pointer pointing to the value at the positional index
+     * provided.
+     * @param position zero-based index of the next field in the value schema
+     * @param maxOffset max possible offset value when iterating
+     * @return true if a value was found and ptr was set, false if the value is null and ptr was not
+     * set, and null if the value is null and there are no more values
+      */
+    @edu.umd.cs.findbugs.annotations.SuppressWarnings(
+            value="NP_BOOLEAN_RETURN_NULL", 
+            justification="Designed to return null.")
+    public Boolean next(ImmutableBytesWritable ptr, int position, int maxOffset, ValueBitSet valueSet) {
+        if (ptr.getOffset() + ptr.getLength() >= maxOffset) {
+            ptr.set(ptr.get(), maxOffset, 0);
+            return null;
+        }
+        if (position >= getFieldCount()) {
+            return null;
+        }
+        // Move the pointer past the current value and set length
+        // to 0 to ensure you never set the ptr past the end of the
+        // backing byte array.
+        ptr.set(ptr.get(), ptr.getOffset() + ptr.getLength(), 0);
+        if (!isNull(position, valueSet)) {
+            Field field = this.getField(position);
+            if (field.getDataType().isFixedWidth()) {
+                ptr.set(ptr.get(),ptr.getOffset(), field.getByteSize());
+            } else {
+                int length = ByteUtil.vintFromBytes(ptr);
+                ptr.set(ptr.get(),ptr.getOffset(),length);
+            }
+            return ptr.getLength() > 0;
+        }
+        return false;
+    }
+}