Fix hstore SQL literal generation for null and escaped values#3780
Open
brianpursley wants to merge 3 commits intonpgsql:mainfrom
Open
Fix hstore SQL literal generation for null and escaped values#3780brianpursley wants to merge 3 commits intonpgsql:mainfrom
brianpursley wants to merge 3 commits intonpgsql:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes SQL literal generation for PostgreSQL hstore in NpgsqlHstoreTypeMapping to correctly handle null values, empty dictionaries, and escaping of special characters, with unit tests covering the corrected behavior.
Changes:
- Reworked
hstoreSQL literal generation to emit separators correctly and support empty dictionaries. - Added proper escaping for
\,"and'when generatinghstoreSQL literals. - Added unit tests for null values, escaping, and empty dictionaries.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/EFCore.PG/Storage/Internal/Mapping/NpgsqlHstoreTypeMapping.cs |
Fixes hstore SQL literal formatting/escaping and handles empty dictionaries safely. |
test/EFCore.PG.Tests/Storage/NpgsqlTypeMappingTest.cs |
Adds unit test coverage for the fixed hstore literal generation edge cases. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This reverts commit f1eac90.
Contributor
Author
|
Here is a simple Program.cs that exercises the changes: using var dbContext = new ExampleDbContext();
dbContext.Database.EnsureDeleted();
dbContext.Database.EnsureCreated();
dbContext.Blogs.Add(new Blog { Name = "ABC"});
dbContext.SaveChanges();
var blog = dbContext.Blogs.Single(b => b.Name == "ABC");
foreach (var item in blog.Features!)
{
Console.WriteLine($"{item.Key}: {item.Value ?? "<NULL>"}");
}
public class ExampleDbContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasPostgresExtension("hstore");
modelBuilder.Entity<Blog>()
.Property(x => x.Features)
.HasDefaultValue(new Dictionary<string, string?>
{
["k1"] = null,
["k\"2\""] = "v\"2\"",
["k'3'"] = "v'3'",
["k\\4"] = "v\\4"
});
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseNpgsql("Host=localhost;Username=postgres;Password=postgres;Database=ExampleDb")
.LogTo(Console.WriteLine, LogLevel.Information)
.EnableSensitiveDataLogging();
}
}
public class Blog
{
public int Id { get; set; }
public required string Name { get; set; }
public Dictionary<string, string?>? Features { get; set; }
}Logged table creation: CREATE TABLE "Blogs" (
"Id" integer GENERATED BY DEFAULT AS IDENTITY,
"Name" text NOT NULL,
"Features" hstore DEFAULT HSTORE '"k1"=>NULL,"k\"2\""=>"v\"2\"","k''3''"=>"v''3''","k\\4"=>"v\\4"',
CONSTRAINT "PK_Blogs" PRIMARY KEY ("Id")
);Output: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fix hstore SQL literal generation bugs in NpgsqlHstoreTypeMapping.
Details
The previous implementation produced invalid or corrupted literals in several cases:
This PR updates hstore literal generation to:
\,"and'appropriately for use inside the generated SQL literalUnit tests were added for each of these fixed cases.