Skip to content

Commit

Permalink
Merge pull request #6 from Servant-Software-LLC/5-unable-to-get-query…
Browse files Browse the repository at this point in the history
…engine-results-with-select-column-aliases

The original column name in the queryOutput was provided in the …
  • Loading branch information
DaveRMaltby committed Mar 16, 2024
2 parents 322a7d9 + e41f50c commit 4b86c00
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 2 deletions.
7 changes: 5 additions & 2 deletions src/Core/QueryProcessing/QueryEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,11 @@ private IEnumerable<DataRow> ResolveSelectColumns(DataTable queryOutput, IEnumer
var selectColumns = queryOutput.NewRow();
foreach (DataColumn dataColumn in queryOutput.Columns)
{
//Copy the column value from fromDataRows to the selectColumns
selectColumns[dataColumn.ColumnName] = dataRow[GetColumnName(dataColumn.ColumnName)];
//Items in the dataRow are using their original column names, so we need to get the original column name
var sqlColumn = dataColumn.ExProps().Column;

//Copy the column value from fromDataRows to the selectColumns.
selectColumns[dataColumn.ColumnName] = dataRow[GetColumnName(sqlColumn.ColumnName)];
}

yield return selectColumns;
Expand Down
38 changes: 38 additions & 0 deletions tests/Grammars/MySQL.Tests/QueryEngineTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using Irony.Parsing;
using SqlBuildingBlocks.Core.Tests.Utils;
using SqlBuildingBlocks.Grammars.MySQL.Tests.Utils;
using SqlBuildingBlocks.Interfaces;
using SqlBuildingBlocks.LogicalEntities;
using SqlBuildingBlocks.QueryProcessing;
using SqlBuildingBlocks.Utils;
using System.Linq;
using Xunit;

namespace SqlBuildingBlocks.Grammars.MySQL.Tests;

public class QueryEngineTests
{
[Fact]
public void Results_ColumnAlias()
{
SqlGrammarMySQL grammar = new();
var node = GrammarParser.Parse(grammar, @"SELECT VARIABLE_NAME Variable_name, VARIABLE_VALUE Value FROM performance_schema.session_variables WHERE VARIABLE_NAME LIKE 'sql_mode'");

FakeDatabaseConnectionProvider databaseConnectionProvider = new();
FakeTableDataProvider tableDataProvider = new();
SqlSelectDefinition selectDefinition = grammar.Create(node, databaseConnectionProvider, tableDataProvider, null);

Assert.False(selectDefinition.InvalidReferences);

AllTableDataProvider allTableDataProvider = new(new ITableDataProvider[] { tableDataProvider });
var queryEngine = new QueryEngine(allTableDataProvider, selectDefinition);

var queryResults = queryEngine.Query();

var results = queryResults.Results.ToList();

Assert.Equal(1, results.Count);

Check warning on line 34 in tests/Grammars/MySQL.Tests/QueryEngineTests.cs

View workflow job for this annotation

GitHub Actions / build

Do not use Assert.Equal() to check for collection size. Use Assert.Single instead. (https://xunit.net/xunit.analyzers/rules/xUnit2013)

Check warning on line 34 in tests/Grammars/MySQL.Tests/QueryEngineTests.cs

View workflow job for this annotation

GitHub Actions / build

Do not use Assert.Equal() to check for collection size. Use Assert.Single instead. (https://xunit.net/xunit.analyzers/rules/xUnit2013)
Assert.Equal("Variable_name", results[0].Table.Columns[0].ColumnName);
Assert.Equal("Value", results[0].Table.Columns[1].ColumnName);
}
}
10 changes: 10 additions & 0 deletions tests/Grammars/MySQL.Tests/Utils/FakeDatabaseConnectionProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using SqlBuildingBlocks.Interfaces;

namespace SqlBuildingBlocks.Grammars.MySQL.Tests.Utils;

internal class FakeDatabaseConnectionProvider : IDatabaseConnectionProvider
{
public string DefaultDatabase { get; set; } = string.Empty;

public bool CaseInsensitive => true;
}
39 changes: 39 additions & 0 deletions tests/Grammars/MySQL.Tests/Utils/FakeTableDataProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using SqlBuildingBlocks.Interfaces;
using SqlBuildingBlocks.LogicalEntities;
using SqlBuildingBlocks.QueryProcessing;
using System.Data;

namespace SqlBuildingBlocks.Grammars.MySQL.Tests.Utils;

public class FakeTableDataProvider : ITableDataProvider
{
public IEnumerable<DataColumn> GetColumns(SqlTable table)
{
if (table.TableName == "session_variables")
{
yield return new DataColumn("VARIABLE_NAME", typeof(string));
yield return new DataColumn("VARIABLE_VALUE", typeof(string));
yield break;
}

throw new NotImplementedException();
}

public record variable(string VARIABLE_NAME, string VARIABLE_VALUE);

Check warning on line 22 in tests/Grammars/MySQL.Tests/Utils/FakeTableDataProvider.cs

View workflow job for this annotation

GitHub Actions / build

The type name 'variable' only contains lower-cased ascii characters. Such names may become reserved for the language.

Check warning on line 22 in tests/Grammars/MySQL.Tests/Utils/FakeTableDataProvider.cs

View workflow job for this annotation

GitHub Actions / build

The type name 'variable' only contains lower-cased ascii characters. Such names may become reserved for the language.

private IEnumerable<variable> GetEnumerable()
{
yield return new("activate_all_roles_on_login", "OFF");
yield return new("sql_mode", "STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION");
}
public IQueryable GetTableData(SqlTable table)
{
var result = GetEnumerable().AsQueryable();
return result;
}

public (bool DatabaseServiced, IEnumerable<SqlTableInfo> Tables) GetTables(string database)
{
throw new NotImplementedException();
}
}
25 changes: 25 additions & 0 deletions tests/Grammars/MySQL.Tests/Utils/SqlGrammarMySQL.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Irony.Parsing;
using SqlBuildingBlocks.Interfaces;
using SqlBuildingBlocks.LogicalEntities;

namespace SqlBuildingBlocks.Grammars.MySQL.Tests.Utils;

public class SqlGrammarMySQL : Grammar
{
public SqlGrammarMySQL()
{
//MySQL has special naming rules for identifiers. (Note: the backtick)
//REF: https://dev.mysql.com/doc/refman/8.0/en/identifiers.html
SqlBuildingBlocks.Grammars.MySQL.SimpleId simpleId = new(this);
Id id = new(this, simpleId);

SqlBuildingBlocks.Grammars.MySQL.SelectStmt selectStmt = new(this, id);

selectStmt.Expr.InitializeRule(selectStmt, selectStmt.FuncCall);
Root = selectStmt;
}

public virtual SqlSelectDefinition Create(ParseTreeNode selectStmt, IDatabaseConnectionProvider databaseConnectionProvider, ITableSchemaProvider tableSchemaProvider, IFunctionProvider functionProvider) =>
((SelectStmt)Root).Create(selectStmt, databaseConnectionProvider, tableSchemaProvider, functionProvider);

}

0 comments on commit 4b86c00

Please sign in to comment.