diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/Lib.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/Lib.cs index 47d5cf291f5..d7c56c22b53 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/Lib.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/Lib.cs @@ -441,10 +441,17 @@ public MyStruct(int x) [SpacetimeDB.Index.BTree(Accessor = "TestIndexWithoutColumns")] [SpacetimeDB.Index.BTree(Accessor = "TestIndexWithEmptyColumns", Columns = [])] [SpacetimeDB.Index.BTree(Accessor = "TestUnknownColumns", Columns = ["UnknownColumn"])] +[SpacetimeDB.Index.BTree(Columns = ["SelfIndexingColumn"])] +[SpacetimeDB.Index.BTree( + Name = "TestCanonicalNameWithoutAccessor", + Columns = ["SecondaryIndexingColumn"] +)] public partial struct TestIndexIssues { [SpacetimeDB.Index.BTree(Accessor = "TestUnexpectedColumns", Columns = ["UnexpectedColumn"])] public int SelfIndexingColumn; + + public int SecondaryIndexingColumn; } [SpacetimeDB.Table( diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#FFI.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#FFI.verified.cs index e69962b169c..881b9ad8989 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#FFI.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#FFI.verified.cs @@ -251,6 +251,10 @@ public readonly partial struct QueryBuilder public readonly struct TestIndexIssuesCols { public readonly global::SpacetimeDB.Col SelfIndexingColumn; + public readonly global::SpacetimeDB.Col< + global::TestIndexIssues, + int + > SecondaryIndexingColumn; internal TestIndexIssuesCols(string tableName) { @@ -258,12 +262,20 @@ internal TestIndexIssuesCols(string tableName) tableName, "SelfIndexingColumn" ); + SecondaryIndexingColumn = new global::SpacetimeDB.Col( + tableName, + "SecondaryIndexingColumn" + ); } } public readonly struct TestIndexIssuesIxCols { public readonly global::SpacetimeDB.IxCol SelfIndexingColumn; + public readonly global::SpacetimeDB.IxCol< + global::TestIndexIssues, + int + > SecondaryIndexingColumn; internal TestIndexIssuesIxCols(string tableName) { @@ -271,6 +283,10 @@ internal TestIndexIssuesIxCols(string tableName) tableName, "SelfIndexingColumn" ); + SecondaryIndexingColumn = new global::SpacetimeDB.IxCol( + tableName, + "SecondaryIndexingColumn" + ); } } @@ -1196,6 +1212,16 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar AccessorName: "TestUnknownColumns", Algorithm: new SpacetimeDB.Internal.RawIndexAlgorithm.BTree([]) ), + new( + SourceName: "TestIndexIssues_SelfIndexingColumn_idx_btree", + AccessorName: "SelfIndexingColumn", + Algorithm: new SpacetimeDB.Internal.RawIndexAlgorithm.BTree([0]) + ), + new( + SourceName: "TestIndexIssues_SecondaryIndexingColumn_idx_btree", + AccessorName: "SecondaryIndexingColumn", + Algorithm: new SpacetimeDB.Internal.RawIndexAlgorithm.BTree([1]) + ), new( SourceName: "TestIndexIssues_SelfIndexingColumn_idx_btree", AccessorName: "TestUnexpectedColumns", @@ -1257,6 +1283,82 @@ public sealed class TestUnknownColumnsIndex() public TestUnknownColumnsIndex TestUnknownColumns => new(); + public sealed class SelfIndexingColumnIndex() + : SpacetimeDB.Internal.IndexBase( + "TestIndexIssues_SelfIndexingColumn_idx_btree" + ) + { + public IEnumerable Filter(int SelfIndexingColumn) => + DoFilter( + new SpacetimeDB.Internal.BTreeIndexBounds( + SelfIndexingColumn + ) + ); + + public ulong Delete(int SelfIndexingColumn) => + DoDelete( + new SpacetimeDB.Internal.BTreeIndexBounds( + SelfIndexingColumn + ) + ); + + public IEnumerable Filter( + global::SpacetimeDB.Bound SelfIndexingColumn + ) => + DoFilter( + new SpacetimeDB.Internal.BTreeIndexBounds( + SelfIndexingColumn + ) + ); + + public ulong Delete(global::SpacetimeDB.Bound SelfIndexingColumn) => + DoDelete( + new SpacetimeDB.Internal.BTreeIndexBounds( + SelfIndexingColumn + ) + ); + } + + public SelfIndexingColumnIndex SelfIndexingColumn => new(); + + public sealed class SecondaryIndexingColumnIndex() + : SpacetimeDB.Internal.IndexBase( + "TestIndexIssues_SecondaryIndexingColumn_idx_btree" + ) + { + public IEnumerable Filter(int SecondaryIndexingColumn) => + DoFilter( + new SpacetimeDB.Internal.BTreeIndexBounds( + SecondaryIndexingColumn + ) + ); + + public ulong Delete(int SecondaryIndexingColumn) => + DoDelete( + new SpacetimeDB.Internal.BTreeIndexBounds( + SecondaryIndexingColumn + ) + ); + + public IEnumerable Filter( + global::SpacetimeDB.Bound SecondaryIndexingColumn + ) => + DoFilter( + new SpacetimeDB.Internal.BTreeIndexBounds( + SecondaryIndexingColumn + ) + ); + + public ulong Delete(global::SpacetimeDB.Bound SecondaryIndexingColumn) => + DoDelete( + new SpacetimeDB.Internal.BTreeIndexBounds( + SecondaryIndexingColumn + ) + ); + } + + public SecondaryIndexingColumnIndex SecondaryIndexingColumn => new(); + public sealed class TestUnexpectedColumnsIndex() : SpacetimeDB.Internal.IndexBase( "TestIndexIssues_SelfIndexingColumn_idx_btree" @@ -2442,6 +2544,56 @@ internal TestUnknownColumnsIndex() public TestUnknownColumnsIndex TestUnknownColumns => new(); + public sealed class SelfIndexingColumnIndex + : global::SpacetimeDB.Internal.ReadOnlyIndexBase + { + internal SelfIndexingColumnIndex() + : base("TestIndexIssues_SelfIndexingColumn_idx_btree") { } + + public IEnumerable Filter(int SelfIndexingColumn) => + DoFilter( + new global::SpacetimeDB.Internal.BTreeIndexBounds( + SelfIndexingColumn + ) + ); + + public IEnumerable Filter( + global::SpacetimeDB.Bound SelfIndexingColumn + ) => + DoFilter( + new global::SpacetimeDB.Internal.BTreeIndexBounds( + SelfIndexingColumn + ) + ); + } + + public SelfIndexingColumnIndex SelfIndexingColumn => new(); + + public sealed class SecondaryIndexingColumnIndex + : global::SpacetimeDB.Internal.ReadOnlyIndexBase + { + internal SecondaryIndexingColumnIndex() + : base("TestIndexIssues_SecondaryIndexingColumn_idx_btree") { } + + public IEnumerable Filter(int SecondaryIndexingColumn) => + DoFilter( + new global::SpacetimeDB.Internal.BTreeIndexBounds( + SecondaryIndexingColumn + ) + ); + + public IEnumerable Filter( + global::SpacetimeDB.Bound SecondaryIndexingColumn + ) => + DoFilter( + new global::SpacetimeDB.Internal.BTreeIndexBounds( + SecondaryIndexingColumn + ) + ); + } + + public SecondaryIndexingColumnIndex SecondaryIndexingColumn => new(); + public sealed class TestUnexpectedColumnsIndex : global::SpacetimeDB.Internal.ReadOnlyIndexBase { @@ -2827,6 +2979,11 @@ public static void Main() (identity, connectionId, random, time) => new SpacetimeDB.ProcedureContext(identity, connectionId, random, time) ); + SpacetimeDB.Internal.Module.RegisterExplicitIndexName( + "TestIndexIssues_SecondaryIndexingColumn_idx_btree", + "TestCanonicalNameWithoutAccessor" + ); + var __memoryStream = new MemoryStream(); var __writer = new BinaryWriter(__memoryStream); diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestIndexIssues.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestIndexIssues.verified.cs index d39750331c2..862805ded3e 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestIndexIssues.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestIndexIssues.verified.cs @@ -9,11 +9,13 @@ partial struct TestIndexIssues public void ReadFields(System.IO.BinaryReader reader) { SelfIndexingColumn = BSATN.SelfIndexingColumnRW.Read(reader); + SecondaryIndexingColumn = BSATN.SecondaryIndexingColumnRW.Read(reader); } public void WriteFields(System.IO.BinaryWriter writer) { BSATN.SelfIndexingColumnRW.Write(writer, SelfIndexingColumn); + BSATN.SecondaryIndexingColumnRW.Write(writer, SecondaryIndexingColumn); } object SpacetimeDB.BSATN.IStructuralReadWrite.GetSerializer() @@ -22,11 +24,12 @@ object SpacetimeDB.BSATN.IStructuralReadWrite.GetSerializer() } public override string ToString() => - $"TestIndexIssues {{ SelfIndexingColumn = {SpacetimeDB.BSATN.StringUtil.GenericToString(SelfIndexingColumn)} }}"; + $"TestIndexIssues {{ SelfIndexingColumn = {SpacetimeDB.BSATN.StringUtil.GenericToString(SelfIndexingColumn)}, SecondaryIndexingColumn = {SpacetimeDB.BSATN.StringUtil.GenericToString(SecondaryIndexingColumn)} }}"; public readonly partial struct BSATN : SpacetimeDB.BSATN.IReadWrite { internal static readonly SpacetimeDB.BSATN.I32 SelfIndexingColumnRW = new(); + internal static readonly SpacetimeDB.BSATN.I32 SecondaryIndexingColumnRW = new(); public TestIndexIssues Read(System.IO.BinaryReader reader) { @@ -47,7 +50,11 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar _ => new SpacetimeDB.BSATN.AlgebraicType.Product( new SpacetimeDB.BSATN.AggregateElement[] { - new("SelfIndexingColumn", SelfIndexingColumnRW.GetAlgebraicType(registrar)) + new("SelfIndexingColumn", SelfIndexingColumnRW.GetAlgebraicType(registrar)), + new( + "SecondaryIndexingColumn", + SecondaryIndexingColumnRW.GetAlgebraicType(registrar) + ) } ) ); @@ -60,14 +67,18 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar public override int GetHashCode() { var ___hashSelfIndexingColumn = SelfIndexingColumn.GetHashCode(); - return ___hashSelfIndexingColumn; + var ___hashSecondaryIndexingColumn = SecondaryIndexingColumn.GetHashCode(); + return ___hashSelfIndexingColumn ^ ___hashSecondaryIndexingColumn; } #nullable enable public bool Equals(TestIndexIssues that) { var ___eqSelfIndexingColumn = this.SelfIndexingColumn.Equals(that.SelfIndexingColumn); - return ___eqSelfIndexingColumn; + var ___eqSecondaryIndexingColumn = this.SecondaryIndexingColumn.Equals( + that.SecondaryIndexingColumn + ); + return ___eqSelfIndexingColumn && ___eqSecondaryIndexingColumn; } public override bool Equals(object? that) diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module.verified.txt b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module.verified.txt index 492d1cf9db5..ad21b0bc356 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module.verified.txt +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module.verified.txt @@ -140,7 +140,7 @@ public partial record TestTableTaggedEnum : SpacetimeDB.TaggedEnum<(int X, int Y [SpacetimeDB.Index.BTree(Accessor = "TestIndexWithEmptyColumns", Columns = [])] [SpacetimeDB.Index.BTree(Accessor = "TestUnknownColumns", Columns = ["UnknownColumn"])] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -public partial struct TestIndexIssues +[SpacetimeDB.Index.BTree(Columns = ["SelfIndexingColumn"])] */ Message: Could not find the specified column UnknownColumn in TestIndexIssues., Severity: Error, @@ -154,6 +154,46 @@ public partial struct TestIndexIssues } }, {/* +[SpacetimeDB.Index.BTree(Accessor = "TestUnknownColumns", Columns = ["UnknownColumn"])] +[SpacetimeDB.Index.BTree(Columns = ["SelfIndexingColumn"])] + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +[SpacetimeDB.Index.BTree( +*/ + Message: Index attribute on a table declaration must specify Accessor. Field-level index attributes may omit Accessor and default to the field name., + Severity: Error, + Descriptor: { + Id: STDB0029, + Title: Table-level index attributes must specify Accessor, + MessageFormat: Index attribute on a table declaration must specify Accessor. Field-level index attributes may omit Accessor and default to the field name., + Category: SpacetimeDB, + DefaultSeverity: Error, + IsEnabledByDefault: true + } + }, + {/* +[SpacetimeDB.Index.BTree(Columns = ["SelfIndexingColumn"])] +[SpacetimeDB.Index.BTree( + ^^^^^^^^^^^^^^^^^^^^^^^^ + Name = "TestCanonicalNameWithoutAccessor", +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Columns = ["SecondaryIndexingColumn"] +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +)] +^ +public partial struct TestIndexIssues +*/ + Message: Index attribute on a table declaration must specify Accessor. Field-level index attributes may omit Accessor and default to the field name., + Severity: Error, + Descriptor: { + Id: STDB0029, + Title: Table-level index attributes must specify Accessor, + MessageFormat: Index attribute on a table declaration must specify Accessor. Field-level index attributes may omit Accessor and default to the field name., + Category: SpacetimeDB, + DefaultSeverity: Error, + IsEnabledByDefault: true + } + }, + {/* [SpacetimeDB.Table( ^^^^^^^^^^^^^^^^^^ diff --git a/crates/bindings-csharp/Codegen/Diag.cs b/crates/bindings-csharp/Codegen/Diag.cs index c4916e378ca..6c55cf0ee15 100644 --- a/crates/bindings-csharp/Codegen/Diag.cs +++ b/crates/bindings-csharp/Codegen/Diag.cs @@ -257,4 +257,13 @@ string typeName $"[SpacetimeDB.Settings] is declared multiple times: {string.Join(", ", fullNames)}", _ => Location.None ); + + public static readonly ErrorDescriptor TableLevelIndexMissingAccessor = + new( + group, + "Table-level index attributes must specify Accessor", + _ => + $"Index attribute on a table declaration must specify Accessor. Field-level index attributes may omit Accessor and default to the field name.", + attr => attr + ); } diff --git a/crates/bindings-csharp/Codegen/Module.cs b/crates/bindings-csharp/Codegen/Module.cs index db31d77e865..8c988c2d902 100644 --- a/crates/bindings-csharp/Codegen/Module.cs +++ b/crates/bindings-csharp/Codegen/Module.cs @@ -407,6 +407,11 @@ DiagReporter diag .ToImmutableArray() ) { + if (string.IsNullOrWhiteSpace(attr.Accessor)) + { + diag.Report(ErrorDescriptor.TableLevelIndexMissingAccessor, data); + } + if (attr.Columns.Length == 0) { diag.Report(ErrorDescriptor.EmptyIndexColumns, data);