Skip to content

Merge erdomke fork improvements (d0f3634) with conflict resolution#4

Merged
nikoraes merged 17 commits into
mainfrom
merge-erdomke-fork
May 28, 2026
Merged

Merge erdomke fork improvements (d0f3634) with conflict resolution#4
nikoraes merged 17 commits into
mainfrom
merge-erdomke-fork

Conversation

@nikoraes

Copy link
Copy Markdown
Member

This PR merges the improvements from erdomke's fork into main, resolving merge conflicts.

Changes from the fork:

  • Generic Get<T>() deserialization — central type-aware parser via JsonSerializer + custom converters
  • Proper handling of Infinity/NaN — encoded with \u0000 prefix in ToJson, decoded by special converters
  • Backslash escaping fix — removed broken EscapeCypher that double-escaped backslashes
  • ::numeric type annotations — handled via ToJson → converter pipeline
  • Edge<T>/Vertex<T>/Entity<T> records — strongly-typed graph entities with polymorphism
  • Path as record — uses IReadOnlyList segments
  • Efficient byte-level I/O — ReadOnlySequence avoids string allocations
  • Dynamic return type support — Get() with custom converters handles runtime types

Preserved from existing code:

  • Explicit operators for Vertex, Edge, Dictionary
  • IsArray, IsMap, IsNull, IsJsonString properties
  • Existing test coverage (updated for new API)

erdomke-ansys and others added 9 commits February 24, 2026 15:49
- Escaping backslashes in incoming Cypher is breaking string literals with escapes.
- String values with escapes are not properly deserialized.
- Values with the `::numeric` type annotation are not handled.
- `Infinity`, `-Infinity`, and `NaN` are not properly handled. These are returned as raw tokens (not JSON strings). The current parsing also doesn't allow these values to be deeply nested in structures.
- No handling for returning maps from Cypher
- No way to dynamically handle the return type of a Cypher query at run time. The current code only works when the return types are known at design time.
- No way to serialize/deserialize strongly-typed classes.
Incorporates fixes and improvements from erdomke's fork:
- Generic Get<T>() deserialization with custom converters
- Proper Infinity/NaN handling
- Backslash escaping fix
- ::numeric type annotations support
- Edge<T>/Vertex<T>/Entity<T> records with polymorphism
- Path as record with IReadOnlyList segments
- Efficient byte-level I/O (ReadOnlySequence<byte>)
- Dynamic return type support

Resolved merge conflicts in Agtype.cs and updated tests for new API.
…ric type assertion, skip ::jsonb::agtype test on AGE 1.5.0

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR merges upstream fork changes to modernize Agtype parsing/serialization and graph entity modeling, aiming to improve correctness (Infinity/NaN, ::numeric, escaping) and performance (byte-level I/O, fewer allocations) while updating tests accordingly.

Changes:

  • Refactors Agtype to store UTF-8 bytes (ReadOnlySequence<byte>) and introduces a Get<T>() pipeline based on JsonSerializer + custom converters.
  • Introduces strongly-typed graph entity records (Entity<T>, Vertex<T>, Edge<T>) and updates Path to a record with segment lists.
  • Updates Npgsql extension methods and test suite to align with the new parsing/serialization behavior.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
test/Npgsql.AgeTests/TestBase.cs Adds AGE version detection to gate tests that require newer server features.
test/Npgsql.AgeTests/CypherHelperTests.cs Removes the EscapeCypher backslash-escaping test (helper removed).
test/Npgsql.AgeTests/AgTypeTests.cs Updates expectations for JSON-based parsing and new entity/path models.
test/Npgsql.AgeTests/AgeIntegrationTests.cs Adds integration coverage for escaping, special values, and typed returns; updates array tests to list-based API.
src/Npgsql.Age/Types/Agtype.cs Reworks Agtype storage/IO, adds Get<T>(), and implements agtype→JSON translation for deserialization.
src/Npgsql.Age/Types/Entity.cs Adds base record type for graph entities.
src/Npgsql.Age/Types/Vertex.cs Converts Vertex into record(s) using shared serialization options.
src/Npgsql.Age/Types/Edge.cs Converts Edge into record(s) using shared serialization options and JSON property naming.
src/Npgsql.Age/Types/Path.cs Converts Path into a record based on segment lists and serialization options.
src/Npgsql.Age/NpgsqlAgeExtensions.cs Stops escaping cypher text and switches parameter serialization to Agtype.Create(...).
src/Npgsql.Age/Internal/CypherHelpers.cs Removes EscapeCypher helper.
src/Npgsql.Age/Internal/AgtypeConverter.cs Updates Npgsql type converter to read/write agtype using byte sequences and streaming writes.
src/Npgsql.Age/Internal/JsonConverters/SerializerOptions.cs Splits read/write serializer options and adds converter/polymorphism configuration.
src/Npgsql.Age/Internal/JsonConverters/PathObjectConverter.cs Implements custom (de)serialization for Path via $type + segments.
src/Npgsql.Age/Internal/JsonConverters/InferredObjectConverter.cs Updates inference logic for object values and typed entities/paths.
src/Npgsql.Age/Internal/JsonConverters/EntityConverterFactory.cs Adds a converter factory to emit ::vertex/::edge literals during serialization.
src/Npgsql.Age/Internal/JsonConverters/IntegerConverter.cs Adds int converter that can parse special string-encoded numeric forms.
src/Npgsql.Age/Internal/JsonConverters/FloatConverter.cs Adds float converter to write/read Infinity/NaN forms in agtype syntax.
src/Npgsql.Age/Internal/JsonConverters/DoubleConverter.cs Adds double converter to write/read Infinity/NaN forms in agtype syntax.
src/Npgsql.Age/Internal/JsonConverters/DecimalConverter.cs Adds decimal converter to emit and parse ::numeric literals.

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

Comment thread src/Npgsql.Age/Types/Agtype.cs
Comment thread src/Npgsql.Age/Types/Agtype.cs
Comment thread src/Npgsql.Age/Types/Agtype.cs Outdated
Comment thread src/Npgsql.Age/Types/Agtype.cs
Comment thread src/Npgsql.Age/Types/Agtype.cs Outdated
Comment thread src/Npgsql.Age/Types/Edge.cs Outdated
Comment thread src/Npgsql.Age/Types/Path.cs Outdated
Comment thread src/Npgsql.Age/Types/Path.cs Outdated
Comment thread test/Npgsql.AgeTests/TestBase.cs Outdated
Comment thread test/Npgsql.AgeTests/AgTypeTests.cs Outdated
nikoraes added 3 commits May 28, 2026 14:10
…s private init, empty guard, XML doc fix, DecimalConverter invariant culture, remove Entity.GetHashCode, restore public Agtype ctor, fix DataSource leak, fix test reference
@nikoraes

Copy link
Copy Markdown
Member Author

fixes #5

@nikoraes nikoraes linked an issue May 28, 2026 that may be closed by this pull request
@nikoraes nikoraes merged commit 03c281c into main May 28, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AgTypeConverter has a sync over async implementation

3 participants