Skip to content

NetTopologySuite Regression - Cannot resolve geometry type due to SchemaQualifiedName #4585

@rbaumgarden

Description

@rbaumgarden

Description

The merge in #4382 changes the string used to resolve types from the Name to the SchemaQualifiedName, which can break type resolution.

Steps to reproduce

This code was taken from the documentation. In the particular database I am using, 'geometry' is a type in the 'postgis' schema.

using NetTopologySuite.Geometries;
using NetTopologySuite.Geometries.Implementation;
using Npgsql;

NpgsqlConnection.GlobalTypeMapper.UseNetTopologySuite(new DotSpatialAffineCoordinateSequenceFactory(Ordinates.XY), handleOrdinates: Ordinates.XY);

using (NpgsqlConnection con = new NpgsqlConnection(connectionString))
{
    con.Open();

    using (NpgsqlCommand cmd = con.CreateCommand())
    {
        Point p = new Point(new Coordinate(1d, 1d));
        cmd.CommandText = "CREATE TEMP TABLE tmp_geom (geom GEOMETRY)";
        cmd.ExecuteNonQuery();

        cmd.CommandText = "INSERT INTO tmp_geom (geom) VALUES (@p)";
        cmd.Parameters.AddWithValue("@p", NpgsqlTypes.NpgsqlDbType.Geometry, p);
        cmd.ExecuteNonQuery();
    }

    using (NpgsqlCommand cmd = con.CreateCommand())
    {
        cmd.CommandText = "select geom from tmp_geom";

        using (var rdr = cmd.ExecuteReader())
        {
            if (rdr.HasRows)
            {
                rdr.Read();
                var geom = rdr[0];
                Console.WriteLine(geom);
            }
        }
    }
}

The issue

The NetTopologySuite extension is matching on an unqualified name, which results in a failure to resolve the types if the schema of the postgis types is not 'public' or 'pg_catalog' as excluded by the SchemaQualifiedName property.

Issue #4481 proposes a solution to standardize type references in a struct; it could be up to the extension to decide if names should be qualified or not. Currently there is no work around short of moving the types to another schema or building the NetTopologySuite extension to account for the changed type name it receives.

Stack Trace

Exception message:
System.NotSupportedException
  HResult=0x80131515
  Message=The field 'geom' has type 'postgis.geometry', which is currently unknown to Npgsql. You can retrieve it as a string by marking it as unknown, please see the FAQ.
  Source=Npgsql
Stack trace:
   at Npgsql.Internal.TypeHandlers.UnknownTypeHandler.Read(NpgsqlReadBuffer buf, Int32 byteLen, Boolean async, FieldDescription fieldDescription)
   at Npgsql.Internal.TypeHandling.NpgsqlTypeHandler.<Read>d__4`1.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Runtime.CompilerServices.ValueTaskAwaiter`1.GetResult()
   at Npgsql.Internal.TypeHandling.NpgsqlTypeHandler`1.<ReadAsObject>d__2.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Npgsql.NpgsqlDataReader.GetValue(Int32 ordinal)
   at Program.<Main>$(String[] args) in D:\linq2db\newest_everything\newest_everything\Program.cs:line 36

  This exception was originally thrown at this call stack:
    Npgsql.Internal.TypeHandlers.UnknownTypeHandler.Read(Npgsql.Internal.NpgsqlReadBuffer, int, bool, Npgsql.BackendMessages.FieldDescription)
    Npgsql.Internal.TypeHandling.NpgsqlTypeHandler.Read<TAny>(Npgsql.Internal.NpgsqlReadBuffer, int, bool, Npgsql.BackendMessages.FieldDescription)
    System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
    System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(System.Threading.Tasks.Task)
    System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task)
    System.Threading.Tasks.ValueTask<TResult>.Result.get()
    System.Runtime.CompilerServices.ValueTaskAwaiter<TResult>.GetResult()
    Npgsql.Internal.TypeHandling.NpgsqlTypeHandler<TDefault>.ReadAsObject(Npgsql.Internal.NpgsqlReadBuffer, int, bool, Npgsql.BackendMessages.FieldDescription)
    System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
    System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(System.Threading.Tasks.Task)
    ...
    [Call Stack Truncated]

Further technical details

Npgsql version: 6.0.5

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions