You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by bu...@apache.org on 2016/07/21 16:01:54 UTC

avro git commit: AVRO-1877 restore correct javaUnbox in Specific Compiler.

Repository: avro
Updated Branches:
  refs/heads/master 0376544cf -> 5259f26ec


AVRO-1877 restore correct javaUnbox in Specific Compiler.

Time logical types were broken by the patch for AVRO-1847, this
patch restores correct behavior with some minor refactoring to
clean up duplicate code.

Signed-off-by: Sean Busbey <bu...@cloudera.com>


Project: http://git-wip-us.apache.org/repos/asf/avro/repo
Commit: http://git-wip-us.apache.org/repos/asf/avro/commit/5259f26e
Tree: http://git-wip-us.apache.org/repos/asf/avro/tree/5259f26e
Diff: http://git-wip-us.apache.org/repos/asf/avro/diff/5259f26e

Branch: refs/heads/master
Commit: 5259f26ecee6c268f0ddc86ef45104fe967f267a
Parents: 0376544
Author: Yibing Shi <sh...@gmail.com>
Authored: Thu Jul 21 10:55:14 2016 -0500
Committer: Sean Busbey <bu...@cloudera.com>
Committed: Thu Jul 21 10:55:14 2016 -0500

----------------------------------------------------------------------
 .../compiler/specific/SpecificCompiler.java     | 43 +++++++---
 .../compiler/specific/TestSpecificCompiler.java | 90 ++++++++++++++++++++
 2 files changed, 121 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/avro/blob/5259f26e/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java
