Skip to content

Commit 25e9f7c

Browse files
authored
fix(linq): Flux AST for Tag parameters which are not String (#202)
1 parent 9661b85 commit 25e9f7c

File tree

8 files changed

+119
-9
lines changed

8 files changed

+119
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
### Bug Fixes
88
1. [#193](https://github.com/influxdata/influxdb-client-csharp/pull/193): Create services without API implementation
9+
1. [#202](https://github.com/influxdata/influxdb-client-csharp/pull/202): Flux AST for Tag parameters which are not `String` [LINQ]
910

1011
## 1.18.0 [2021-04-30]
1112

Client.Linq.Test/DomainObjects.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,20 @@ class SensorAttribute
5353
public string Name { get; set; }
5454
public string Value { get; set; }
5555
}
56+
57+
[Measurement(nameof(TagIsNotDefinedAsString))]
58+
class TagIsNotDefinedAsString
59+
{
60+
[Column(IsTag = true)]
61+
public int Id { get; set; }
62+
63+
[Column(IsTag = true)]
64+
public string Tag { get; set; }
65+
66+
[Column(nameof(Energy))]
67+
public decimal Energy { get; set; }
68+
69+
[Column(IsTimestamp = true)]
70+
public DateTime Timestamp { get; set; }
71+
}
5672
}

Client.Linq.Test/InfluxDBQueryVisitorTest.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,46 @@ orderby s.Timestamp
766766
Assert.AreEqual(expected, ((InfluxDBQueryable<Sensor>) query).ToDebugQuery()._Query);
767767
}
768768

769+
[Test]
770+
public void TagIsNotDefinedAsString()
771+
{
772+
var fromDateTime = new DateTime(2020, 10, 15, 8, 20, 15, DateTimeKind.Utc);
773+
var queries = new[]
774+
{
775+
(
776+
from s in InfluxDBQueryable<TagIsNotDefinedAsString>.Queryable("my-bucket", "my-org", _queryApi)
777+
where s.Timestamp >= fromDateTime
778+
where s.Id == 123456
779+
select s,
780+
"(r[\"Id\"] == p4)"
781+
),
782+
(
783+
from s in InfluxDBQueryable<TagIsNotDefinedAsString>.Queryable("my-bucket", "my-org", _queryApi)
784+
where s.Timestamp >= fromDateTime
785+
where 123456 == s.Id
786+
select s,
787+
"(p4 == r[\"Id\"])"
788+
),
789+
};
790+
791+
foreach (var (queryable, expression) in queries)
792+
{
793+
var visitor = BuildQueryVisitor(queryable);
794+
795+
var expected = "start_shifted = int(v: time(v: p3))\n\n" +
796+
"from(bucket: p1) " +
797+
"|> range(start: time(v: start_shifted)) " +
798+
$"|> filter(fn: (r) => {expression}) " +
799+
"|> pivot(rowKey:[\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\") " +
800+
"|> drop(columns: [\"_start\", \"_stop\", \"_measurement\"])";
801+
802+
Assert.AreEqual(expected, visitor.BuildFluxQuery());
803+
var ast = visitor.BuildFluxAST();
804+
Assert.AreEqual(fromDateTime, GetLiteral<DateTimeLiteral>(ast, 2).Value);
805+
Assert.AreEqual("123456", GetLiteral<StringLiteral>(ast, 3).Value);
806+
}
807+
}
808+
769809
private InfluxDBQueryVisitor BuildQueryVisitor(IQueryable queryable, Expression expression = null)
770810
{
771811
var queryExecutor = (InfluxDBQueryExecutor) ((DefaultQueryProvider) queryable.Provider).Executor;

Client.Linq/Internal/Expressions/AssignmentValue.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@ namespace InfluxDB.Client.Linq.Internal.Expressions
55
internal class AssignmentValue: IExpressionPart
66
{
77
internal readonly object Value;
8-
private readonly string _assignment;
8+
internal readonly string Assignment;
99
internal AssignmentValue(object value, string assignment)
1010
{
1111
Value = value;
12-
_assignment = assignment;
12+
Assignment = assignment;
1313
}
1414

1515
public void AppendFlux(StringBuilder builder)
1616
{
17-
builder.Append(_assignment);
17+
builder.Append(Assignment);
1818
}
1919
}
2020
}

Client.Linq/Internal/QueryExpressionTreeVisitor.cs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ private void NormalizeNamedField()
185185

186186
NormalizeNamedField();
187187
}
188-
188+
189189
private void NormalizeNamedFieldValue()
190190
{
191191
var index = _expressionParts
@@ -241,6 +241,33 @@ private void NormalizeNamedFieldValue()
241241
NormalizeNamedFieldValue();
242242
}
243243

