Skip to content

Commit a0666bf

Browse files
committed
Fixed test
1 parent 780342d commit a0666bf

File tree

4 files changed

+39
-11
lines changed

4 files changed

+39
-11
lines changed

src/Foundatio.Parsers.LuceneQueries/Extensions/QueryNodeExtensions.cs

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using Foundatio.Parsers.LuceneQueries.Nodes;
44
using Foundatio.Parsers.LuceneQueries.Visitors;
@@ -189,9 +189,14 @@ public static void SetOriginalField(this IFieldQueryNode node, string field)
189189
}
190190

191191
private const string OperationTypeKey = "@OperationType";
192+
public static bool HasOperationType(this IQueryNode node)
193+
{
194+
return node.Data.ContainsKey(OperationTypeKey);
195+
}
196+
192197
public static string GetOperationType(this IQueryNode node)
193198
{
194-
if (!node.Data.TryGetValue(OperationTypeKey, out var value))
199+
if (!node.Data.TryGetValue(OperationTypeKey, out object value))
195200
return null;
196201

197202
return (string)value;

src/Foundatio.Parsers.LuceneQueries/Visitors/AssignOperationTypeVisitor.cs

+20-1
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,19 @@ public class AssignOperationTypeVisitor : ChainableQueryVisitor
99
{
1010
public override Task VisitAsync(GroupNode node, IQueryVisitorContext context)
1111
{
12+
if (node.HasOperationType())
13+
return Task.CompletedTask;
14+
1215
if (String.IsNullOrEmpty(node.Field))
1316
return base.VisitAsync(node, context);
1417

1518
if (node.Left is not TermNode leftTerm)
1619
{
20+
// For sub aggregations we need to see if there is a parent with parens
21+
var closestParentWithParens = node.GetGroupNode();
22+
if (closestParentWithParens is { HasParens: true })
23+
return base.VisitAsync(node, context);
24+
1725
context.AddValidationError($"Aggregations ({node.Field}) must specify a field.");
1826
return Task.CompletedTask;
1927
}
@@ -35,6 +43,17 @@ public override Task VisitAsync(GroupNode node, IQueryVisitorContext context)
3543

3644
public override void Visit(TermNode node, IQueryVisitorContext context)
3745
{
46+
if (node.HasOperationType())
47+
return;
48+
49+
if (String.IsNullOrEmpty(node.Field))
50+
return;
51+
52+
// For sub aggregations we need to see if there is a parent with parens
53+
var closestParentWithParens = node.GetGroupNode();
54+
if (closestParentWithParens is { HasParens: true })
55+
return;
56+
3857
if (String.IsNullOrEmpty(node.Field) && !String.IsNullOrEmpty(node.Term))
3958
{
4059
context.AddValidationError($"Aggregations ({node.Term}) must specify a field.");
@@ -51,7 +70,7 @@ public override void Visit(TermNode node, IQueryVisitorContext context)
5170
node.SetOperationType(node.Field);
5271
node.Field = node.Term;
5372
node.Term = null;
54-
}
73+
}
5574
}
5675

5776
public static class AggregationType

src/Foundatio.Parsers.LuceneQueries/Visitors/FieldResolverQueryVisitor.cs

+3
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ private async Task ResolveField(IFieldQueryNode node, IQueryVisitorContext conte
6060

6161
if (resolvedField == null)
6262
{
63+
if (context.QueryType is QueryTypes.Aggregation && node.Field.StartsWith("@"))
64+
return;
65+
6366
// add field to unresolved fields list
6467
context.GetValidationResult().UnresolvedFields.Add(node.Field);
6568
return;

tests/Foundatio.Parsers.ElasticQueries.Tests/ElasticQueryParserTests.cs

+9-8
Original file line numberDiff line numberDiff line change
@@ -1495,20 +1495,21 @@ private async Task<string> GetIncludeAsync(string name)
14951495
return "included:value";
14961496
}
14971497

1498-
[Fact]
1499-
public async Task CanValidateAggregation()
1498+
[Theory]
1499+
[InlineData("terms:field1")]
1500+
[InlineData("terms:(field1~100 @missing:__missing__)")]
1501+
[InlineData("terms:(field1~100 (@missing:__missing__))")]
1502+
public async Task CanValidateAggregation(string aggregation)
15001503
{
1501-
var index = CreateRandomIndex<MyType>(d => d.Properties(p => p.Keyword(e => e.Name(m => m.Field1))));
1502-
await Client.IndexAsync(new MyType { Field1 = "value123" }, i => i.Index(index));
1503-
await Client.Indices.RefreshAsync(index);
1504-
1504+
string index = CreateRandomIndex<MyType>(d => d.Properties(p => p.Keyword(e => e.Name(m => m.Field1))));
15051505
var context = new ElasticQueryVisitorContext { QueryType = QueryTypes.Aggregation };
1506-
var parser = new ElasticQueryParser(c => c.UseMappings(Client, index).SetValidationOptions(new QueryValidationOptions { AllowUnresolvedFields = false, }).SetLoggerFactory(Log));
1507-
var node = await parser.ParseAsync("terms:(id~100 @missing:__missing__)", context);
1506+
var parser = new ElasticQueryParser(c => c.UseMappings(Client, index).SetLoggerFactory(Log));
1507+
var node = await parser.ParseAsync(aggregation, context);
15081508

15091509
var result = await ValidationVisitor.RunAsync(node, context);
15101510
Assert.True(result.IsValid, result.Message);
15111511
Assert.Single(result.ReferencedFields, "field1");
1512+
Assert.Empty(result.UnresolvedFields);
15121513
}
15131514
}
15141515

0 commit comments

Comments
 (0)