christinefeng commented on a change in pull request #616: PHOENIX-5432:
Refactor LiteralExpression to use the builder pattern
URL: https://github.com/apache/phoenix/pull/616#discussion_r347703123
##########
File path:
phoenix-core/src/main/java/org/apache/phoenix/expression/LiteralExpression.java
##########
@@ -57,181 +56,236 @@
private static final LiteralExpression[] NULL_EXPRESSIONS = new
LiteralExpression[Determinism.values().length];
private static final LiteralExpression[] TYPED_NULL_EXPRESSIONS = new
LiteralExpression[PDataType.values().length * Determinism.values().length];
private static final LiteralExpression[] BOOLEAN_EXPRESSIONS = new
LiteralExpression[2 * Determinism.values().length];
-
+
static {
for (Determinism determinism : Determinism.values()) {
- NULL_EXPRESSIONS[determinism.ordinal()] = new
LiteralExpression(null, determinism);
+ NULL_EXPRESSIONS[determinism.ordinal()] = new
LiteralExpression(null, null,
+ ByteUtil.EMPTY_BYTE_ARRAY, null, null,
SortOrder.getDefault(), determinism);
for (int i = 0; i < PDataType.values().length; i++) {
-
TYPED_NULL_EXPRESSIONS[i+PDataType.values().length*determinism.ordinal()] = new
LiteralExpression(PDataType.values()[i], determinism);
- }
- BOOLEAN_EXPRESSIONS[determinism.ordinal()] = new
LiteralExpression(Boolean.FALSE,
- PBoolean.INSTANCE, PBoolean.INSTANCE.toBytes(Boolean.FALSE),
determinism);
-
BOOLEAN_EXPRESSIONS[Determinism.values().length+determinism.ordinal()] = new
LiteralExpression(Boolean.TRUE, PBoolean.INSTANCE,
PBoolean.INSTANCE.toBytes(Boolean.TRUE), determinism);
+ PDataType type = PDataType.values()[i];
+
TYPED_NULL_EXPRESSIONS[i+PDataType.values().length*determinism.ordinal()] =
+ new LiteralExpression(null, type,
ByteUtil.EMPTY_BYTE_ARRAY,
+ !type.isFixedWidth() ? null :
type.getMaxLength(null), null,
+ SortOrder.getDefault(), determinism);
+ }
+ BOOLEAN_EXPRESSIONS[determinism.ordinal()] = new
LiteralExpression(Boolean.FALSE,
+ PBoolean.INSTANCE,
PBoolean.INSTANCE.toBytes(Boolean.FALSE),
+ !PBoolean.INSTANCE.isFixedWidth() ? null :
+ PBoolean.INSTANCE.getMaxLength(null), null,
SortOrder.getDefault(),
+ determinism);
+
+ BOOLEAN_EXPRESSIONS[Determinism.values().length +
determinism.ordinal()] =
+ new LiteralExpression(Boolean.TRUE, PBoolean.INSTANCE,
+ PBoolean.INSTANCE.toBytes(Boolean.TRUE),
!PBoolean.INSTANCE.isFixedWidth() ? null
+ : PBoolean.INSTANCE.getMaxLength(null), null,
SortOrder.getDefault(),
+ determinism);
}
}
-
+
private Object value;
private PDataType type;
private Determinism determinism;
private byte[] byteValue;
private Integer maxLength;
private Integer scale;
private SortOrder sortOrder;
-
+
private static LiteralExpression getNullLiteralExpression(Determinism
determinism) {
- return NULL_EXPRESSIONS[determinism.ordinal()] ;
+ return NULL_EXPRESSIONS[determinism.ordinal()] ;
}
-
+
private static LiteralExpression getTypedNullLiteralExpression(PDataType
type, Determinism determinism){
- return
TYPED_NULL_EXPRESSIONS[type.ordinal()+PDataType.values().length*determinism.ordinal()];
+ return
TYPED_NULL_EXPRESSIONS[type.ordinal()+PDataType.values().length*determinism.ordinal()];
}
-
+
private static LiteralExpression getBooleanLiteralExpression(Boolean bool,
Determinism determinism){
- return BOOLEAN_EXPRESSIONS[ (Boolean.FALSE.equals(bool) ? 0 :
Determinism.values().length) + determinism.ordinal()];
+ return BOOLEAN_EXPRESSIONS[ (Boolean.FALSE.equals(bool) ? 0 :
Determinism.values().length) + determinism.ordinal()];
}
public static boolean isFalse(Expression child) {
- if (child!=null) {
+ if (child != null) {
return child ==
BOOLEAN_EXPRESSIONS[child.getDeterminism().ordinal()];
}
return false;
}
-
+
public static boolean isTrue(Expression child) {
- if (child!=null) {
- return child ==
BOOLEAN_EXPRESSIONS[Determinism.values().length+child.getDeterminism().ordinal()];
- }
- return false;
+ if (child != null) {
+ return child ==
BOOLEAN_EXPRESSIONS[Determinism.values().length+child.getDeterminism().ordinal()];
+ }
+ return false;
}
public static boolean isBooleanNull(Expression child) {
- if (child!=null) {
- return child ==
TYPED_NULL_EXPRESSIONS[PBoolean.INSTANCE.ordinal()+PDataType.values().length*child.getDeterminism().ordinal()];
- }
- return false;
+ if (child != null) {
+ return child ==
TYPED_NULL_EXPRESSIONS[PBoolean.INSTANCE.ordinal()+PDataType.values().length*child.getDeterminism().ordinal()];
+ }
+ return false;
}
public static boolean isBooleanFalseOrNull(Expression child) {
- if (child!=null) {
+ if (child != null) {
return child ==
BOOLEAN_EXPRESSIONS[child.getDeterminism().ordinal()]
|| child ==
TYPED_NULL_EXPRESSIONS[PBoolean.INSTANCE.ordinal()+PDataType.values().length*child.getDeterminism().ordinal()];
}
return false;
}
-
- public static LiteralExpression newConstant(Object value) {
- return newConstant(value, Determinism.ALWAYS);
- }
-
- // TODO: cache?
- public static LiteralExpression newConstant(Object value, Determinism
determinism) {
- if (value instanceof Boolean) {
- return getBooleanLiteralExpression((Boolean)value, determinism);
+
+ public static class Builder {
+
+ private Object value;
+ private PDataType type;
+ private Determinism determinism;
+ private byte[] byteValue;
+ private Integer maxLength;
+ private Integer scale;
+ private SortOrder sortOrder;
+ private Boolean rowKeyOrderOptimizable; //Changed type of this field
from primitive to object since its value should be true if not explicitly set
in Builder
+
+ public Builder setValue(Object value) {
+ this.value=value;
+ return this;
}
- else if (value == null) {
- return getNullLiteralExpression(determinism);
+
+ public Builder setDataType(PDataType type) {
+ this.type=type;
+ return this;
}
- PDataType type = PDataType.fromLiteral(value);
- byte[] b = type.toBytes(value);
- if (type.isNull(b)) {
- return getTypedNullLiteralExpression(type, determinism);
+
+ public Builder setDeterminism(Determinism determinism) {
+ this.determinism=determinism;
+ return this;
}
- if (type == PVarchar.INSTANCE) {
- String s = (String) value;
- if (s.length() == b.length) { // single byte characters only
- type = PChar.INSTANCE;
- }
+
+ public Builder setRowKeyOrderOptimizable(Boolean
rowKeyOrderOptimizable) {
+ this.rowKeyOrderOptimizable=rowKeyOrderOptimizable;
+ return this;
}
- return new LiteralExpression(value, type, b, determinism);
- }
- public static LiteralExpression newConstant(Object value, PDataType type)
throws SQLException {
- return newConstant(value, type, Determinism.ALWAYS);
- }
-
- public static LiteralExpression newConstant(Object value, PDataType type,
Determinism determinism) throws SQLException {
- return newConstant(value, type, SortOrder.getDefault(), determinism);
- }
-
- public static LiteralExpression newConstant(Object value, PDataType type,
SortOrder sortOrder) throws SQLException {
- return newConstant(value, type, null, null, sortOrder,
Determinism.ALWAYS);
- }
-
- public static LiteralExpression newConstant(Object value, PDataType type,
SortOrder sortOrder, Determinism determinism) throws SQLException {
- return newConstant(value, type, null, null, sortOrder, determinism);
- }
-
- public static LiteralExpression newConstant(Object value, PDataType type,
Integer maxLength, Integer scale) throws SQLException {
- return newConstant(value, type, maxLength, scale,
SortOrder.getDefault(), Determinism.ALWAYS);
- }
-
- public static LiteralExpression newConstant(Object value, PDataType type,
Integer maxLength, Integer scale, Determinism determinism) throws SQLException
{ // remove?
- return newConstant(value, type, maxLength, scale,
SortOrder.getDefault(), determinism);
- }
+ public Builder setMaxLength(Integer maxLength) {
+ this.maxLength=maxLength;
+ return this;
+ }
- public static LiteralExpression newConstant(Object value, PDataType type,
Integer maxLength, Integer scale, SortOrder sortOrder, Determinism determinism)
- throws SQLException {
- return newConstant(value, type, maxLength, scale, sortOrder,
determinism, true);
- }
-
- // TODO: cache?
- public static LiteralExpression newConstant(Object value, PDataType type,
Integer maxLength, Integer scale, SortOrder sortOrder, Determinism determinism,
boolean rowKeyOrderOptimizable)
- throws SQLException {
- if (value == null) {
- return (type == null) ? getNullLiteralExpression(determinism) :
getTypedNullLiteralExpression(type, determinism);
+ public Builder setScale(Integer scale) {
+ this.scale=scale;
+ return this;
}
- else if (value instanceof Boolean) {
- return getBooleanLiteralExpression((Boolean)value, determinism);
+
+ public Builder setSortOrder(SortOrder sortOrder) {
+ this.sortOrder=sortOrder;
+ return this;
}
- PDataType actualType = PDataType.fromLiteral(value);
- type = type == null ? actualType : type;
- try {
- value = type.toObject(value, actualType);
- } catch (IllegalDataException e) {
- throw TypeMismatchException.newException(type, actualType,
value.toString());
+
+ public Builder setByteValue(byte[] byteValue) {
+ this.byteValue=byteValue;
+ return this;
}
- byte[] b = type.isArrayType() ? ((PArrayDataType)type).toBytes(value,
PArrayDataType.arrayBaseType(type), sortOrder, rowKeyOrderOptimizable) :
- type.toBytes(value, sortOrder);
- if (type == PVarchar.INSTANCE || type == PChar.INSTANCE) {
- if (type == PChar.INSTANCE && maxLength != null && b.length <
maxLength) {
- if (rowKeyOrderOptimizable) {
- b = type.pad(b, maxLength, sortOrder);
- } else {
- b = StringUtil.padChar(b, maxLength);
- }
- } else if (value != null) {
- maxLength = ((String)value).length();
+
+ private void setDefaults() {
+ if (this.determinism == null) {
+ this.determinism = Determinism.ALWAYS;
+ }
+ if (this.sortOrder == null) {
+ this.sortOrder = SortOrder.getDefault();
+ }
+ if (this.rowKeyOrderOptimizable == null) {
+ this.rowKeyOrderOptimizable = true;
}
- } else if (type.isArrayType()) {
- maxLength = ((PhoenixArray)value).getMaxLength();
- }
- if (b.length == 0) {
- return getTypedNullLiteralExpression(type, determinism);
- }
- if (maxLength == null) {
- maxLength = type.isFixedWidth() ? type.getMaxLength(value) : null;
}
- return new LiteralExpression(value, type, b, maxLength, scale,
sortOrder, determinism);
- }
- public LiteralExpression() {
- }
-
- public LiteralExpression(byte[] byteValue) {
- this.byteValue = byteValue!=null ? byteValue :
ByteUtil.EMPTY_BYTE_ARRAY;
- this.determinism = Determinism.ALWAYS;
- }
+ /**
+ * Build method for Literal Expressions that have only fields value
and determinism (can be null)
+ * or only field byteValue
+ * @param byteValueOnly true if LiteralExpression's only field is
byteValue; false otherwise
+ * @return LiteralExpression object
+ */
+ public LiteralExpression buildValueAndDeterminism(boolean
byteValueOnly) {
+ if (byteValueOnly) {
+ return new LiteralExpression(null, null, this.byteValue =
this.byteValue != null
Review comment:
I see in PTableImpl, there's a public build method that calls the private
initDerivedAttributes method based on whether a particular field is null.
I could change my code to do a similar thing, but in my case the public
build method would have no function other than calling the method that
initializes derived attributes, since it needs to be called in all cases, if
that makes sense.
Either way, the actual LiteralExpression constructor I included is private,
and the two build methods (build() and buildValueAndDeterminism(), which call
the constructor) are public.
Let me know if you feel I should change it so there's a public build method
calling the private initDerivedAttributes method.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services