Skip to content

fix(server): normalize typed DEFAULT_VALUE after JSON reload#3035

Open
dpol1 wants to merge 1 commit into
apache:masterfrom
dpol1:fix/3028-preserve-default-value
Open

fix(server): normalize typed DEFAULT_VALUE after JSON reload#3035
dpol1 wants to merge 1 commit into
apache:masterfrom
dpol1:fix/3028-preserve-default-value

Conversation

@dpol1
Copy link
Copy Markdown
Contributor

@dpol1 dpol1 commented May 21, 2026

Purpose of the PR

Normalizes PropertyKey default values to their declared data type upon retrieval. Previously, values stored in userdata could lose their original type during serialization and deserialization (for example, a DATE default reloaded as a String), leading to type mismatches when applying defaults.

The defaultValue() method in both hugegraph-core and hugegraph-struct now converts deserialized representations back to their expected runtime types using the existing type-aware converters based on PropertyKey.dataType(). This ensures that typed defaults (such as DATE) remain correctly typed after a JSON round-trip and when applied to vertices and edges.

This change is verified with tests covering schema parsing, vertex property assignment, and both binary and text serializers.

Main Changes

  • Core PropertyKey.defaultValue() normalization

    • In hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/PropertyKey.java, defaultValue() now:
      • reads Userdata.DEFAULT_VALUE from userdata,
      • if non-null, normalizes it via validValue(value), which routes through the existing type-aware converters (convValue / convSingleValuedataType().valueToDate/Number/UUID/Blob).
    • This ensures that defaults reloaded from JSON as String (for typed keys such as DATE) are converted back to their runtime type before being used by consumers like HugeElement.updateToDefaultValueIfNone().
  • Struct PropertyKey.defaultValue() mirror

    • Applies the same normalization logic to hugegraph-struct/src/main/java/org/apache/hugegraph/struct/schema/PropertyKey.java so that struct PropertyKey behaves consistently with core:
      • defaultValue() also normalizes the stored ~default_value according to the DataType.
    • Adds a focused unit test PropertyKeyTest.testDefaultValueNormalizedToDate() in hugegraph-struct that constructs a DATE property key with a String default and asserts that defaultValue() returns a Date.
  • End-to-end vertex default application

    • Adds testAddVertexWithDateDefaultValue() to VertexCoreTest:
      • defines a DATE property key with Userdata.DEFAULT_VALUE set to a Date,
      • creates a vertex without explicitly setting that property,
      • commits, reloads the vertex from the backend (forcing schema reload),
      • asserts that the applied property is a Date with the expected value, not a String.
    • This reproduces and locks in the user-facing symptom from [Bug] Preserve typed DEFAULT_VALUE and struct userdata after JSON reload #3028 through HugeElement.updateToDefaultValueIfNone().
  • Serializer round-trip for DEFAULT_VALUE

    • Extends TextSerializerTest and BinarySerializerTest with:
      • testPropertyKeyDefaultValueRoundTripsAsDate():
        • serializes a DATE PropertyKey whose DEFAULT_VALUE is a Date,
        • deserializes it back,
        • asserts that defaultValue() on the reloaded key returns a Date equal to the original.
    • Ensures that both text and binary serializers preserve the typed default after a full round-trip.
  • Schema parsing normalization (core)

    • Extends SchemaElementTest with:
      • testPropertyKeyFromMapNormalizesDateDefaultValue():
        • builds a PropertyKey from a Map with DATA_TYPE=DATE and ~default_value as a formatted date String,
        • asserts that defaultValue() returns a Date.
      • testPropertyKeyFromMapNormalizesDateSetDefaultValue():
        • same as above but for Cardinality.SET, with ~default_value as a collection of date strings,
        • asserts that defaultValue() returns a Collection whose elements are all Date instances.
    • This validates both the scalar and collection branches of validValue() for DATE defaults.

