Skip to content

Commit fdb03ff

Browse files
committed
feat: general improvements and minor bugs
1 parent ed4aed4 commit fdb03ff

3 files changed

Lines changed: 92 additions & 32 deletions

File tree

src/WebExpress.WebIndex.Test/WQL/UnitTestWqlWordSearchA.cs

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -236,14 +236,37 @@ public void AbstracrSyntaxTree()
236236
[InlineData("text ~ ||", false, 2, WqlExpressionType.Operator, WqlExpressionType.Parameter)]
237237
[InlineData("text ~ '", false, 3, WqlExpressionType.Quotation, WqlExpressionType.Parameter)]
238238
[InlineData("text ~ \"", false, 3, WqlExpressionType.Quotation, WqlExpressionType.Parameter)]
239-
[InlineData("text ~ Helena", true, 3, WqlExpressionType.Parameter, WqlExpressionType.LogicalOperator, WqlExpressionType.Order, WqlExpressionType.Partitioning)]
240-
[InlineData("text ~ 'Helena'", true, 5, WqlExpressionType.Quotation, WqlExpressionType.LogicalOperator, WqlExpressionType.Order, WqlExpressionType.Partitioning)]
241-
[InlineData("text ~ \"Helena\"", true, 5, WqlExpressionType.Quotation, WqlExpressionType.LogicalOperator, WqlExpressionType.Order, WqlExpressionType.Partitioning)]
239+
[InlineData("text ~ Helena", true, 3, WqlExpressionType.Parameter, WqlExpressionType.LogicalOperator, WqlExpressionType.Order, WqlExpressionType.PartitioningOperator)]
240+
[InlineData("text ~ 'Helena'", true, 5, WqlExpressionType.Quotation, WqlExpressionType.LogicalOperator, WqlExpressionType.Order, WqlExpressionType.PartitioningOperator)]
241+
[InlineData("text ~ \"Helena\"", true, 5, WqlExpressionType.Quotation, WqlExpressionType.LogicalOperator, WqlExpressionType.Order, WqlExpressionType.PartitioningOperator)]
242242
[InlineData("text ~ day(", false, 4, WqlExpressionType.OpenParenthesis, WqlExpressionType.Parameter, WqlExpressionType.Quotation, WqlExpressionType.CloseParenthesis)]
243-
[InlineData("text ~ day()", true, 5, WqlExpressionType.CloseParenthesis, WqlExpressionType.LogicalOperator, WqlExpressionType.Order, WqlExpressionType.Partitioning)]
243+
[InlineData("text ~ day()", true, 5, WqlExpressionType.CloseParenthesis, WqlExpressionType.LogicalOperator, WqlExpressionType.Order, WqlExpressionType.PartitioningOperator)]
244+
[InlineData("text ~ day('Helena')", true, 8, WqlExpressionType.CloseParenthesis, WqlExpressionType.LogicalOperator, WqlExpressionType.Order, WqlExpressionType.PartitioningOperator)]
245+
[InlineData("text ~ day('Helena',", false, 8, WqlExpressionType.Separator, WqlExpressionType.LogicalOperator, WqlExpressionType.Parameter)]
244246
[InlineData("text ~ day(\"", false, 5, WqlExpressionType.Quotation, WqlExpressionType.Parameter, WqlExpressionType.CloseParenthesis)]
245247
[InlineData("text ~ Helena and", false, 4, WqlExpressionType.LogicalOperator, WqlExpressionType.Attribute, WqlExpressionType.OpenParenthesis)]
246-
[InlineData("text in ('Helena', 'Hans')", true, 11, WqlExpressionType.CloseParenthesis, WqlExpressionType.LogicalOperator, WqlExpressionType.Order, WqlExpressionType.Partitioning)]
248+
[InlineData("text in #", false, 2, WqlExpressionType.Operator, WqlExpressionType.OpenParenthesis)]
249+
[InlineData("text in (", false, 3, WqlExpressionType.OpenParenthesis, WqlExpressionType.Parameter, WqlExpressionType.Function)]
250+
[InlineData("text in ('Helena'", false, 6, WqlExpressionType.Quotation, WqlExpressionType.Separator, WqlExpressionType.Order, WqlExpressionType.CloseParenthesis)]
251+
[InlineData("text in ('Helena' ,", false, 7, WqlExpressionType.Separator, WqlExpressionType.Parameter, WqlExpressionType.Function)]
252+
[InlineData("text in ('Helena', 'Hans')", true, 11, WqlExpressionType.CloseParenthesis, WqlExpressionType.LogicalOperator, WqlExpressionType.Order, WqlExpressionType.PartitioningOperator)]
253+
[InlineData("(text ~ 'Helena')", true, 7, WqlExpressionType.CloseParenthesis, WqlExpressionType.LogicalOperator, WqlExpressionType.Order, WqlExpressionType.PartitioningOperator)]
254+
[InlineData("(text ~ 'Helena'", false, 6, WqlExpressionType.Quotation, WqlExpressionType.LogicalOperator, WqlExpressionType.CloseParenthesis)]
255+
[InlineData("order", false, 1, WqlExpressionType.Order, WqlExpressionType.Attribute)]
256+
[InlineData("orderby", false, 1, WqlExpressionType.Order, WqlExpressionType.Attribute)]
257+
[InlineData("order by", false, 1, WqlExpressionType.Order, WqlExpressionType.Attribute)]
258+
[InlineData("orderby text", true, 2, WqlExpressionType.Attribute, WqlExpressionType.OrderDirection, WqlExpressionType.Separator, WqlExpressionType.PartitioningOperator)]
259+
[InlineData("order by text", true, 2, WqlExpressionType.Attribute, WqlExpressionType.OrderDirection, WqlExpressionType.Separator, WqlExpressionType.PartitioningOperator)]
260+
[InlineData("orderby text,", false, 3, WqlExpressionType.Separator, WqlExpressionType.Attribute)]
261+
[InlineData("order by text,", false, 3, WqlExpressionType.Separator, WqlExpressionType.Attribute)]
262+
[InlineData("orderby text asc", true, 3, WqlExpressionType.OrderDirection, WqlExpressionType.PartitioningOperator)]
263+
[InlineData("order by text asc", true, 3, WqlExpressionType.OrderDirection, WqlExpressionType.PartitioningOperator)]
264+
[InlineData("orderby text desc", true, 3, WqlExpressionType.OrderDirection, WqlExpressionType.PartitioningOperator)]
265+
[InlineData("order by text desc", true, 3, WqlExpressionType.OrderDirection, WqlExpressionType.PartitioningOperator)]
266+
[InlineData("skip", false, 1, WqlExpressionType.PartitioningOperator, WqlExpressionType.Partitioning)]
267+
[InlineData("skip 5", true, 2, WqlExpressionType.Partitioning, WqlExpressionType.PartitioningOperator)]
268+
[InlineData("take", false, 1, WqlExpressionType.PartitioningOperator, WqlExpressionType.Partitioning)]
269+
[InlineData("take 5", true, 2, WqlExpressionType.Partitioning, WqlExpressionType.PartitioningOperator)]
247270
public void Analyze(string wql, bool valid, int count, WqlExpressionType type, params WqlExpressionType[] expectedNextTokens)
248271
{
249272
// arrange

src/WebExpress.WebIndex/Wql/WqlExpressionType.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,6 @@ public enum WqlExpressionType
7878
/// <summary>
7979
/// Represents the separator character used to delimit values.
8080
/// </summary>
81-
Separator,
82-
83-
/// <summary>
84-
/// Represents a constant value used within an expression.
85-
/// </summary>
86-
Literal
81+
Separator
8782
}
8883
}

