DapperLib / DapperLib/Dapper

Broken type mapping on nullable structs (discovered for npgsql)

Open
#1,755 4 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C#
Stars
18.4k
Forks
3.7k
Avg merge
5h 8m
Merged PRs (30d)
1

Description

Consider this application:

    class Program
    {
        static async Task Main(string[] args)
        {
            const string connectionString = "User ID=postgres;Password=postgres;Host=localhost;Port=5432;Database=ac;";
            await using var connection = new NpgsqlConnection(connectionString);

            DateTime? param = null;
            await connection.QueryAsync(
                "SELECT 1 WHERE @param IS NOT NULL",
                new
                {
                    param
                });

            Console.WriteLine("Success");
        }
    }

in version 2.0.90 of Dapper there were no issues with such query, in version 2.0.123 postgres returns error 42P18 which stands for ambiguous_parameter

Unhandled exception. Npgsql.PostgresException (0x80004005): 42P18: could not determine data type of parameter $1
   at Npgsql.NpgsqlConnector.<ReadMessage>g__ReadMessageLong|194_0(NpgsqlConnector connector, Boolean async, DataRowLoadingMode dataRowLoadingMode, Boolean readingNotifications, Boolean isReadingPrependedMessage)
   at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
   at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
   at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
   at Npgsql.NpgsqlCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
   at Dapper.SqlMapper.QueryAsync[T](IDbConnection cnn, Type effectiveType, CommandDefinition command) in /_/Dapper/SqlMapper.Async.cs:line 418
   at NpgsqlDateTimeBug.Program.Main(String[] args) in C:\Users\lszafirski\source\repos\NpgsqlDateTimeBug\NpgsqlDateTimeBug\Program.cs:line 17
   at NpgsqlDateTimeBug.Program.Main(String[] args) in C:\Users\lszafirski\source\repos\NpgsqlDateTimeBug\NpgsqlDateTimeBug\Program.cs:line 24
   at NpgsqlDateTimeBug.Program.<Main>(String[] args)
  Exception data:
    Severity: ERROR
    SqlState: 42P18
    MessageText: could not determine data type of parameter $1
    File: postgres.c
    Line: 1499
    Routine: exec_parse_message

I think the type of parameter in prepared statement is unknown
If I change parameter type to default non-nullable DateTime or string error does not appear.

Target framework: net5.0
Npgsql: 5.0.11
Postgres: PostgreSQL 13.3 (Debian 13.3-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the nullable DateTime parameter example against Npgsql 5.0.11 and PostgreSQL 13.3, then inspect the parameter handling reached from SqlMapper.Async.cs around line 418. Done means the query no longer produces PostgreSQL error 42P18 for the nullable parameter while preserving the behavior for non-nullable values.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, postgresql
Domain
databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.