phoenix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jamestay...@apache.org
Subject [3/3] git commit: PHOENIX-118 Type mismatch error on upsert for unsigned_date and date
Date Sun, 09 Mar 2014 01:26:23 GMT
PHOENIX-118 Type mismatch error on upsert for unsigned_date and date


Project: http://git-wip-us.apache.org/repos/asf/incubator-phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-phoenix/commit/65ac0ca3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-phoenix/tree/65ac0ca3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-phoenix/diff/65ac0ca3

Branch: refs/heads/master
Commit: 65ac0ca34623c6ba69858a9c29dc78c11c46acfb
Parents: 1159b6e
Author: James Taylor <jamestaylor@apache.org>
Authored: Sat Mar 8 17:25:54 2014 -0800
Committer: James Taylor <jamestaylor@apache.org>
Committed: Sat Mar 8 17:25:54 2014 -0800

----------------------------------------------------------------------
 .../apache/phoenix/compile/UpsertCompiler.java  |   53 +-
 .../UngroupedAggregateRegionObserver.java       |   21 +-
 .../phoenix/exception/SQLExceptionCode.java     |    2 +-
 .../ValueTypeIncompatibleException.java         |    4 +-
 .../expression/ArithmeticExpression.java        |   31 +
 .../expression/BaseAddSubtractExpression.java   |   33 +-
 .../expression/DecimalAddExpression.java        |   11 +-
 .../expression/DecimalDivideExpression.java     |    5 +-
 .../expression/DecimalMultiplyExpression.java   |    5 +-
 .../expression/DecimalSubtractExpression.java   |   11 +-
 .../phoenix/expression/DivideExpression.java    |   46 +-
 .../phoenix/expression/LiteralExpression.java   |    7 +-
 .../phoenix/expression/MultiplyExpression.java  |   43 +-
 .../hbase/index/util/KeyValueBuilder.java       |    4 +-
 .../apache/phoenix/index/PhoenixIndexCodec.java |    7 +-
 .../query/ConnectionQueryServicesImpl.java      |    5 +-
 .../apache/phoenix/schema/PArrayDataType.java   |   39 +-
 .../org/apache/phoenix/schema/PDataType.java    | 1452 +++++++-----------
 .../java/org/apache/phoenix/util/IndexUtil.java |    7 +-
 .../org/apache/phoenix/util/NumberUtil.java     |    8 +-
 .../arithmetic/ArithmeticOperationTest.java     |   10 +-
 .../phoenix/client/TestClientKeyValue.java      |    8 +-
 .../phoenix/client/TestClientKeyValueLocal.java |    6 +
 .../phoenix/end2end/ArithmeticQueryTest.java    |   22 +-
 .../phoenix/end2end/ExecuteStatementsTest.java  |    8 +-
 .../end2end/UpsertSelectAutoCommitTest.java     |    2 +-
 .../phoenix/end2end/UpsertValuesTest.java       |   37 +-
 .../phoenix/end2end/VariableLengthPKTest.java   |   13 +-
 .../phoenix/end2end/index/MutableIndexTest.java |    1 -
 .../apache/phoenix/schema/PDataTypeTest.java    |   12 +-
 .../apache/phoenix/schema/SortOrderTest.java    |   13 +
 .../apache/phoenix/util/MetaDataUtilTest.java   |   34 +-
 .../phoenix/util/MinVersionTestRunner.java      |   64 +
 33 files changed, 863 insertions(+), 1161 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/65ac0ca3/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