src/WebExpress.WebIndex/Wql/WqlParser.cs

Lines changed: 63 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,9 @@ private WqlExpressionNodeFilter<TIndexItem> ParseFilter(Queue<WqlToken> tokenQue
245245
[]
246246
);
247247

248-
ilaQueue.Enqueue(new WqlLookaheadToken(closeToken, WqlExpressionType.OpenParenthesis)
248+
ilaQueue.Enqueue(new WqlLookaheadToken(closeToken, WqlExpressionType.CloseParenthesis)
249249
{
250-
ExpectedNextTokens = [WqlExpressionType.Attribute, WqlExpressionType.OpenParenthesis]
250+
ExpectedNextTokens = [WqlExpressionType.LogicalOperator, WqlExpressionType.Order, WqlExpressionType.PartitioningOperator]
251251
});
252252

253253
if (PeekToken(tokenQueue, "and") ||
@@ -344,8 +344,7 @@ private WqlExpressionNodeFilterCondition<TIndexItem> ParseCondition(Queue<WqlTok
344344
}
345345

346346
var condition = Conditions
347-
.Where(x => PeekToken(tokenQueue, x.Key.Split(' ')))
348-
.FirstOrDefault();
347+
.FirstOrDefault(x => PeekToken(tokenQueue, x.Key?.Split(' ')));
349348

350349
try
351350
{
@@ -364,15 +363,15 @@ private WqlExpressionNodeFilterCondition<TIndexItem> ParseCondition(Queue<WqlTok
364363
}
365364

366365
var operationTokens = ReadToken(tokenQueue, condition.Key.Split(' ')).ToList();
367-
ilaQueue.Enqueue(new WqlLookaheadToken(new WqlTokenCombine(operationTokens), WqlExpressionType.Operator)
368-
{
369-
ExpectedNextTokens = [WqlExpressionType.Parameter]
370-
});
371-
372366
var instance = Activator.CreateInstance(condition.Value) as WqlExpressionNodeFilterCondition<TIndexItem>;
373367

374368
if (instance is WqlExpressionNodeFilterConditionBinary<TIndexItem> binary)
375369
{
370+
ilaQueue.Enqueue(new WqlLookaheadToken(new WqlTokenCombine(operationTokens), WqlExpressionType.Operator)
371+
{
372+
ExpectedNextTokens = [WqlExpressionType.Parameter]
373+
});
374+
376375
binary.Culture = Culture;
377376
binary.Attribute = attribute;
378377

@@ -383,8 +382,12 @@ private WqlExpressionNodeFilterCondition<TIndexItem> ParseCondition(Queue<WqlTok
383382
}
384383
else if (instance is WqlExpressionNodeFilterConditionSet<TIndexItem> set)
385384
{
386-
var parameters = new List<WqlExpressionNodeParameter<TIndexItem>>();
385+
ilaQueue.Enqueue(new WqlLookaheadToken(new WqlTokenCombine(operationTokens), WqlExpressionType.Operator)
386+
{
387+
ExpectedNextTokens = [WqlExpressionType.OpenParenthesis]
388+
});
387389

390+
var parameters = new List<WqlExpressionNodeParameter<TIndexItem>>();
388391
var openToken = ReadToken(tokenQueue, "(");
389392

390393
ilaQueue.Enqueue(new WqlLookaheadToken(openToken, WqlExpressionType.OpenParenthesis)
@@ -396,13 +399,14 @@ private WqlExpressionNodeFilterCondition<TIndexItem> ParseCondition(Queue<WqlTok
396399

397400
while (PeekToken(tokenQueue, ","))
398401
{
399-
var SeparatorToken = ReadToken(tokenQueue, ",");
400-
parameters.Add(ParseParameter(tokenQueue, ilaQueue, false));
402+
var separatorToken = ReadToken(tokenQueue, ",");
401403

402-
ilaQueue.Enqueue(new WqlLookaheadToken(SeparatorToken, WqlExpressionType.Separator)
404+
ilaQueue.Enqueue(new WqlLookaheadToken(separatorToken, WqlExpressionType.Separator)
403405
{
404406
ExpectedNextTokens = [WqlExpressionType.Parameter, WqlExpressionType.Separator]
405407
});
408+
409+
parameters.Add(ParseParameter(tokenQueue, ilaQueue, false));
406410
}
407411

408412
var closeToken = ReadToken(tokenQueue, ")");
@@ -837,8 +841,7 @@ private WqlExpressionNodeFilterFunction<TIndexItem> ParseFunction(Queue<WqlToken
837841
{
838842
var parameters = new List<WqlExpressionNodeParameter<TIndexItem>>();
839843
var function = Functions
840-
.Where(x => PeekToken(tokenQueue, x.Key))
841-
.FirstOrDefault();
844+
.FirstOrDefault(x => PeekToken(tokenQueue, x.Key));
842845
var nameToken = ReadToken(tokenQueue);
843846
var tokenList = new List<IWqlToken>()
844847
{
@@ -861,9 +864,7 @@ private WqlExpressionNodeFilterFunction<TIndexItem> ParseFunction(Queue<WqlToken
861864

862865
try
863866
{
864-
var instance = Activator.CreateInstance(function.Value) as WqlExpressionNodeFilterFunction<TIndexItem>;
865-
866-
if (instance is null)
867+
if (Activator.CreateInstance(function.Value) is not WqlExpressionNodeFilterFunction<TIndexItem> instance)
867868
{
868869
throw new WqlParseException
869870
(
@@ -896,11 +897,24 @@ private WqlExpressionNodeFilterFunction<TIndexItem> ParseFunction(Queue<WqlToken
896897

897898
while (PeekToken(tokenQueue, ","))
898899
{
899-
tokenList.Add(ReadToken(tokenQueue, ","));
900+
var separatorToken = ReadToken(tokenQueue, ",");
901+
tokenList.Add(separatorToken);
902+
903+
ilaQueue.Enqueue(new WqlLookaheadToken(separatorToken, WqlExpressionType.Separator)
904+
{
905+
ExpectedNextTokens = [WqlExpressionType.Parameter, WqlExpressionType.Function]
906+
});
907+
900908
parameters.Add(ParseParameter(tokenQueue, ilaQueue, true));
901909
}
902910

903-
tokenList.Add(ReadToken(tokenQueue, ")"));
911+
var closeToken = ReadToken(tokenQueue, ")");
912+
tokenList.Add(closeToken);
913+
914+
ilaQueue.Enqueue(new WqlLookaheadToken(closeToken, WqlExpressionType.CloseParenthesis)
915+
{
916+
ExpectedNextTokens = [WqlExpressionType.LogicalOperator, WqlExpressionType.Order, WqlExpressionType.PartitioningOperator]
917+
});
904918
}
905919

906920
instance.Parameters = parameters;
@@ -988,6 +1002,34 @@ private WqlExpressionNodeOrder<TIndexItem> ParseOrder(Queue<WqlToken> tokenQueue
9881002

9891003
return new WqlExpressionNodeOrder<TIndexItem> { Attributes = attributes };
9901004
}
1005+
else if (PeekToken(tokenQueue, "order"))
1006+
{
1007+
var attributes = new List<WqlExpressionNodeOrderAttribute<TIndexItem>>();
1008+
var i = 0;
1009+
1010+
var orderbyToken = ReadToken(tokenQueue, "order");
1011+
1012+
ilaQueue.Enqueue(new WqlLookaheadToken(orderbyToken, WqlExpressionType.Order)
1013+
{
1014+
ExpectedNextTokens = [WqlExpressionType.Attribute]
1015+
});
1016+
1017+
attributes.Add(ParseOrderAttribute(tokenQueue, i++, ilaQueue));
1018+
1019+
while (PeekToken(tokenQueue, ","))
1020+
{
1021+
var separatorToken = ReadToken(tokenQueue, ",");
1022+
1023+
ilaQueue.Enqueue(new WqlLookaheadToken(separatorToken, WqlExpressionType.Separator)
1024+
{
1025+
ExpectedNextTokens = [WqlExpressionType.Attribute]
1026+
});
1027+
1028+
attributes.Add(ParseOrderAttribute(tokenQueue, i++, ilaQueue));
1029+
}
1030+
1031+
return new WqlExpressionNodeOrder<TIndexItem> { Attributes = attributes };
1032+
}
9911033
else
9921034
{
9931035
return null;
@@ -1116,7 +1158,7 @@ private static WqlExpressionNodePartitioning<TIndexItem> ParsePartitioning(Queue
11161158

11171159
ilaQueue.Enqueue(new WqlLookaheadToken(valueToken, WqlExpressionType.Partitioning)
11181160
{
1119-
ExpectedNextTokens = [WqlExpressionType.Partitioning],
1161+
ExpectedNextTokens = [WqlExpressionType.PartitioningOperator],
11201162
});
11211163

11221164
function.Add(new WqlExpressionNodePartitioningFunction<TIndexItem>()

0 commit comments

Comments
 (0)