Verifying these changes

  • Need tests and can be verified as follows:
    • hugegraph-core:
      • VertexCoreTest.testAddVertexWithDateDefaultValue()
      • SchemaElementTest.testPropertyKeyFromMapNormalizesDateDefaultValue()
      • SchemaElementTest.testPropertyKeyFromMapNormalizesDateSetDefaultValue()
    • Serializers:
      • TextSerializerTest.testPropertyKeyDefaultValueRoundTripsAsDate()
      • BinarySerializerTest.testPropertyKeyDefaultValueRoundTripsAsDate()
    • hugegraph-struct:
      • PropertyKeyTest.testDefaultValueNormalizedToDate()

All existing tests remain green.

Does this PR potentially affect the following parts?

  • Dependencies
  • Modify configurations
  • The public API
  • Other affects (typed here)
    • Tightens the behavior of PropertyKey.defaultValue() for malformed or type-incompatible defaults: such values are now validated and may trigger conversion errors instead of leaking unexpected raw String values at read time.
  • Nope

Documentation Status

  • Doc - TODO
  • Doc - Done
  • Doc - No Need

Normalizes PropertyKey default values to their declared data type upon retrieval. Previously, values stored in userdata could lose their original type during serialization and deserialization (e.g., Date becoming String), leading to type mismatches.

The `defaultValue()` method now converts deserialized string representations back to their expected runtime types. This change is verified with extensive tests covering schema parsing, vertex property assignment, and both binary and text serializers.

Fixes apache#3028
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. bug Something isn't working tests Add or improve test cases labels May 21, 2026
@dpol1 dpol1 changed the title normalize typed DEFAULT_VALUE after JSON reload fix(server): normalize typed DEFAULT_VALUE after JSON reload May 22, 2026
@imbajin imbajin requested a review from Copilot May 30, 2026 14:34
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes schema PropertyKey typed ~default_value (Userdata.DEFAULT_VALUE) losing runtime type after JSON (de)serialization by normalizing the stored default value back to the key’s declared DataType when retrieved.

Changes:

  • Normalize PropertyKey.defaultValue() in both hugegraph-core and hugegraph-struct via existing type-aware validValue(...) conversion.
  • Add regression coverage for DATE defaults across schema parsing (fromMap), serializer round-trips (text/binary), and vertex default application after backend reload.
  • Add a focused hugegraph-struct unit test validating defaultValue() returns a Date when userdata contains a formatted date String.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/schema/PropertyKey.java Normalize DEFAULT_VALUE on read in defaultValue() using validValue(...)
hugegraph-struct/src/main/java/org/apache/hugegraph/struct/schema/PropertyKey.java Mirror the same defaultValue() normalization behavior in struct schema model
hugegraph-struct/src/test/java/org/apache/hugegraph/struct/schema/PropertyKeyTest.java Add unit test ensuring string DATE default normalizes to java.util.Date
hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/TextSerializerTest.java Add text serializer round-trip test for DATE default value typing
hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/serializer/BinarySerializerTest.java Add binary serializer round-trip test for DATE default value typing
hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/core/SchemaElementTest.java Add fromMap(...) tests for SINGLE and SET DATE default value normalization
hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/VertexCoreTest.java Add end-to-end vertex test ensuring DATE default applies as Date after commit/reload

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Member

@imbajin imbajin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found one SET-cardinality regression in the default-value normalization path.

// value (e.g. Date) comes back as a String. Normalize it to the
// runtime type expected by this property key's data type. Idempotent
// for values already of the expected type.
return value == null ? null : this.validValue(value);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Preserve SET cardinality when normalizing defaults

defaultValue() now delegates ~default_value normalization to validValue(), but JSON-reloaded SET defaults arrive as an ArrayList. The existing convValue() then chooses the output collection from the input type, so a Cardinality.SET default can still come back as an ArrayList. The new SET test only asserts Collection, so it misses this.

This can install list-valued defaults for SET properties after schema reload, preserving duplicates and breaking cardinality semantics. Please make both core and struct PropertyKey.convValue() choose the target container from this.cardinality (LinkedHashSet for SET, ArrayList for LIST), and add a regression assertion that a SET default returns a Set and collapses duplicates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working size:L This PR changes 100-499 lines, ignoring generated files. tests Add or improve test cases

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Preserve typed DEFAULT_VALUE and struct userdata after JSON reload

3 participants