----------------------------------------------------------------------
diff --git a/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java b/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java
index 9ba36d3..762f84c 100644
--- a/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java
+++ b/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java
@@ -575,12 +575,14 @@ public class SpecificCompiler {
 
   /** Utility for template use.  Returns the java type for a Schema. */
   public String javaType(Schema schema) {
-    if (enableDecimalLogicalType
-        || !(schema.getLogicalType() instanceof LogicalTypes.Decimal)) {
-      Conversion<?> conversion = SPECIFIC
-          .getConversionFor(schema.getLogicalType());
-      if (conversion != null) {
-        return conversion.getConvertedType().getName();
+    return javaType(schema, true);
+  }
+
+  private String javaType(Schema schema, boolean checkConvertedLogicalType) {
+    if (checkConvertedLogicalType) {
+      String convertedLogicalType = getConvertedLogicalType(schema);
+      if (convertedLogicalType != null) {
+        return convertedLogicalType;
       }
     }
 
@@ -613,15 +615,32 @@ public class SpecificCompiler {
     }
   }
 
+  private String getConvertedLogicalType(Schema schema) {
+    if (enableDecimalLogicalType
+        || !(schema.getLogicalType() instanceof LogicalTypes.Decimal)) {
+      Conversion<?> conversion = SPECIFIC
+          .getConversionFor(schema.getLogicalType());
+      if (conversion != null) {
+        return conversion.getConvertedType().getName();
+      }
+    }
+    return null;
+  }
+
   /** Utility for template use.  Returns the unboxed java type for a Schema. */
   public String javaUnbox(Schema schema) {
+    String convertedLogicalType = getConvertedLogicalType(schema);
+    if (convertedLogicalType != null) {
+      return convertedLogicalType;
+    }
+
     switch (schema.getType()) {
-    case INT:     return "int";
-    case LONG:    return "long";
-    case FLOAT:   return "float";
-    case DOUBLE:  return "double";
-    case BOOLEAN: return "boolean";
-    default:      return javaType(schema);
+      case INT:     return "int";
+      case LONG:    return "long";
+      case FLOAT:   return "float";
+      case DOUBLE:  return "double";
+      case BOOLEAN: return "boolean";
+      default:      return javaType(schema, false);
     }
   }
 

http://git-wip-us.apache.org/repos/asf/avro/blob/5259f26e/lang/java/compiler/src/test/java/org/apache/avro/compiler/specific/TestSpecificCompiler.java
----------------------------------------------------------------------
diff --git a/lang/java/compiler/src/test/java/org/apache/avro/compiler/specific/TestSpecificCompiler.java b/lang/java/compiler/src/test/java/org/apache/avro/compiler/specific/TestSpecificCompiler.java
index 58d2af4..25ad97d 100644
--- a/lang/java/compiler/src/test/java/org/apache/avro/compiler/specific/TestSpecificCompiler.java
+++ b/lang/java/compiler/src/test/java/org/apache/avro/compiler/specific/TestSpecificCompiler.java
@@ -363,6 +363,96 @@ public class TestSpecificCompiler {
   }
 
   @Test
+  public void testJavaUnbox() throws Exception {
+    SpecificCompiler compiler = createCompiler();
+    compiler.setEnableDecimalLogicalType(false);
+
+    Schema intSchema = Schema.create(Schema.Type.INT);
+    Schema longSchema = Schema.create(Schema.Type.LONG);
+    Schema floatSchema = Schema.create(Schema.Type.FLOAT);
+    Schema doubleSchema = Schema.create(Schema.Type.DOUBLE);
+    Schema boolSchema = Schema.create(Schema.Type.BOOLEAN);
+    Assert.assertEquals("Should use int for Type.INT",
+        "int", compiler.javaUnbox(intSchema));
+    Assert.assertEquals("Should use long for Type.LONG",
+        "long", compiler.javaUnbox(longSchema));
+    Assert.assertEquals("Should use float for Type.FLOAT",
+        "float", compiler.javaUnbox(floatSchema));
+    Assert.assertEquals("Should use double for Type.DOUBLE",
+        "double", compiler.javaUnbox(doubleSchema));
+    Assert.assertEquals("Should use boolean for Type.BOOLEAN",
+        "boolean", compiler.javaUnbox(boolSchema));
+
+    Schema dateSchema = LogicalTypes.date()
+        .addToSchema(Schema.create(Schema.Type.INT));
+    Schema timeSchema = LogicalTypes.timeMillis()
+        .addToSchema(Schema.create(Schema.Type.INT));
+    Schema timestampSchema = LogicalTypes.timestampMillis()
+        .addToSchema(Schema.create(Schema.Type.LONG));
+    // Date/time types should always use upper level java classes, even though
+    // their underlying representations are primitive types
+    Assert.assertEquals("Should use Joda LocalDate for date type",
+        "org.joda.time.LocalDate", compiler.javaUnbox(dateSchema));
+    Assert.assertEquals("Should use Joda LocalTime for time-millis type",
+        "org.joda.time.LocalTime", compiler.javaUnbox(timeSchema));
+    Assert.assertEquals("Should use Joda DateTime for timestamp-millis type",
+        "org.joda.time.DateTime", compiler.javaUnbox(timestampSchema));
+
+  }
+
+  @Test
+  public void testNullableTypesJavaUnbox() throws Exception {
+    SpecificCompiler compiler = createCompiler();
+    compiler.setEnableDecimalLogicalType(false);
+
+    // Nullable types should return boxed types instead of primitive types
+    Schema nullableIntSchema1 = Schema.createUnion(
+        Schema.create(Schema.Type.NULL), Schema.create(Schema.Type.INT));
+    Schema nullableIntSchema2 = Schema.createUnion(
+        Schema.create(Schema.Type.INT), Schema.create(Schema.Type.NULL));
+    Assert.assertEquals("Should return boxed type",
+        compiler.javaUnbox(nullableIntSchema1), "java.lang.Integer");
+    Assert.assertEquals("Should return boxed type",
+        compiler.javaUnbox(nullableIntSchema2), "java.lang.Integer");
+
+    Schema nullableLongSchema1 = Schema.createUnion(
+        Schema.create(Schema.Type.NULL), Schema.create(Schema.Type.LONG));
+    Schema nullableLongSchema2 = Schema.createUnion(
+        Schema.create(Schema.Type.LONG), Schema.create(Schema.Type.NULL));
+    Assert.assertEquals("Should return boxed type",
+        compiler.javaUnbox(nullableLongSchema1), "java.lang.Long");
+    Assert.assertEquals("Should return boxed type",
+        compiler.javaUnbox(nullableLongSchema2), "java.lang.Long");
+
+    Schema nullableFloatSchema1 = Schema.createUnion(
+        Schema.create(Schema.Type.NULL), Schema.create(Schema.Type.FLOAT));
+    Schema nullableFloatSchema2 = Schema.createUnion(
+        Schema.create(Schema.Type.FLOAT), Schema.create(Schema.Type.NULL));
+    Assert.assertEquals("Should return boxed type",
+        compiler.javaUnbox(nullableFloatSchema1), "java.lang.Float");
+    Assert.assertEquals("Should return boxed type",
+        compiler.javaUnbox(nullableFloatSchema2), "java.lang.Float");
+
+    Schema nullableDoubleSchema1 = Schema.createUnion(
+        Schema.create(Schema.Type.NULL), Schema.create(Schema.Type.DOUBLE));
+    Schema nullableDoubleSchema2 = Schema.createUnion(
+        Schema.create(Schema.Type.DOUBLE), Schema.create(Schema.Type.NULL));
+    Assert.assertEquals("Should return boxed type",
+        compiler.javaUnbox(nullableDoubleSchema1), "java.lang.Double");
+    Assert.assertEquals("Should return boxed type",
+        compiler.javaUnbox(nullableDoubleSchema2), "java.lang.Double");
+
+    Schema nullableBooleanSchema1 = Schema.createUnion(
+        Schema.create(Schema.Type.NULL), Schema.create(Schema.Type.BOOLEAN));
+    Schema nullableBooleanSchema2 = Schema.createUnion(
+        Schema.create(Schema.Type.BOOLEAN), Schema.create(Schema.Type.NULL));
+    Assert.assertEquals("Should return boxed type",
+        compiler.javaUnbox(nullableBooleanSchema1), "java.lang.Boolean");
+    Assert.assertEquals("Should return boxed type",
+        compiler.javaUnbox(nullableBooleanSchema2), "java.lang.Boolean");
+  }
+
+  @Test
   public void testLogicalTypesWithMultipleFields() throws Exception {
     Schema logicalTypesWithMultipleFields = new Schema.Parser().parse(
         new File("src/test/resources/simple_record.avsc"));