Skip to content

Map byte[] to json/jsonb as a raw JSON document again - #3935

Open
Aykuttonpc wants to merge 1 commit into
npgsql:mainfrom
Aykuttonpc:scout/efcore.pg-3698-byte-array-jsonb
Open

Aykuttonpc wants to merge 1 commit into
npgsql:mainfrom
Aykuttonpc:scout/efcore.pg-3698-byte-array-jsonb

Conversation

@Aykuttonpc

Copy link
Copy Markdown

Fixes #3698

Since 10.0, a byte[] property mapped to a json/jsonb column is picked up by NpgsqlTypeMappingSource.FindCollectionMapping as a JSON primitive collection of bytes. It is written as a JSON array of numbers, and rows holding real JSON documents (e.g. written by 9.x) fail to materialize with "Invalid token type: 'StartObject'".

This restores the 9.x behavior, using the same approach as the multidimensional array fix (#3663): unless an element mapping is explicitly configured (e.g. via PrimitiveCollection()), FindCollectionMapping returns null for byte[] on json/jsonb, so FindBaseMapping falls back to NpgsqlJsonTypeMapping, which sends the bytes as the raw UTF-8 document as supported by Npgsql. The default bytea mapping and the byte[] -> smallint[] array mapping are unaffected.

Tests

  • NpgsqlTypeMappingSourceTest.Json_byte_array (json, jsonb): byte[] with a json/jsonb store type resolves to NpgsqlJsonTypeMapping with ClrType byte[] and no element mapping (fails before this change).
  • NpgsqlTypeMappingSourceTest.Json_byte_array_configured_as_primitive_collection: PrimitiveCollection() on byte[] with jsonb still produces a primitive collection with a smallint element mapping.
  • AdHocJsonQueryNpgsqlTest.Byte_array_mapped_to_json_column (json, jsonb): writes a document through EF and checks the stored value with ->>, reads a document inserted with raw SQL, and updates it (fails before this change).

Notes

  • Data written by 10.0 under this mapping is stored as a JSON array of byte values. With this change it is read back as the raw bytes of that array text. Users who depend on the 10.0 representation can keep it by configuring the property with PrimitiveCollection(); otherwise the stored data needs converting.
  • Only byte[] is restored. char[] (and ArraySegment), which Npgsql also writes to json/jsonb as raw text, went through the same change in 10.0; I left it out since the issue is about byte[], but the same check could cover it.
  • JsonAgg/JsonbAgg (which return byte[]) also go back to their 9.x behavior: the aggregated JSON array is read as its raw bytes.

byte[] mapped to a json/jsonb column was picked up as a primitive
collection of bytes, so it was written as a JSON array of numbers and
failed to read existing JSON documents. Unless an element mapping is
explicitly configured, fall back to NpgsqlJsonTypeMapping as before.

This branch has not been deployed

No deployments
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.

byte[] can't be used anymore for jsonb columns

1 participant