index a45455e..8352f56 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
@@ -127,30 +127,30 @@ public class UpsertCompiler {
             Map<ImmutableBytesPtr,Map<PColumn,byte[]>> mutation = Maps.newHashMapWithExpectedSize(batchSize);
             PTable table = tableRef.getTable();
             ResultSet rs = new PhoenixResultSet(iterator, projector, statement);
+            ImmutableBytesWritable ptr = new ImmutableBytesWritable();
             while (rs.next()) {
                 for (int i = 0; i < values.length; i++) {
                     PColumn column = table.getColumns().get(columnIndexes[i]);
-                    byte[] byteValue = rs.getBytes(i+1);
+                    byte[] bytes = rs.getBytes(i+1);
+                    ptr.set(bytes == null ? ByteUtil.EMPTY_BYTE_ARRAY : bytes);
                     Object value = rs.getObject(i+1);
                     int rsPrecision = rs.getMetaData().getPrecision(i+1);
                     Integer precision = rsPrecision == 0 ? null : rsPrecision;
                     int rsScale = rs.getMetaData().getScale(i+1);
                     Integer scale = rsScale == 0 ? null : rsScale;
-                    if (column.getSortOrder() == SortOrder.DESC) {
-                        byte[] tempByteValue = Arrays.copyOf(byteValue, byteValue.length);
-                        byteValue = SortOrder.invert(byteValue, 0, tempByteValue, 0, byteValue.length);
-                    }
                     // We are guaranteed that the two column will have compatible types,
                     // as we checked that before.
-                    if (!column.getDataType().isSizeCompatible(column.getDataType(),
-                            value, byteValue,
-                            precision, column.getMaxLength(), 
-                            scale, column.getScale())) {
-                        throw new SQLExceptionInfo.Builder(SQLExceptionCode.DATA_INCOMPATIBLE_WITH_TYPE)
-                            .setColumnName(column.getName().getString()).build().buildException();
+                    if (!column.getDataType().isSizeCompatible(ptr, value, column.getDataType(),
+                            precision, scale,
+                            column.getMaxLength(),column.getScale())) {
+                        throw new SQLExceptionInfo.Builder(SQLExceptionCode.DATA_EXCEEDS_MAX_CAPACITY)
+                            .setColumnName(column.getName().getString())
+                            .setMessage("value=" + column.getDataType().toStringLiteral(ptr,
null)).build().buildException();
                     }
-                    values[i] = column.getDataType().coerceBytes(byteValue, value, column.getDataType(),
-                            precision, scale, column.getMaxLength(), column.getScale());
+                    column.getDataType().coerceBytes(ptr, value, column.getDataType(),
+                            precision, scale, SortOrder.getDefault(),
+                            column.getMaxLength(), column.getScale(), column.getSortOrder());
+                    values[i] = ByteUtil.copyKeyBytesIfNecessary(ptr);
                 }
                 setValues(values, pkSlotIndexes, columnIndexes, table, mutation);
                 rowCount++;
@@ -674,39 +674,32 @@ public class UpsertCompiler {
                     PColumn column = allColumns.get(columnIndexes[nodeIndex]);
                     constantExpression.evaluate(tuple, ptr);
                     Object value = null;
-                    byte[] byteValue = ByteUtil.copyKeyBytesIfNecessary(ptr);
                     if (constantExpression.getDataType() != null) {
-                        // If SortOrder from expression in SELECT doesn't match the
-                        // column being projected into then invert the bits.
-                        if (constantExpression.getSortOrder() != column.getSortOrder()) {
-                            byte[] tempByteValue = Arrays.copyOf(byteValue, byteValue.length);
-                            byteValue = SortOrder.invert(byteValue, 0, tempByteValue, 0,
byteValue.length);
-                        }
-                        value = constantExpression.getDataType().toObject(byteValue);
+                        value = constantExpression.getDataType().toObject(ptr, constantExpression.getSortOrder());
                         if (!constantExpression.getDataType().isCoercibleTo(column.getDataType(),
value)) { 
                             throw TypeMismatchException.newException(
                                 constantExpression.getDataType(), column.getDataType(), "expression:
"
                                         + constantExpression.toString() + " in column " +
column);
                         }
-                        if (!column.getDataType().isSizeCompatible(constantExpression.getDataType(),
-                                value, byteValue, constantExpression.getMaxLength(),
-                                column.getMaxLength(), constantExpression.getScale(), column.getScale()))
{ 
+                        if (!column.getDataType().isSizeCompatible(ptr, value, constantExpression.getDataType(),
+                                constantExpression.getMaxLength(), constantExpression.getScale(),

+                                column.getMaxLength(), column.getScale())) { 
                             throw new SQLExceptionInfo.Builder(
-                                SQLExceptionCode.DATA_INCOMPATIBLE_WITH_TYPE).setColumnName(column.getName().getString())
+                                SQLExceptionCode.DATA_EXCEEDS_MAX_CAPACITY).setColumnName(column.getName().getString())
                                 .setMessage("value=" + constantExpression.toString()).build().buildException();
                         }
                     }
-                    byteValue = column.getDataType().coerceBytes(byteValue, value,
-                            constantExpression.getDataType(), constantExpression.getMaxLength(),
constantExpression.getScale(),
-                            column.getMaxLength(), column.getScale());
+                    column.getDataType().coerceBytes(ptr, value,
+                            constantExpression.getDataType(), constantExpression.getMaxLength(),
constantExpression.getScale(), constantExpression.getSortOrder(),
+                            column.getMaxLength(), column.getScale(),column.getSortOrder());
                     byte[] viewValue = overlapViewColumns.get(column);
-                    if (viewValue != null && Bytes.compareTo(byteValue, viewValue)
!= 0) {
+                    if (viewValue != null && Bytes.compareTo(ptr.get(), ptr.getOffset(),
ptr.getLength(), viewValue, 0, viewValue.length) != 0) {
                         throw new SQLExceptionInfo.Builder(
                                 SQLExceptionCode.CANNOT_UPDATE_VIEW_COLUMN)
                                 .setColumnName(column.getName().getString())
                                 .setMessage("value=" + constantExpression.toString()).build().buildException();
                     }
-                    values[nodeIndex] = byteValue;
+                    values[nodeIndex] = ByteUtil.copyKeyBytesIfNecessary(ptr);
                     nodeIndex++;
                 }
                 // Add columns based on view

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/65ac0ca3/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java
b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java
index 96ffa11..e016305 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java
@@ -226,23 +226,18 @@ public class UngroupedAggregateRegionObserver extends BaseScannerRegionObserver
                                 Expression expression = selectExpressions.get(i);
                                 if (expression.evaluate(result, ptr)) {
                                     PColumn column = projectedColumns.get(i);
-                                    byte[] bytes = ptr.copyBytes();
-                                    Object value = expression.getDataType().toObject(bytes,
column.getSortOrder());
-                                    // If SortOrder from expression in SELECT doesn't match
the
-                                    // column being projected into then invert the bits.
-                                    if (expression.getSortOrder() != column.getSortOrder())
{
-                                        SortOrder.invert(bytes, 0, bytes, 0, bytes.length);
-                                    }
+                                    Object value = expression.getDataType().toObject(ptr,
column.getSortOrder());
                                     // We are guaranteed that the two column will have the
same type.
-                                    if (!column.getDataType().isSizeCompatible(column.getDataType(),
-                                            value, bytes,
-                                            expression.getMaxLength(), column.getMaxLength(),

-                                            expression.getScale(), column.getScale())) {
+                                    if (!column.getDataType().isSizeCompatible(ptr, value,
column.getDataType(),
+                                            expression.getMaxLength(),  expression.getScale(),

+                                            column.getMaxLength(), column.getScale())) {
                                         throw new ValueTypeIncompatibleException(column.getDataType(),
                                                 column.getMaxLength(), column.getScale());
                                     }
-                                    bytes = column.getDataType().coerceBytes(bytes, value,
expression.getDataType(),
-                                            expression.getMaxLength(), expression.getScale(),
column.getMaxLength(), column.getScale());
+                                    column.getDataType().coerceBytes(ptr, value, expression.getDataType(),
+                                            expression.getMaxLength(), expression.getScale(),
expression.getSortOrder(), 
+                                            column.getMaxLength(), column.getScale(), column.getSortOrder());
+                                    byte[] bytes = ByteUtil.copyKeyBytesIfNecessary(ptr);
                                     row.setValue(column, bytes);
                                 }
                             }

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/65ac0ca3/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
b/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
index 42a6c3e..885e3ae 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
@@ -68,7 +68,7 @@ public enum SQLExceptionCode {
     }),
     VALUE_IN_UPSERT_NOT_CONSTANT(204, "22008", "Values in UPSERT must evaluate to a constant."),
     MALFORMED_URL(205, "22009", "Malformed URL."),
-    DATA_INCOMPATIBLE_WITH_TYPE(206, "22003", "The value is outside the range for the data
type."),
+    DATA_EXCEEDS_MAX_CAPACITY(206, "22003", "The data exceeds the max capacity for the data
type."),
     MISSING_CHAR_LENGTH(207, "22003", "Missing length for CHAR."),
     NONPOSITIVE_CHAR_LENGTH(208, "22003", "CHAR or VARCHAR must have a positive length."),
     DECIMAL_PRECISION_OUT_OF_RANGE(209, "22003", "Decimal precision outside of range. Should
be within 1 and " + PDataType.MAX_PRECISION + "."),

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/65ac0ca3/phoenix-core/src/main/java/org/apache/phoenix/exception/ValueTypeIncompatibleException.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/exception/ValueTypeIncompatibleException.java
b/phoenix-core/src/main/java/org/apache/phoenix/exception/ValueTypeIncompatibleException.java
index 3f2be50..3adf415 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/exception/ValueTypeIncompatibleException.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/exception/ValueTypeIncompatibleException.java
@@ -23,11 +23,11 @@ import org.apache.phoenix.schema.PDataType;
 
 public class ValueTypeIncompatibleException extends IllegalDataException {
     private static final long serialVersionUID = 1L;
-    private static SQLExceptionCode code = SQLExceptionCode.DATA_INCOMPATIBLE_WITH_TYPE;
+    private static SQLExceptionCode code = SQLExceptionCode.DATA_EXCEEDS_MAX_CAPACITY;
 
     public ValueTypeIncompatibleException(PDataType type, Integer precision, Integer scale)
{
         super(new SQLExceptionInfo.Builder(code).setMessage(getTypeDisplayString(type, precision,
scale))
-                .build().toString());
+                .build().buildException());
     }
 
     private static String getTypeDisplayString(PDataType type, Integer precision, Integer
scale) {

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/65ac0ca3/phoenix-core/src/main/java/org/apache/phoenix/expression/ArithmeticExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/ArithmeticExpression.java
b/phoenix-core/src/main/java/org/apache/phoenix/expression/ArithmeticExpression.java
index 5128d07..247e9d7 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/ArithmeticExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/ArithmeticExpression.java
@@ -19,6 +19,8 @@ package org.apache.phoenix.expression;
 
 import java.util.List;
 
+import org.apache.phoenix.schema.PDataType;
+
 public abstract class ArithmeticExpression extends BaseCompoundExpression {
 
     public ArithmeticExpression() {
@@ -39,5 +41,34 @@ public abstract class ArithmeticExpression extends BaseCompoundExpression
{
         return buf.toString();
     }
     
+    protected Integer getScale(Expression e) {
+        Integer scale = e.getScale();
+        if (scale != null) {
+            return scale;
+        }
+        PDataType dataType = e.getDataType();
+        if (dataType != null) {
+            scale = dataType.getScale(null);
+            if (scale != null) {
+                return scale;
+            }
+        }
+        return null;
+    }
+    protected int getPrecision(Expression e) {
+        Integer precision = e.getMaxLength();
+        if (precision != null) {
+            return precision;
+        }
+        PDataType dataType = e.getDataType();
+        if (dataType != null) {
+            precision = dataType.getMaxLength(null);
+            if (precision != null) {
+                return precision;
+            }
+        }
+        return PDataType.MAX_PRECISION;
+    }
+    
     abstract protected String getOperatorString();
 }

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/65ac0ca3/phoenix-core/src/main/java/org/apache/phoenix/expression/BaseAddSubtractExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/BaseAddSubtractExpression.java
b/phoenix-core/src/main/java/org/apache/phoenix/expression/BaseAddSubtractExpression.java
index b91d5c7..da7bd9f 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/BaseAddSubtractExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/BaseAddSubtractExpression.java
@@ -30,40 +30,21 @@ abstract public class BaseAddSubtractExpression extends ArithmeticExpression
{
         super(children);
     }
 
-    protected static Integer getPrecision(Integer lp, Integer ls, Expression childExpr) {
-        if (childExpr.getDataType() == null) {
-            return null;
-        }
-        Integer rp = childExpr.getMaxLength();
-        Integer rs = childExpr.getScale();
-        if (rp == null) {
-            rp = childExpr.getDataType().getMaxLength(null);
-        }
-    	if (lp == null) {
-    		return rp;
-    	}
-    	if (rp == null) {
-    	    return lp;
-    	}
+    protected static Integer getPrecision(Integer lp, Integer rp, Integer ls, Integer rs)
{
         if (ls == null || rs == null) {
             return PDataType.MAX_PRECISION;
         }
-        int val = getScale(lp, ls, childExpr) + Math.max(lp - ls, rp - rs) + 1;
+        int val = getScale(lp, rp, ls, rs) + Math.max(lp - ls, rp - rs) + 1;
         return Math.min(PDataType.MAX_PRECISION, val);
     }
 
-    protected static Integer getScale(Integer lp, Integer ls, Expression childExpr) {
-        Integer rs = childExpr.getScale();
-    	// If we are adding a decimal with scale and precision to a decimal
-    	// with no precision nor scale, the scale system does not apply.
-        if (ls == null) {
-            return rs;
-        }
-        if (rs == null) {
-            return ls;
+    protected static Integer getScale(Integer lp, Integer rp, Integer ls, Integer rs) {
+        // If we are adding a decimal with scale and precision to a decimal
+        // with no precision nor scale, the scale system does not apply.
+        if (ls == null || rs == null) {
+            return null;
         }
         int val = Math.max(ls, rs);
         return Math.min(PDataType.MAX_PRECISION, val);
     }
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/65ac0ca3/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalAddExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalAddExpression.java
b/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalAddExpression.java
index 169afb9..3e4e4ed 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalAddExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalAddExpression.java
@@ -37,10 +37,13 @@ public class DecimalAddExpression extends AddExpression {
 
     public DecimalAddExpression(List<Expression> children) {
         super(children);
-        for (int i=0; i<children.size(); i++) {
+        Expression firstChild = children.get(0);
+        maxLength = getPrecision(firstChild);
+        scale = getScale(firstChild);
+        for (int i=1; i<children.size(); i++) {
             Expression childExpr = children.get(i);
-            maxLength = getPrecision(maxLength, scale, childExpr);
-            scale = getScale(maxLength, scale, childExpr);
+            maxLength = getPrecision(maxLength, getPrecision(childExpr), scale, getScale(childExpr));
+            scale = getScale(maxLength, getPrecision(childExpr), scale, getScale(childExpr));
         }
     }
 
@@ -66,7 +69,7 @@ public class DecimalAddExpression extends AddExpression {
                 result = result.add(bd);
             }
         }
-        if (maxLength != null && scale != null) {
+        if (maxLength != null || scale != null) {
             result = NumberUtil.setDecimalWidthAndScale(result, maxLength, scale);
         }
         if (result == null) {

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/65ac0ca3/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalDivideExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalDivideExpression.java
b/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalDivideExpression.java
index 78c9abe..fc37552 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalDivideExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalDivideExpression.java
@@ -21,10 +21,9 @@ import java.math.BigDecimal;
 import java.util.List;
 
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
-
 import org.apache.phoenix.exception.ValueTypeIncompatibleException;
-import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.schema.PDataType;
+import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.util.NumberUtil;
 
@@ -60,7 +59,7 @@ public class DecimalDivideExpression extends DivideExpression {
                 result = result.divide(bd, PDataType.DEFAULT_MATH_CONTEXT);
             }
         }
-        if (getMaxLength() != null && getScale() != null) {
+        if (getMaxLength() != null || getScale() != null) {
             result = NumberUtil.setDecimalWidthAndScale(result, getMaxLength(), getScale());
         }
         if (result == null) {

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/65ac0ca3/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalMultiplyExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalMultiplyExpression.java
b/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalMultiplyExpression.java
index 06a9336..ea34d36 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalMultiplyExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalMultiplyExpression.java
@@ -21,10 +21,9 @@ import java.math.BigDecimal;
 import java.util.List;
 
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
-
 import org.apache.phoenix.exception.ValueTypeIncompatibleException;
-import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.schema.PDataType;
+import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.util.NumberUtil;
 
@@ -60,7 +59,7 @@ public class DecimalMultiplyExpression extends MultiplyExpression {
                 result = result.multiply(bd);
             }
         }
-        if (getMaxLength() != null && getScale() != null) {
+        if (getMaxLength() != null || getScale() != null) {
             result = NumberUtil.setDecimalWidthAndScale(result, getMaxLength(), getScale());
         }
         if (result == null) {

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/65ac0ca3/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalSubtractExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalSubtractExpression.java
b/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalSubtractExpression.java
index 0e39cd9..8188a90 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalSubtractExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/DecimalSubtractExpression.java
@@ -44,10 +44,13 @@ public class DecimalSubtractExpression extends SubtractExpression {
 
     public DecimalSubtractExpression(List<Expression> children) {
         super(children);
-        for (int i=0; i<children.size(); i++) {
+        Expression firstChild = children.get(0);
+        maxLength = getPrecision(firstChild);
+        scale = getScale(firstChild);
+        for (int i=1; i<children.size(); i++) {
             Expression childExpr = children.get(i);
-            maxLength = getPrecision(maxLength, scale, childExpr);
-            scale = getScale(maxLength, scale, childExpr);
+            maxLength = getPrecision(maxLength, getPrecision(childExpr), scale, getScale(childExpr));
+            scale = getScale(maxLength, getPrecision(childExpr), scale, getScale(childExpr));
         }
     }
 
@@ -83,7 +86,7 @@ public class DecimalSubtractExpression extends SubtractExpression {
                 }
             }
         }
-        if (maxLength != null && scale != null) {
+        if (maxLength != null || scale != null) {
             result = NumberUtil.setDecimalWidthAndScale(result, maxLength, scale);
         }
         if (result == null) {

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/65ac0ca3/phoenix-core/src/main/java/org/apache/phoenix/expression/DivideExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/DivideExpression.java
b/phoenix-core/src/main/java/org/apache/phoenix/expression/DivideExpression.java
index f064b9d..5b5ffd8 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/DivideExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/DivideExpression.java
@@ -39,10 +39,13 @@ public abstract class DivideExpression extends ArithmeticExpression {
 
     public DivideExpression(List<Expression> children) {
         super(children);
-        for (int i=0; i<children.size(); i++) {
+        Expression firstChild = children.get(0);
+        maxLength = getPrecision(firstChild);
+        scale = getScale(firstChild);
+        for (int i=1; i<children.size(); i++) {
             Expression childExpr = children.get(i);
-            maxLength = getPrecision(maxLength, scale, childExpr);
-            scale = getScale(maxLength, scale, childExpr);
+            maxLength = getPrecision(maxLength, getPrecision(childExpr), scale, getScale(childExpr));
+            scale = getScale(maxLength, getPrecision(childExpr), scale, getScale(childExpr));
         }
     }
 
@@ -61,42 +64,25 @@ public abstract class DivideExpression extends ArithmeticExpression {
         return " / ";
     }
     
-    private static Integer getPrecision(Integer lp, Integer ls, Expression childExpr) {
-        if (childExpr.getDataType() == null) {
-            return null;
-        }
-        Integer rp = childExpr.getMaxLength();
-        if (rp == null) {
-            rp = childExpr.getDataType().getMaxLength(null);
-        }
-        if (lp == null) {
-            return rp;
-        }
-        if (rp == null) {
-            return lp;
+    private static Integer getPrecision(Integer lp, Integer rp, Integer ls, Integer rs) {
+        if (ls == null || rs == null) {
+            return PDataType.MAX_PRECISION;
         }
-        Integer rs = childExpr.getScale();
-    	if (ls == null || rs == null) {
-    		return PDataType.MAX_PRECISION;
-    	}
-        int val = getScale(lp, ls, childExpr) + lp - ls + rp;
+        int val = getScale(lp, rp, ls, rs) + lp - ls + rp;
         return Math.min(PDataType.MAX_PRECISION, val);
     }
 
-    private static Integer getScale(Integer lp, Integer ls, Expression childExpr) {
-    	// If we are adding a decimal with scale and precision to a decimal
-    	// with no precision nor scale, the scale system does not apply.
-        Integer rs = childExpr.getScale();
-        if (ls == null) {
-            return rs;
-        }
-        if (rs == null) {
-            return ls;
+    private static Integer getScale(Integer lp, Integer rp, Integer ls, Integer rs) {
+        // If we are adding a decimal with scale and precision to a decimal
+        // with no precision nor scale, the scale system does not apply.
+        if (ls == null || rs == null) {
+            return null;
         }
         int val = Math.max(PDataType.MAX_PRECISION - lp + ls - rs, 0);
         return Math.min(PDataType.MAX_PRECISION, val);
     }
 
+
     @Override
     public Integer getScale() {
         return scale;

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/65ac0ca3/phoenix-core/src/main/java/org/apache/phoenix/expression/LiteralExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/LiteralExpression.java
b/phoenix-core/src/main/java/org/apache/phoenix/expression/LiteralExpression.java
index 32950c6..d382518 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/LiteralExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/LiteralExpression.java
@@ -118,11 +118,11 @@ public class LiteralExpression extends BaseTerminalExpression {
     }
     
     public static LiteralExpression newConstant(Object value, PDataType type, SortOrder sortOrder)
throws SQLException {
-        return newConstant(value, type, type == null || !type.isFixedWidth() ? null : type.getMaxLength(value),
null, sortOrder, true);
+        return newConstant(value, type, null, null, sortOrder, true);
     }
     
     public static LiteralExpression newConstant(Object value, PDataType type, SortOrder sortOrder,
boolean isDeterministic) throws SQLException {
-        return newConstant(value, type, type == null || !type.isFixedWidth() ? null : type.getMaxLength(value),
null, sortOrder, isDeterministic);
+        return newConstant(value, type, null, null, sortOrder, isDeterministic);
     }
     
     public static LiteralExpression newConstant(Object value, PDataType type, Integer maxLength,
Integer scale) throws SQLException {
@@ -167,6 +167,9 @@ public class LiteralExpression extends BaseTerminalExpression {
             if (b.length == 0) {
                 return TYPED_NULL_EXPRESSIONS[type.ordinal()];
             }
+            if (maxLength == null) {
+                maxLength = type == null || !type.isFixedWidth() ? null : type.getMaxLength(value);
+            }
             return new LiteralExpression(value, type, b, maxLength, scale, sortOrder, isDeterministic);
         } catch (IllegalDataException e) {
             throw new SQLExceptionInfo.Builder(SQLExceptionCode.ILLEGAL_DATA).setRootCause(e).build().buildException();

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/65ac0ca3/phoenix-core/src/main/java/org/apache/phoenix/expression/MultiplyExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/MultiplyExpression.java
b/phoenix-core/src/main/java/org/apache/phoenix/expression/MultiplyExpression.java
index 6e089e9..90a4706 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/MultiplyExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/MultiplyExpression.java
@@ -39,10 +39,13 @@ public abstract class MultiplyExpression extends ArithmeticExpression
{
 
     public MultiplyExpression(List<Expression> children) {
         super(children);
-        for (int i=0; i<children.size(); i++) {
+        Expression firstChild = children.get(0);
+        maxLength = getPrecision(firstChild);
+        scale = getScale(firstChild);
+        for (int i=1; i<children.size(); i++) {
             Expression childExpr = children.get(i);
-            maxLength = getPrecision(maxLength, scale, childExpr);
-            scale = getScale(maxLength, scale, childExpr);
+            maxLength = getPrecision(maxLength, getPrecision(childExpr), scale, getScale(childExpr));
+            scale = getScale(maxLength, getPrecision(childExpr), scale, getScale(childExpr));
         }
     }
 
@@ -61,37 +64,19 @@ public abstract class MultiplyExpression extends ArithmeticExpression
{
         return " * ";
     }
     
-    private static Integer getPrecision(Integer lp, Integer ls, Expression childExpr) {
-        Integer rp = childExpr.getMaxLength();
-        if (childExpr.getDataType() == null) {
-            return null;
-        }
-        if (rp == null) {
-            rp = childExpr.getDataType().getMaxLength(null);
-        }
-        if (lp == null) {
-            return rp;
+    private static Integer getPrecision(Integer lp, Integer rp, Integer ls, Integer rs) {
+        if (ls == null || rs == null) {
+            return PDataType.MAX_PRECISION;
         }
-        if (rp == null) {
-            return lp;
-        }
-        Integer rs = childExpr.getScale();
-    	if (ls == null || rs == null) {
-    		return PDataType.MAX_PRECISION;
-    	}
         int val = lp + rp;
         return Math.min(PDataType.MAX_PRECISION, val);
     }
 
-    private static Integer getScale(Integer lp, Integer ls, Expression childExpr) {
-    	// If we are adding a decimal with scale and precision to a decimal
-    	// with no precision nor scale, the scale system does not apply.
-        Integer rs = childExpr.getScale();
-        if (ls == null) {
-            return rs;
-        }
-        if (rs == null) {
-            return ls;
+    private static Integer getScale(Integer lp, Integer rp, Integer ls, Integer rs) {
+        // If we are adding a decimal with scale and precision to a decimal
+        // with no precision nor scale, the scale system does not apply.
+        if (ls == null || rs == null) {
+            return null;
         }
         int val = ls + rs;
         return Math.min(PDataType.MAX_PRECISION, val);

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/65ac0ca3/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/util/KeyValueBuilder.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/util/KeyValueBuilder.java
b/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/util/KeyValueBuilder.java
index 0d27512..7b6a090 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/util/KeyValueBuilder.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/util/KeyValueBuilder.java
@@ -32,6 +32,8 @@ import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
  * Build {@link KeyValue} in an efficient way
  */
 public abstract class KeyValueBuilder {
+    public static final String CLIENT_KEY_VALUE_MIN_VERSION = "0.94.14";
+    private static final int CUSTOM_KEY_VALUE_MIN_VERSION = VersionUtil.encodeVersion("0.94.14");
 
     /**
      * Helper method for a {@link KeyValueBuilder} that catches an IOException from a {@link
Put}
@@ -63,8 +65,6 @@ public abstract class KeyValueBuilder {
         }
     }
 
-    private static final int CUSTOM_KEY_VALUE_MIN_VERSION = VersionUtil.encodeVersion("0.94.14");
-
     public static KeyValueBuilder get(String hbaseVersion) {
         int version = VersionUtil.encodeVersion(hbaseVersion);
         if (version >= CUSTOM_KEY_VALUE_MIN_VERSION) {

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/65ac0ca3/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexCodec.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexCodec.java b/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexCodec.java
index 7fb0add..800daf1 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexCodec.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexCodec.java
@@ -41,6 +41,7 @@ import org.apache.phoenix.hbase.index.covered.IndexCodec;
 import org.apache.phoenix.hbase.index.covered.IndexUpdate;
 import org.apache.phoenix.hbase.index.covered.TableState;
 import org.apache.phoenix.hbase.index.scanner.Scanner;
+import org.apache.phoenix.hbase.index.util.GenericKeyValueBuilder;
 import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
 import org.apache.phoenix.hbase.index.util.IndexManagementUtil;
 import org.apache.phoenix.hbase.index.util.KeyValueBuilder;
@@ -70,9 +71,9 @@ public class PhoenixIndexCodec extends BaseIndexCodec {
         // server
         conf.setIfUnset(IndexWriter.INDEX_FAILURE_POLICY_CONF_KEY,
             PhoenixIndexFailurePolicy.class.getName());
-        // We cannot use the ClientKeyValueBuilder because when these hit the memstore
-        // the memstore assmes we have a backing buffer.
-        this.kvBuilder = KeyValueBuilder.get(env.getHBaseVersion());
+        // Use the GenericKeyValueBuilder, as it's been shown in perf testing that ClientKeyValue
doesn't help
+        // TODO: Jesse to investigate more
+        this.kvBuilder = GenericKeyValueBuilder.INSTANCE;
     }
 
     List<IndexMaintainer> getIndexMaintainers(Map<String, byte[]> attributes)
throws IOException{

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/65ac0ca3/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
index f5a80c6..52926f7 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
@@ -889,6 +889,9 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices
implement
             throw new SQLException(t);
         }
     }
+    
+    // Our property values are translated using toString, so we need to "string-ify" this.
+    private static final String TRUE_BYTES_AS_STRING = Bytes.toString(PDataType.TRUE_BYTES);
 
     private void ensureViewIndexTableCreated(byte[] physicalTableName, Map<String,Object>
tableProps, List<Pair<byte[],Map<String,Object>>> families, byte[][] splits,
long timestamp) throws SQLException {
         Long maxFileSize = (Long)tableProps.get(HTableDescriptor.MAX_FILESIZE);
@@ -907,7 +910,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices
implement
         }
         long indexMaxFileSize = maxFileSize * indexMaxFileSizePerc / 100;
         tableProps.put(HTableDescriptor.MAX_FILESIZE, indexMaxFileSize);
-        tableProps.put(MetaDataUtil.IS_VIEW_INDEX_TABLE_PROP_NAME, PDataType.TRUE_BYTES);
+        tableProps.put(MetaDataUtil.IS_VIEW_INDEX_TABLE_PROP_NAME, TRUE_BYTES_AS_STRING);
         // Only use splits if table is salted, otherwise it may not be applicable
         HTableDescriptor desc = ensureTableCreated(physicalIndexName, PTableType.TABLE, tableProps,
families, splits, false);
         if (desc != null) {

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/65ac0ca3/phoenix-core/src/main/java/org/apache/phoenix/schema/PArrayDataType.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PArrayDataType.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PArrayDataType.java
index 3538bf9..97c481e 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PArrayDataType.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PArrayDataType.java
@@ -75,9 +75,11 @@ public class PArrayDataType {
 		return createArrayBytes(byteStream, oStream, (PhoenixArray)object, noOfElements, baseType,
0);
 	}
 	
-    private byte[] rewriteArrayBytes(byte[] bytes, Integer desiredMaxLength, Integer maxLength,
PDataType baseType) {
-        if (bytes == null || bytes.length == 0) { return null; }
-        ByteBuffer buffer = ByteBuffer.wrap(bytes, 0, bytes.length);
+    private void rewriteArrayBytes(ImmutableBytesWritable ptr, Integer desiredMaxLength,
Integer maxLength, PDataType baseType) {
+        if (ptr.getLength() == 0) {
+            return;
+        }
+        ByteBuffer buffer = ByteBuffer.wrap(ptr.get(), ptr.getOffset(), ptr.getLength());
         int initPos = buffer.position();
         buffer.position((buffer.limit() - (Bytes.SIZEOF_BYTE + Bytes.SIZEOF_INT)));
         int noOfElemPos = buffer.position();
@@ -101,7 +103,7 @@ public class PArrayDataType {
         }
         newBuffer.putInt(temp);
         newBuffer.put(ARRAY_SERIALIZATION_VERSION);
-        return newBuffer.array();
+        ptr.set(newBuffer.array());
     }
 
     public static int serializeNulls(DataOutputStream oStream, int nulls) throws IOException
{
@@ -220,24 +222,34 @@ public class PArrayDataType {
 		}
     }
 	
-	public boolean isSizeCompatible(PDataType srcType, Object value,
-			byte[] b, Integer maxLength, Integer desiredMaxLength,
-			Integer scale, Integer desiredScale) {
+	public boolean isSizeCompatible(ImmutableBytesWritable ptr, Object value,
+			PDataType srcType, Integer maxLength, Integer scale,
+			Integer desiredMaxLength, Integer desiredScale) {
 		PhoenixArray pArr = (PhoenixArray) value;
 		Object[] arr = (Object[]) pArr.array;
 		PDataType baseType = PDataType.fromTypeId(srcType.getSqlType()
 				- Types.ARRAY);
 		for (int i = 0 ; i < arr.length; i++) {
-			if (!baseType.isSizeCompatible(baseType, arr[i], b, srcType.getMaxLength(arr[i]),
-					desiredMaxLength, scale, desiredScale)) {
+			if (!baseType.isSizeCompatible(ptr, arr[i], baseType, srcType.getMaxLength(arr[i]),
+					scale, desiredMaxLength, desiredScale)) {
 				return false;
 			}
 		}
 		return true;
 	}
 	
-	public byte[] coerceBytes(byte[] b, Object value, PDataType actualType, Integer maxLength,
Integer scale,
-            Integer desiredMaxLength, Integer desiredScale) {
+	public void coerceBytes(ImmutableBytesWritable ptr, Object value, PDataType actualType,
Integer maxLength, Integer scale,
+            Integer desiredMaxLength, Integer desiredScale, PDataType desiredType) {
+	    if (ptr.getLength() == 0 || value == null) {
+	        return;
+	    }
+	    
+	    // TODO: handle bit inversion
+	    // TODO: handle coerce between different types
+	    // TODO: validate that maxLength and desiredMaxLength come through as expected
+	    // TODO: handle when value == null correct, as you may need to re-write due to coercian
to different type
+	    // or bit inversion
+	    //FIXME: don't write number of elements in the case of fixed width arrays as it will
mess up sort order
 	    PhoenixArray pArr = (PhoenixArray) value;
         Object[] arr = (Object[]) pArr.array;
         PDataType baseType = PDataType.fromTypeId(actualType.getSqlType()
@@ -250,9 +262,10 @@ public class PArrayDataType {
                     break;
                 }
             }
-            if (createNewArray) { return rewriteArrayBytes(b, desiredMaxLength, desiredMaxLength,
baseType); }
+            if (createNewArray) { 
+                rewriteArrayBytes(ptr, desiredMaxLength, desiredMaxLength, baseType); 
+            }
         }
-        return b;
 	}
 
 


Mime
View raw message