Skip to content

Commit

Permalink
Merge pull request #63 from mrt181/61_JsonPropertyNames_are_ignored_w…
Browse files Browse the repository at this point in the history
…hen_using_syntax_to_select_individual_columns

[ksqlDb.RestApi.Client]: fix colum names in sql
  • Loading branch information
tomasfabian authored Mar 9, 2024
2 parents 0bf5165 + 7641824 commit f9b3fed
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
using FluentAssertions;
using ksqlDB.RestApi.Client.KSql.Linq.PullQueries;
using ksqlDB.RestApi.Client.KSql.Query.Context;
using ksqlDB.RestApi.Client.KSql.Query.Functions;
using ksqlDB.RestApi.Client.KSql.RestApi.Enums;
using ksqlDb.RestApi.Client.Tests.Models;
using ksqlDb.RestApi.Client.Tests.Models.Sensors;
using NUnit.Framework;
using UnitTests;
using static ksqlDB.RestApi.Client.KSql.RestApi.Enums.IdentifierEscaping;
using TestParameters = ksqlDb.RestApi.Client.Tests.Helpers.TestParameters;

namespace ksqlDb.RestApi.Client.Tests.KSql.Linq.PullQueries;
Expand Down Expand Up @@ -143,4 +147,76 @@ public void Take()
//Assert
ksql.Should().BeEquivalentTo($"SELECT * FROM {MaterializedViewName} LIMIT {limit};");
}

[TestCase(Never, ExpectedResult = $"SELECT sub FROM {nameof(JsonPropertyNameTestData)};")]
[TestCase(Keywords, ExpectedResult = $"SELECT sub FROM {nameof(JsonPropertyNameTestData)};")]
[TestCase(Always, ExpectedResult = $"SELECT `sub` FROM `{nameof(JsonPropertyNameTestData)}`;")]
public string SelectColumnsUsingPullQueryThatHaveJsonPropertyName(IdentifierEscaping escaping)
{
//Arrange
var dbContext = new KSqlDBContext(new KSqlDBContextOptions(TestParameters.KsqlDbUrl)
{ IdentifierEscaping = escaping });

//Act
var ksql = dbContext.CreatePullQuery<JsonPropertyNameTestData>()
.Select(c => new { c.SubProperty })
.ToQueryString();

//Assert
return ksql.ReplaceLineEndings();
}

[TestCase(Never, ExpectedResult = $"SELECT sub AS Prop FROM {nameof(JsonPropertyNameTestData)};")]
[TestCase(Keywords, ExpectedResult = $"SELECT sub AS Prop FROM {nameof(JsonPropertyNameTestData)};")]
[TestCase(Always, ExpectedResult = $"SELECT `sub` AS `Prop` FROM `{nameof(JsonPropertyNameTestData)}`;")]
public string SelectColumnsUsingPullQueryThatHaveJsonPropertyNameWithAlias(IdentifierEscaping escaping)
{
//Arrange
var dbContext = new KSqlDBContext(new KSqlDBContextOptions(TestParameters.KsqlDbUrl)
{ IdentifierEscaping = escaping });

//Act
var ksql = dbContext.CreatePullQuery<JsonPropertyNameTestData>()
.Select(c => new { Prop = c.SubProperty })
.ToQueryString();

//Assert
return ksql.ReplaceLineEndings();
}

[TestCase(Never, ExpectedResult = $"SELECT RowTime, sub FROM {nameof(JsonPropertyNameTestData)};")]
[TestCase(Keywords, ExpectedResult = $"SELECT RowTime, sub FROM {nameof(JsonPropertyNameTestData)};")]
[TestCase(Always, ExpectedResult = $"SELECT RowTime, `sub` FROM `{nameof(JsonPropertyNameTestData)}`;")]
public string SelectColumnsUsingPullQueryThatHaveJsonPropertyNameWithPseudoColumn(IdentifierEscaping escaping)
{
//Arrange
var dbContext = new KSqlDBContext(new KSqlDBContextOptions(TestParameters.KsqlDbUrl)
{ IdentifierEscaping = escaping });

//Act
var ksql = dbContext.CreatePullQuery<JsonPropertyNameTestData>()
.Select(c => new { c.RowTime, c.SubProperty })
.ToQueryString();

//Assert
return ksql.ReplaceLineEndings();
}

[TestCase(Never, ExpectedResult = $"SELECT RowTime, sub AS Prop FROM {nameof(JsonPropertyNameTestData)};")]
[TestCase(Keywords, ExpectedResult = $"SELECT RowTime, sub AS Prop FROM {nameof(JsonPropertyNameTestData)};")]
[TestCase(Always, ExpectedResult = $"SELECT RowTime, `sub` AS `Prop` FROM `{nameof(JsonPropertyNameTestData)}`;")]
public string SelectColumnsUsingPullQueryThatHaveJsonPropertyNameWithAliasWithPseudoColum(IdentifierEscaping escaping)
{
//Arrange
var dbContext = new KSqlDBContext(new KSqlDBContextOptions(TestParameters.KsqlDbUrl)
{ IdentifierEscaping = escaping });

//Act
var ksql = dbContext.CreatePullQuery<JsonPropertyNameTestData>()
.Select(c => new { c.RowTime, Prop = c.SubProperty })
.ToQueryString();

//Assert
return ksql.ReplaceLineEndings();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Text.Json.Serialization;
using ksqlDB.RestApi.Client.KSql.Query;
using ksqlDB.RestApi.Client.KSql.RestApi.Statements.Annotations;

namespace ksqlDb.RestApi.Client.Tests.Models
{
public class JsonPropertyNameTestData : Record
{
[JsonPropertyName("sub")] public SubProperty SubProperty { get; set; }
}

[Struct]
public class SubProperty
{
[JsonPropertyName("prop")] public string Property { get; set; }
}
}
40 changes: 27 additions & 13 deletions ksqlDb.RestApi.Client/KSql/Query/Visitors/KSqlVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Text.Json.Serialization;
using ksqlDB.RestApi.Client.Infrastructure.Extensions;
using ksqlDb.RestApi.Client.KSql.Entities;
using ksqlDB.RestApi.Client.KSql.RestApi.Extensions;
Expand Down Expand Up @@ -120,7 +121,7 @@ public override Expression Visit(Expression expression)
break;

case ExpressionType.Conditional:
VisitConditional((ConditionalExpression) expression);
VisitConditional((ConditionalExpression)expression);
break;
}

