jonwagner / Insight.Database

Fast, lightweight .NET micro-ORM
Other
861 stars 145 forks source link

PostgreSQL CommandType.StoredProcedure 42809: procname() is not a procedure exception #490

Closed SCVNG3R closed 1 year ago

SCVNG3R commented 1 year ago

As it's mentioned on Npgsql documentation website, starting with Npgsql 7.0, CommandType.StoredProcedure now invokes stored procedures, and not function as before. Attempting to call a database function (such as GetBeerByType()) will result in the following exception: Npgsql.PostgresException: '42809: procname() is not a procedure

This renders Insight.Database unusable with PostgreSQL More info can be found here: Npgsql Basic Usage

Steps to reproduce

Attempt to run the HelloWorld code under Npgsql

Expected behavior

Return value from calling a database function

jonwagner commented 1 year ago

I see that this is a transition because PG < v11 only had functions and now it supports stored procedures. NpgSQL previously mapped CommandType.StoredProcedure to functions and now is correcting the behaviour.

Their release notes mark this as a breaking change.

I believe the correct stance to take is:

As for Insight.Database, I will update the test cases to use stored procedures and ensure it works with PG11 and NPGSQL7.

jonwagner commented 1 year ago

sigh...this is going to be a lot harder than i expected.

jonwagner commented 1 year ago

I'll try to find time to do a full pass through the PG provider but it's non-trivial.

stale[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Grauenwolf commented 8 months ago

sigh...this is going to be a lot harder than i expected.

  • postgres and npgsql use entirely different methods for returning recordsets and output parameters between functions and procedures
  • there is no CommandType.Function that allows us to distinguish between functions and procedures and get the desired functionality.

We could add our own. Make a NpgsqlCommandType enum and add the missing value as NpgsqlCommandType.Function=100.

For the property...

public NpgsqlCommandType NpgsqlCommandType {
    { get => (CommandType)NpgsqlCommandType; }
    { set => NpgsqlCommandType = (CommandType)value; }
}

This works because enums don't have range checks.

jonwagner commented 7 months ago

Good news?

For v8.0, I updated the Postgres provider. Now if you use CommandType.StoredProcedure, we do a mixup on the command:

And surprisingly, this works!

@Grauenwolf give it a shot after the next build.

(Note that there is no longer support for calling stored procedures, but this feels like it's better compatibility.)