edgedb / edgedb-net

The official .NET client library for EdgeDB
https://edgedb.com
Apache License 2.0
83 stars 9 forks source link

Type confusion when retrieving data typed as option #67

Closed Darkle closed 1 year ago

Darkle commented 1 year ago

Describe the bug There seems to be a type confusion bug when retrieving data typed as an option.

Reproduction With the following schema:

module default {
  type Settings {
    required uniqueId: str {
      default := "settings"; 
      constraint exclusive;
    };
    required baz: int32 {
      default := 2;
      constraint min_value(1);
    };
    required bar: bool {
      default := true;
    };
  };
  type Foo {
    required uniqueId: str {
      default := "foo"; 
      constraint exclusive;
    };
    required thing: bool {
      default := true;
    };
  }
}

And the following code:

type Settings =
    { uniqueId: string
      baz: int
      bar: bool }

type Foo = { uniqueId: string; thing: bool }

do! dbClient.ExecuteAsync("""insert Settings unless conflict on .uniqueId;""")
do! dbClient.ExecuteAsync("""insert Foo unless conflict on .uniqueId;""")

let! settings = dbClient.QuerySingleAsync<Option<Settings>>("""select Settings limit 1""")

let! foo = dbClient.QuerySingleAsync<Option<Foo>>("""select Foo limit 1""")

I get an error message of:

Error: EdgeDB.EdgeDBException: Failed to deserialize object to Microsoft.FSharp.Core.FSharpOption`1[Program+Foo]
 ---> System.ArgumentException: Object of type 'Program+Foo' cannot be converted to type 'Program+Settings'.
   at System.RuntimeType.CheckValue(Object& value, ParameterCopyBackAction& copyBack, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
   at System.Reflection.MethodBase.CheckArguments(Span`1 copyOfParameters, IntPtr* byrefParameters, Span`1 shouldCopyBack, ReadOnlySpan`1 parameters, RuntimeType[] sigTypes, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at EdgeDB.Binary.Builders.Wrappers.FSharpOptionWrapper.WrapReferenceOption(Type target, Object value)
   at EdgeDB.Binary.Builders.Wrappers.FSharpOptionWrapper.Wrap(Type target, Object value)
   at EdgeDB.EdgeDBTypeDeserializeInfo.<>c__DisplayClass28_0.<.ctor>b__0(ObjectEnumerator& enumerator)
   at EdgeDB.Binary.Codecs.TypeInitializedObjectCodec.Deserialize(PacketReader& reader, CodecContext context)
   --- End of inner exception stack trace ---
   at EdgeDB.Binary.Codecs.TypeInitializedObjectCodec.Deserialize(PacketReader& reader, CodecContext context)
   at EdgeDB.TypeBuilder.BuildObject(EdgeDBBinaryClient client, Type type, ObjectCodec codec, Data& data)
   at EdgeDB.ObjectBuilder.BuildResult[TType](EdgeDBBinaryClient client, ICodec codec, Data& data)
   at EdgeDB.EdgeDBBinaryClient.QuerySingleAsync[TResult](String query, IDictionary`2 args, Nullable`1 capabilities, CancellationToken token)
   at EdgeDB.EdgeDBClient.QuerySingleAsync[TResult](String query, IDictionary`2 args, Nullable`1 capabilities, CancellationToken token)
   at EdgeDB.EdgeDBClient.QuerySingleAsync[TResult](String query, IDictionary`2 args, Nullable`1 capabilities, CancellationToken token)
   at Program.Pipe #1 input at line 17@17.MoveNext() in /home/coop/Coding/scratch/tempdelete/Program.fs:line 24

Basic repro: https://github.com/Darkle/edgedb-issue-5

Versions (please complete the following information):