Expand All @@ -135,7 +136,7 @@ protected override Expression VisitConditional(ConditionalExpression node)
Append(" THEN ");
Visit(node.IfTrue);

if(node.IfFalse.NodeType != ExpressionType.Conditional)
if (node.IfFalse.NodeType != ExpressionType.Conditional)
Append(" ELSE ");

Visit(node.IfFalse);
Expand Down Expand Up @@ -219,7 +220,8 @@ private protected void TryPrintContains(MethodCallExpression methodCallExpressio
}
}

if (methodCallExpression.Method.DeclaringType == typeof(Enumerable) && methodCallExpression.Method.Name == nameof(Enumerable.Contains))
if (methodCallExpression.Method.DeclaringType == typeof(Enumerable) &&
methodCallExpression.Method.Name == nameof(Enumerable.Contains))
{
PrintArrayContainsForEnumerable(methodCallExpression.Arguments);
}
Expand Down Expand Up @@ -355,7 +357,8 @@ protected virtual void ProcessVisitNewMember(MemberInfo memberInfo, Expression e
return;
}

if (expression is MemberExpression { Expression: MemberExpression {Expression: not null} me3 } && me3.Expression.Type.IsKsqlGrouping())
if (expression is MemberExpression { Expression: MemberExpression { Expression: not null } me1 } &&
me1.Expression.Type.IsKsqlGrouping())
{
Append(memberInfo.Format(QueryMetadata.IdentifierEscaping));
return;
Expand All @@ -367,12 +370,22 @@ protected virtual void ProcessVisitNewMember(MemberInfo memberInfo, Expression e
Append(" ");
}

if (expression is MemberExpression { Expression.NodeType: ExpressionType.MemberAccess} me)
Destructure(me);
else if (expression is MemberExpression {Expression.NodeType: ExpressionType.Constant})
Visit(expression);
else
Append(memberInfo.Format(QueryMetadata.IdentifierEscaping));
switch (expression)
{
case MemberExpression { Expression.NodeType: ExpressionType.MemberAccess } me:
Destructure(me);
break;
case MemberExpression me2 when me2.Member.GetCustomAttribute<JsonPropertyNameAttribute>() != null ||
me2.Member.GetCustomAttribute<PseudoColumnAttribute>() != null:

Check failure on line 379 in ksqlDb.RestApi.Client/KSql/Query/Visitors/KSqlVisitor.cs

View workflow job for this annotation

GitHub Actions / build

The type or namespace name 'PseudoColumnAttribute' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 379 in ksqlDb.RestApi.Client/KSql/Query/Visitors/KSqlVisitor.cs

View workflow job for this annotation

GitHub Actions / build

The type or namespace name 'PseudoColumnAttribute' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 379 in ksqlDb.RestApi.Client/KSql/Query/Visitors/KSqlVisitor.cs

View workflow job for this annotation

GitHub Actions / build

The type or namespace name 'PseudoColumnAttribute' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 379 in ksqlDb.RestApi.Client/KSql/Query/Visitors/KSqlVisitor.cs

View workflow job for this annotation

GitHub Actions / build

The type or namespace name 'PseudoColumnAttribute' could not be found (are you missing a using directive or an assembly reference?)
Append(me2.Member.Format(QueryMetadata.IdentifierEscaping));
break;
case MemberExpression { Expression.NodeType: ExpressionType.Constant }:
Visit(expression);
break;
default:
Append(memberInfo.Format(QueryMetadata.IdentifierEscaping));
break;
}
}

protected override Expression VisitMember(MemberExpression memberExpression)
Expand All @@ -387,7 +400,8 @@ protected override Expression VisitMember(MemberExpression memberExpression)

var memberName = memberExpression.Member.Format(QueryMetadata.IdentifierEscaping);

var alias = IdentifierUtil.Format(((ParameterExpression)memberExpression.Expression).Name, QueryMetadata.IdentifierEscaping);
var alias = IdentifierUtil.Format(((ParameterExpression)memberExpression.Expression).Name,
QueryMetadata.IdentifierEscaping);

Append(foundFromItem?.Alias ?? alias);
Append(".");
Expand Down Expand Up @@ -493,7 +507,7 @@ private void AppendVisitMemberParameter(MemberExpression memberExpression)

if (type != fromItem?.Type)
{
Append(memberExpression.Member.Format(QueryMetadata.IdentifierEscaping));
Append(memberExpression.Member.Format(QueryMetadata.IdentifierEscaping));
}
}

Expand Down Expand Up @@ -601,7 +615,7 @@ protected void JoinAppend(IEnumerable enumerable)
else
Append(ColumnsSeparator);

if(value is ConstantExpression constantExpression)
if (value is ConstantExpression constantExpression)
Visit(constantExpression);
else
Visit(Expression.Constant(value));
Expand Down

0 comments on commit f9b3fed

Please sign in to comment.