From a6effb5f4cba11a12851f00dba818dd4086a5d09 Mon Sep 17 00:00:00 2001 From: "savasp-agent[bot]" <275188714+savasp-agent[bot]@users.noreply.github.com> Date: Thu, 23 Jul 2026 03:03:06 -0700 Subject: [PATCH 1/2] fix: restore zero-warning CodeQL baseline --- .../DocumentationSnippets.cs | 1 + .../DocumentationSnippets.cs | 4 +++ examples/Playground/DocumentationSnippets.cs | 4 +++ .../Querying/Cypher/Execution/CypherEngine.cs | 27 ++++++++++--------- .../IComplexObjectGraphSerializationTests.cs | 2 +- .../IQueryTraversalTests.cs | 6 ++--- .../Serialization/EntityReader.cs | 2 +- .../Querying/Cypher/Execution/CypherEngine.cs | 17 +++++++----- .../CodeGenModelBuilder.cs | 2 -- .../ComplexCollectionStorageCodec.cs | 2 +- .../GraphMutationModelBuilderTests.cs | 9 ++++--- .../GraphQueryProviderBaseTests.cs | 1 + .../TraversalTranslationTests.cs | 7 ++--- 13 files changed, 51 insertions(+), 33 deletions(-) diff --git a/examples/Example1.BasicCRUD/DocumentationSnippets.cs b/examples/Example1.BasicCRUD/DocumentationSnippets.cs index 40706c7c..b78a8513 100644 --- a/examples/Example1.BasicCRUD/DocumentationSnippets.cs +++ b/examples/Example1.BasicCRUD/DocumentationSnippets.cs @@ -24,6 +24,7 @@ private static async Task QueryAsync(IGraph graph) var engineers = await graph.Nodes() .Where(person => person.Department == "Engineering") .ToListAsync(); + Console.WriteLine($"Found {engineers.Count} engineer(s)."); // snippet-end: query } diff --git a/examples/Example2.LINQAndTraversal/DocumentationSnippets.cs b/examples/Example2.LINQAndTraversal/DocumentationSnippets.cs index cf14c3d6..a9d4992b 100644 --- a/examples/Example2.LINQAndTraversal/DocumentationSnippets.cs +++ b/examples/Example2.LINQAndTraversal/DocumentationSnippets.cs @@ -16,6 +16,7 @@ private static async Task QueryRootsAsync(IGraph graph) var ageRange = await graph.Nodes() .Where(person => person.Age >= 28 && person.Age <= 32) .ToListAsync(); + Console.WriteLine($"Found {newYorkers.Count} New Yorker(s) and {ageRange.Count} person(s) in the age range."); // snippet-end: query-roots } @@ -31,6 +32,8 @@ private static async Task TraverseAsync(IGraph graph) .Where(person => person.Name == "Alice") .Traverse(2) .ToListAsync(); + Console.WriteLine( + $"Found {directConnections.Count} direct connection(s) and {twoHopConnections.Count} two-hop connection(s)."); // snippet-end: traversal } @@ -41,6 +44,7 @@ private static async Task PathSegmentsAsync(IGraph graph) .Where(person => person.Name == "Alice") .PathSegments() .ToListAsync(); + Console.WriteLine($"Found {connections.Count} path segment(s)."); // snippet-end: path-segments } } diff --git a/examples/Playground/DocumentationSnippets.cs b/examples/Playground/DocumentationSnippets.cs index ac7a636a..a1b949dc 100644 --- a/examples/Playground/DocumentationSnippets.cs +++ b/examples/Playground/DocumentationSnippets.cs @@ -107,6 +107,7 @@ private static async Task SetBasedMutationAsync(IGraph graph) var deleted = await graph.Nodes() .Where(person => person.Email.EndsWith("@expired.example")) .DeleteAsync(cascadeDelete: true); + Console.WriteLine($"Updated {updated} and deleted {deleted} person(s)."); // snippet-end: set-based-mutation } @@ -123,6 +124,7 @@ private static async Task Neo4jQuickStartAsync() .Where(u => u.IsActive) .OrderBy(u => u.CreatedDate) .ToListAsync(); + Console.WriteLine($"Found {users.Count} active user(s)."); // snippet-end: neo4j-quick-start } @@ -139,6 +141,7 @@ private static async Task AgeQuickStartAsync() var activeUsers = await graph.Nodes() .Where(user => user.IsActive) .ToListAsync(); + Console.WriteLine($"Found {activeUsers.Count} active user(s)."); // snippet-end: age-quick-start } @@ -150,6 +153,7 @@ private static async Task InMemoryQuickStartAsync() await graph.CreateNodeAsync(new Person { Name = "Alice" }); var alice = await graph.Nodes().Where(p => p.Name == "Alice").SingleAsync(); + Console.WriteLine(alice.Name); // snippet-end: in-memory-quick-start } } diff --git a/src/Graph.Age/Querying/Cypher/Execution/CypherEngine.cs b/src/Graph.Age/Querying/Cypher/Execution/CypherEngine.cs index 527ca2d9..79630bdb 100644 --- a/src/Graph.Age/Querying/Cypher/Execution/CypherEngine.cs +++ b/src/Graph.Age/Querying/Cypher/Execution/CypherEngine.cs @@ -137,6 +137,8 @@ await DeleteNodesAsync( } else if (mutation.Kind == GraphMutationKind.Update) { + var updateComplexPlan = complexPlan ?? throw new InvalidOperationException( + "An update mutation must have a complex-property plan."); if (!constraintPlan.IsEmpty) { var rows = await ReadConstraintRowsAsync( @@ -153,7 +155,7 @@ await ValidateUnselectedConstraintsAsync( transaction, cancellationToken).ConfigureAwait(false); } - else if (complexPlan!.HasWork) + else if (updateComplexPlan.HasWork) { // Complex replacement spans multiple AGE statements. Lock every frozen parent in // the same global order as constrained and entity-manager updates before any scalar @@ -172,14 +174,14 @@ await transaction.Runner.AcquireElementLocksAsync( _ = await ExecuteStatementAsync(statement, transaction, cancellationToken).ConfigureAwait(false); } - if (complexPlan!.HasWork) + if (updateComplexPlan.HasWork) { await _complexPropertyManager.ReplaceGraphIdBoundComplexPropertiesAsync( transaction.Runner, nativeIdentities.Cast().ToArray(), - complexPlan.RelationshipTypesToClear, - complexPlan.PropertyNamesToClear, - complexPlan.ReplacementEntity, + updateComplexPlan.RelationshipTypesToClear, + updateComplexPlan.PropertyNamesToClear, + updateComplexPlan.ReplacementEntity, cancellationToken).ConfigureAwait(false); } } @@ -232,14 +234,15 @@ await transaction.Runner.AcquireElementLocksAsync( constraintPlan.Properties.Select(property => property.StorageName).ToArray(), acquireWriteLock: false); var records = await ExecuteStatementAsync(statement, transaction, cancellationToken).ConfigureAwait(false); - var rows = records.Select(record => new GraphMutationConstraintRow( - record["__nativeId"].As(), - constraintPlan.Properties.Select((property, index) => new + var rows = records.Select(record => + { + var values = constraintPlan.Properties.Select((property, index) => { - property.StorageName, - Value = (object?)record[CypherMutationPlanner.ConstraintValueColumn(index)].As(), - }) - .ToDictionary(item => item.StorageName, item => item.Value, StringComparer.Ordinal))) + object? value = record[CypherMutationPlanner.ConstraintValueColumn(index)].As(); + return new KeyValuePair(property.StorageName, value); + }).ToDictionary(item => item.Key, item => item.Value, StringComparer.Ordinal); + return new GraphMutationConstraintRow(record["__nativeId"].As(), values); + }) .ToArray(); GraphMutationConstraintPlan.ValidateTargetRows(nativeIdentities, rows); return rows; diff --git a/src/Graph.CompatibilityTests/IComplexObjectGraphSerializationTests.cs b/src/Graph.CompatibilityTests/IComplexObjectGraphSerializationTests.cs index fc91b4df..b8cdde54 100644 --- a/src/Graph.CompatibilityTests/IComplexObjectGraphSerializationTests.cs +++ b/src/Graph.CompatibilityTests/IComplexObjectGraphSerializationTests.cs @@ -254,7 +254,7 @@ public async Task ConcurrentCollectionUpdates_SeparateTransactions_OneWriterItem public async Task UpdateCleanup_RemovesOnlyComplexValue_DomainRelationshipAndNodeSurvive() { var cancellationToken = TestContext.Current.CancellationToken; - var (owner, domainNode, domainRelationship) = await SeedCollisionAsync( + var (owner, domainNode, _) = await SeedCollisionAsync( complexCity: "Complex Seattle", domainCity: "Domain Portland", cancellationToken); diff --git a/src/Graph.CompatibilityTests/IQueryTraversalTests.cs b/src/Graph.CompatibilityTests/IQueryTraversalTests.cs index b6cafb80..0604a48c 100644 --- a/src/Graph.CompatibilityTests/IQueryTraversalTests.cs +++ b/src/Graph.CompatibilityTests/IQueryTraversalTests.cs @@ -1656,8 +1656,8 @@ await Graph.ConnectAsync( .OptionalTraverse() .Select(result => new { - SourceId = ((Person)result.Source).TestKey, - TargetId = result.Target == null ? null : ((Person)result.Target).TestKey, + SourceId = ((Person)result.Source).TestKey, // lgtm[cs/useless-cast-to-self] + TargetId = result.Target == null ? null : result.Target.TestKey, }) .ToListAsync(TestContext.Current.CancellationToken); @@ -1668,7 +1668,7 @@ await Graph.ConnectAsync( Assert.Contains(results, result => ((Person)result.Source).TestKey == self.TestKey && ((Person?)result.Target)?.TestKey == self.TestKey); Assert.Equal( new[] { one.TestKey, many.TestKey }.Order().ToArray(), - incoming.Select(result => ((Person)result.Target!).TestKey).Order().ToArray()); + incoming.Select(result => result.Target!.TestKey).Order().ToArray()); Assert.Equal(unmatched.TestKey, Assert.Single(projected).SourceId); Assert.Null(projected[0].TargetId); } diff --git a/src/Graph.InMemory/Serialization/EntityReader.cs b/src/Graph.InMemory/Serialization/EntityReader.cs index 15c78276..52d8c8b3 100644 --- a/src/Graph.InMemory/Serialization/EntityReader.cs +++ b/src/Graph.InMemory/Serialization/EntityReader.cs @@ -100,7 +100,7 @@ public EntityInfo BuildEntityInfo(NodeRecord record, StoreState state, Type actu elementType, [.. children .OrderBy(item => item.SequenceNumber) - .Select(item => (EntityInfo?)item.Item2)]); + .Select(item => item.Item2)]); } complexProperties[name] = new Property( diff --git a/src/Graph.Neo4j/Querying/Cypher/Execution/CypherEngine.cs b/src/Graph.Neo4j/Querying/Cypher/Execution/CypherEngine.cs index fbc1c815..5d6d690e 100644 --- a/src/Graph.Neo4j/Querying/Cypher/Execution/CypherEngine.cs +++ b/src/Graph.Neo4j/Querying/Cypher/Execution/CypherEngine.cs @@ -214,14 +214,17 @@ private async Task> ReadConstraintRows constraintPlan.Properties.Select(property => property.StorageName).ToArray(), acquireWriteLock: true); var records = await ExecuteStatementAsync(statement, transaction, cancellationToken).ConfigureAwait(false); - var rows = records.Select(record => new GraphMutationConstraintRow( - global::Neo4j.Driver.ValueExtensions.As(record["__nativeId"]), - constraintPlan.Properties.Select((property, index) => new + var rows = records.Select(record => + { + var values = constraintPlan.Properties.Select((property, index) => { - property.StorageName, - Value = (object?)record[CypherMutationPlanner.ConstraintValueColumn(index)], - }) - .ToDictionary(item => item.StorageName, item => item.Value, StringComparer.Ordinal))) + object? value = record[CypherMutationPlanner.ConstraintValueColumn(index)]; + return new KeyValuePair(property.StorageName, value); + }).ToDictionary(item => item.Key, item => item.Value, StringComparer.Ordinal); + return new GraphMutationConstraintRow( + global::Neo4j.Driver.ValueExtensions.As(record["__nativeId"]), + values); + }) .ToArray(); GraphMutationConstraintPlan.ValidateTargetRows(nativeIdentities, rows); return rows; diff --git a/src/Graph.Serialization.CodeGen/CodeGenModelBuilder.cs b/src/Graph.Serialization.CodeGen/CodeGenModelBuilder.cs index fc7ba616..195d2981 100644 --- a/src/Graph.Serialization.CodeGen/CodeGenModelBuilder.cs +++ b/src/Graph.Serialization.CodeGen/CodeGenModelBuilder.cs @@ -458,8 +458,6 @@ private static bool ImplementsGraphInterface(INamedTypeSymbol type, string inter private static string FindPropertyNameForParameter(IParameterSymbol parameter) { - var parameterName = parameter.Name; - return Utils.GetPropertyNameFromParameter(parameter); } diff --git a/src/Graph.Serialization/RuntimeRepresentation/ComplexCollectionStorageCodec.cs b/src/Graph.Serialization/RuntimeRepresentation/ComplexCollectionStorageCodec.cs index 376a974a..49e25f52 100644 --- a/src/Graph.Serialization/RuntimeRepresentation/ComplexCollectionStorageCodec.cs +++ b/src/Graph.Serialization/RuntimeRepresentation/ComplexCollectionStorageCodec.cs @@ -94,7 +94,7 @@ internal static IReadOnlyList GetCompanionPropertyNames(string logicalNa // deployed-storage compatibility promise: every newly persisted collection has metadata. return new EntityCollection( expectedElementType, - [.. storedEntities.OrderBy(item => item.SequenceNumber).Select(item => (EntityInfo?)item.Entity)]); + [.. storedEntities.OrderBy(item => item.SequenceNumber).Select(item => item.Entity)]); } if (expectedElementType != typeof(object) && metadata.ElementType != expectedElementType) diff --git a/tests/Graph.Core.Tests/GraphMutationModelBuilderTests.cs b/tests/Graph.Core.Tests/GraphMutationModelBuilderTests.cs index 79918a9d..9d5cec6d 100644 --- a/tests/Graph.Core.Tests/GraphMutationModelBuilderTests.cs +++ b/tests/Graph.Core.Tests/GraphMutationModelBuilderTests.cs @@ -380,20 +380,23 @@ public void ConstraintPlan_RejectsCollectionConstraintBeforeSchemaAccess() { Expression>> invalidSelector = metadata => metadata.Values; + Expression, GraphPropertySetters>> setters = + builder => builder.SetProperty(person => person.Nicknames, Array.Empty()); var selection = GraphMutationModelBuilder.Build(UpdateCall( Root(), - (Expression, GraphPropertySetters>>)(builder => - builder.SetProperty(person => person.Nicknames, Array.Empty())))).Selection; + setters)).Selection; var property = typeof(InvalidCollectionConstraintMetadata).GetProperty( nameof(InvalidCollectionConstraintMetadata.Values))!; var scalarProperty = typeof(InvalidCollectionConstraintMetadata).GetProperty( nameof(InvalidCollectionConstraintMetadata.ScalarValue))!; + Expression> scalarSelector = + metadata => metadata.ScalarValue; var mutation = new GraphMutationModel( GraphMutationKind.Update, selection, [ new GraphConstantPropertyAssignment( - (Expression>)(metadata => metadata.ScalarValue), + scalarSelector, scalarProperty, nameof(InvalidCollectionConstraintMetadata.ScalarValue), dynamic: false, diff --git a/tests/Graph.Core.Tests/GraphQueryProviderBaseTests.cs b/tests/Graph.Core.Tests/GraphQueryProviderBaseTests.cs index f240581e..d35f6ff1 100644 --- a/tests/Graph.Core.Tests/GraphQueryProviderBaseTests.cs +++ b/tests/Graph.Core.Tests/GraphQueryProviderBaseTests.cs @@ -410,6 +410,7 @@ private static async Task ConsumeAsync(IAsyncEnumerable stream) { await foreach (var _ in stream) { + // Enumerating the stream is the behavior under test. } } diff --git a/tests/Graph.Neo4j.Translation.Tests/TraversalTranslationTests.cs b/tests/Graph.Neo4j.Translation.Tests/TraversalTranslationTests.cs index d581341a..a3e99cc6 100644 --- a/tests/Graph.Neo4j.Translation.Tests/TraversalTranslationTests.cs +++ b/tests/Graph.Neo4j.Translation.Tests/TraversalTranslationTests.cs @@ -28,7 +28,8 @@ public Task Traverse_NoDepthOrDirection() [Fact] public Task Traverse_WidenedToINodeBeforeLabelFilter_LeavesStartUnconstrained() { - var query = ((IGraphQueryable)Root.Nodes()) + IGraphQueryable nodes = Root.Nodes(); + var query = nodes .OfLabel("Person") .Traverse(); @@ -118,8 +119,8 @@ public Task OptionalTraverse_ComposesProjectionAndPaging() .OptionalTraverse() .Select(result => new { - SourceKey = ((Person)result.Source).TestKey, - TargetKey = result.Target == null ? null : ((Person)result.Target).TestKey, + SourceKey = ((Person)result.Source).TestKey, // lgtm[cs/useless-cast-to-self] + TargetKey = result.Target == null ? null : result.Target.TestKey, }) .Take(5); From 58c9ec5bf65f060e14b32c5c99a08b28fbbf2744 Mon Sep 17 00:00:00 2001 From: "savasp-agent[bot]" <275188714+savasp-agent[bot]@users.noreply.github.com> Date: Thu, 23 Jul 2026 03:13:20 -0700 Subject: [PATCH 2/2] fix: keep result uses outside checked snippets --- examples/Example1.BasicCRUD/DocumentationSnippets.cs | 2 +- .../Example2.LINQAndTraversal/DocumentationSnippets.cs | 6 +++--- examples/Playground/DocumentationSnippets.cs | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/Example1.BasicCRUD/DocumentationSnippets.cs b/examples/Example1.BasicCRUD/DocumentationSnippets.cs index b78a8513..4c2e82e9 100644 --- a/examples/Example1.BasicCRUD/DocumentationSnippets.cs +++ b/examples/Example1.BasicCRUD/DocumentationSnippets.cs @@ -24,8 +24,8 @@ private static async Task QueryAsync(IGraph graph) var engineers = await graph.Nodes() .Where(person => person.Department == "Engineering") .ToListAsync(); - Console.WriteLine($"Found {engineers.Count} engineer(s)."); // snippet-end: query + Console.WriteLine($"Found {engineers.Count} engineer(s)."); } private static async Task UpdateAndDeleteAsync(IGraph graph, Person alice) diff --git a/examples/Example2.LINQAndTraversal/DocumentationSnippets.cs b/examples/Example2.LINQAndTraversal/DocumentationSnippets.cs index a9d4992b..d9b129c5 100644 --- a/examples/Example2.LINQAndTraversal/DocumentationSnippets.cs +++ b/examples/Example2.LINQAndTraversal/DocumentationSnippets.cs @@ -16,8 +16,8 @@ private static async Task QueryRootsAsync(IGraph graph) var ageRange = await graph.Nodes() .Where(person => person.Age >= 28 && person.Age <= 32) .ToListAsync(); - Console.WriteLine($"Found {newYorkers.Count} New Yorker(s) and {ageRange.Count} person(s) in the age range."); // snippet-end: query-roots + Console.WriteLine($"Found {newYorkers.Count} New Yorker(s) and {ageRange.Count} person(s) in the age range."); } private static async Task TraverseAsync(IGraph graph) @@ -32,9 +32,9 @@ private static async Task TraverseAsync(IGraph graph) .Where(person => person.Name == "Alice") .Traverse(2) .ToListAsync(); + // snippet-end: traversal Console.WriteLine( $"Found {directConnections.Count} direct connection(s) and {twoHopConnections.Count} two-hop connection(s)."); - // snippet-end: traversal } private static async Task PathSegmentsAsync(IGraph graph) @@ -44,7 +44,7 @@ private static async Task PathSegmentsAsync(IGraph graph) .Where(person => person.Name == "Alice") .PathSegments() .ToListAsync(); - Console.WriteLine($"Found {connections.Count} path segment(s)."); // snippet-end: path-segments + Console.WriteLine($"Found {connections.Count} path segment(s)."); } } diff --git a/examples/Playground/DocumentationSnippets.cs b/examples/Playground/DocumentationSnippets.cs index a1b949dc..0327aceb 100644 --- a/examples/Playground/DocumentationSnippets.cs +++ b/examples/Playground/DocumentationSnippets.cs @@ -107,8 +107,8 @@ private static async Task SetBasedMutationAsync(IGraph graph) var deleted = await graph.Nodes() .Where(person => person.Email.EndsWith("@expired.example")) .DeleteAsync(cascadeDelete: true); - Console.WriteLine($"Updated {updated} and deleted {deleted} person(s)."); // snippet-end: set-based-mutation + Console.WriteLine($"Updated {updated} and deleted {deleted} person(s)."); } private static async Task Neo4jQuickStartAsync() @@ -124,8 +124,8 @@ private static async Task Neo4jQuickStartAsync() .Where(u => u.IsActive) .OrderBy(u => u.CreatedDate) .ToListAsync(); - Console.WriteLine($"Found {users.Count} active user(s)."); // snippet-end: neo4j-quick-start + Console.WriteLine($"Found {users.Count} active user(s)."); } private static async Task AgeQuickStartAsync() @@ -141,8 +141,8 @@ private static async Task AgeQuickStartAsync() var activeUsers = await graph.Nodes() .Where(user => user.IsActive) .ToListAsync(); - Console.WriteLine($"Found {activeUsers.Count} active user(s)."); // snippet-end: age-quick-start + Console.WriteLine($"Found {activeUsers.Count} active user(s)."); } private static async Task InMemoryQuickStartAsync() @@ -153,7 +153,7 @@ private static async Task InMemoryQuickStartAsync() await graph.CreateNodeAsync(new Person { Name = "Alice" }); var alice = await graph.Nodes().Where(p => p.Name == "Alice").SingleAsync(); - Console.WriteLine(alice.Name); // snippet-end: in-memory-quick-start + Console.WriteLine(alice.Name); } }