244+
/// <summary>
245+
/// Mark variables that are use to filter by tag by tag as tag.
246+
/// </summary>
247+
internal static void NormalizeTagsAssignments(List<IExpressionPart> parts, QueryGenerationContext context)
248+
{
249+
var indexes = Enumerable.Range(0, parts.Count)
250+
.Where(i => parts[i] is BinaryOperator)
251+
.ToList();
252+
253+
foreach (var index in indexes)
254+
{
255+
// "sensorId == 123456"
256+
if (index >= 1 && parts[index - 1] is TagColumnName && parts[index + 1] is AssignmentValue)
257+
{
258+
var assignmentValue = (AssignmentValue) parts[index + 1];
259+
context.Variables.VariableIsTag(assignmentValue.Assignment);
260+
}
261+
262+
// "123456 == sensorId"
263+
if (index >= 1 && parts[index - 1] is AssignmentValue && parts[index + 1] is TagColumnName)
264+
{
265+
var assignmentValue = (AssignmentValue) parts[index - 1];
266+
context.Variables.VariableIsTag(assignmentValue.Assignment);
267+
}
268+
}
269+
}
270+
244271
/// <summary>
245272
/// Normalize generated expression.
246273
/// </summary>

Client.Linq/Internal/QueryVisitor.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ public override void VisitWhereClause(WhereClause whereClause, QueryModel queryM
109109

110110
QueryExpressionTreeVisitor.NormalizeExpressions(rangeFilter);
111111
QueryExpressionTreeVisitor.NormalizeExpressions(tagFilter);
112+
QueryExpressionTreeVisitor.NormalizeTagsAssignments(tagFilter, _context);
112113
QueryExpressionTreeVisitor.NormalizeExpressions(fieldFilter);
113114

114115
Debug.WriteLine("--- normalized LINQ expressions: ---");

Client.Linq/Internal/VariableAggregator.cs

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,35 @@ internal string AddNamedVariable(object value)
1414
var variable = new NamedVariable
1515
{
1616
Value = value,
17-
Name = $"p{_variables.Count + 1}"
17+
Name = $"p{_variables.Count + 1}",
18+
IsTag = false
1819
};
1920
_variables.Add(variable);
2021
return variable.Name;
2122
}
2223

24+
/// <summary>
25+
/// Mark variable with specified name as a Tag.
26+
/// </summary>
27+
/// <param name="variableName">variable name</param>
28+
internal void VariableIsTag(string variableName)
29+
{
30+
foreach (var namedVariable in _variables.Where(it => it.Name.Equals(variableName)))
31+
{
32+
namedVariable.IsTag = true;
33+
}
34+
}
35+
2336
internal List<Statement> GetStatements()
2437
{
2538
return _variables.Select(variable =>
2639
{
2740
Expression literal;
28-
if (variable.Value is int i)
41+
if (variable.IsTag)
42+
{
43+
literal = CreateStringLiteral(variable);
44+
}
45+
else if (variable.Value is int i)
2946
{
3047
literal = new IntegerLiteral("IntegerLiteral", Convert.ToString(i));
3148
}
@@ -47,7 +64,7 @@ internal List<Statement> GetStatements()
4764
}
4865
else
4966
{
50-
literal = new StringLiteral("StringLiteral", Convert.ToString(variable.Value));
67+
literal = CreateStringLiteral(variable);
5168
}
5269

5370
var assignment = new VariableAssignment("VariableAssignment",
@@ -56,11 +73,17 @@ internal List<Statement> GetStatements()
5673
return new OptionStatement("OptionStatement", assignment) as Statement;
5774
}).ToList();
5875
}
76+
77+
private StringLiteral CreateStringLiteral(NamedVariable variable)
78+
{
79+
return new StringLiteral("StringLiteral", Convert.ToString(variable.Value));
80+
}
5981
}
6082

6183
internal sealed class NamedVariable
6284
{
63-
public string Name { get; set; }
64-
public object Value { get; set; }
85+
internal string Name { get; set; }
86+
internal object Value { get; set; }
87+
internal bool IsTag { get; set; }
6588
}
6689
}

Client.Linq/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ The library supports to use a LINQ expression to query the InfluxDB.
3232
- [How to debug output Flux Query](#how-to-debug-output-flux-query)
3333

3434
## Changelog
35+
### 1.19.0-dev.??? [???]
36+
- Fix Flux AST for Tag parameters which are not `String`. See details - [#202](https://github.com/influxdata/influxdb-client-csharp/pull/202)
3537
### 1.19.0-dev.3084 [2021-05-07]
3638
- optimize Flux Query for querying one time-series. See details - [#197](https://github.com/influxdata/influxdb-client-csharp/pull/197)
3739
### 1.18.0-dev.2973 [2021-04-27]

0 commit comments

Comments
 (0)