Skip to content

Commit

Permalink
Merge pull request #554 from mk3008/553-proposal-improve-fluenttable-…
Browse files Browse the repository at this point in the history
…for-single-table-usage-to-reduce-redundancy

Enhance FluentTable with Improved Single Table Support
  • Loading branch information
mk3008 authored Oct 25, 2024
2 parents b7b554c + f0a8567 commit f7a4f72
Show file tree
Hide file tree
Showing 6 changed files with 209 additions and 6 deletions.
4 changes: 3 additions & 1 deletion src/Carbunql/Clauses/SelectableTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ public void SetAlias(string alias)
/// </summary>
public ValueCollection? ColumnAliases { get; init; }

public bool HideColumnAliases { get; internal set; } = false;

public CommentClause? CommentClause { get; set; }

public IEnumerable<Token> GetAliasTokens(Token? parent)
Expand Down Expand Up @@ -90,7 +92,7 @@ public virtual IEnumerable<Token> GetTokens(Token? parent)
yield return new Token(this, parent, Alias);
}

if (ColumnAliases != null)
if (ColumnAliases != null && HideColumnAliases == false)
{
var bracket = Token.ReservedBracketStart(this, parent);
yield return bracket;
Expand Down
40 changes: 37 additions & 3 deletions src/Carbunql/Fluent/FluentTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,29 @@ public static FluentTable Create(string query, IEnumerable<string> columnAliases
else
{
var t = TableParser.Parse(query);
return new FluentTable(t, columnAliases, cteName, alias);
if (t is PhysicalTable pt)
{
if (!string.IsNullOrEmpty(cteName))
{
var ft = Create(pt.GetTableFullName(), columnAliases, pt.GetDefaultName());
ft.HideColumnAliases = true;

var sq = new SelectQuery()
.From(ft);

return Create(sq, Enumerable.Empty<string>(), cteName, alias);

//return Create($"select {string.Join(",", columnAliases)} from {pt.GetTableFullName()}", Enumerable.Empty<string>(), cteName, alias);
}

//return new FluentTable(pt, columnAliases, cteName, alias);
return new FluentTable(pt, columnAliases, cteName, alias)
{
HideColumnAliases = true
};
}

throw new NotSupportedException();
}
}

Expand Down Expand Up @@ -128,6 +150,15 @@ public static FluentTable Create(string commandText, IEnumerable<string> columnN
/// </summary>
public IEnumerable<string> ColumnAliases { get; } = columnAliases;

/// <summary>
/// Determines whether column aliases should be hidden in the SQL output.
/// </summary>
/// <remarks>
/// When set to <c>true</c>, column aliases will be omitted from the generated SQL statements.
/// The default value is <c>false</c>, which includes column aliases in the SQL output.
/// </remarks>
public bool HideColumnAliases { get; private set; } = false;

/// <summary>
/// Gets the name of the Common Table Expression (CTE), if any.
/// </summary>
Expand Down Expand Up @@ -156,7 +187,7 @@ public CommonTable ToCommonTable()

var columnAliases = ColumnAliases.ToValueCollection();

if (ColumnAliases.Any())
if (ColumnAliases.Any() && HideColumnAliases == false)
{
return new CommonTable(Table, CteName, columnAliases)
{
Expand Down Expand Up @@ -184,7 +215,10 @@ public SelectableTable ToSelectable()
{
if (columnAliases.Any())
{
return new SelectableTable(Table, Alias, columnAliases);
return new SelectableTable(Table, Alias, columnAliases)
{
HideColumnAliases = HideColumnAliases
};
}
else
{
Expand Down
9 changes: 8 additions & 1 deletion src/Carbunql/SelectQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public IList<IQuerySource> GetQuerySources()
{
var commonTables = GetCommonTables().ToList();
var sources = new List<IQuerySource>();
var lst = CreateQuerySources(ref sources, commonTables, new Numbering(0));
CreateQuerySources(ref sources, commonTables, new Numbering(0));

return sources;
}
Expand Down Expand Up @@ -170,6 +170,13 @@ private IList<IQuerySource> CreateQuerySources(ref List<IQuerySource> sources, I
var qs = DisassembleQuerySources(ref sources, source, query, commonTables, numbering, SourceType.SubQuery);
currentSources.Add(qs);
}
else if (source.ColumnAliases != null && source.ColumnAliases.Any())
{
// If a column alias is present, no further parsing is done
var names = source.ColumnAliases.SelectMany(x => x.GetColumns()).Select(x => x.Column).ToHashSet();
var qs = new QuerySource(numbering.GetNext(), names, this, source, SourceType.PhysicalTable);
sources.Add(qs);
}
else if (source.Table is PhysicalTable table && commonTables.Any(x => x.Alias == table.GetTableFullName()))
{
// disassemble cte
Expand Down
12 changes: 11 additions & 1 deletion src/Carbunql/Tables/VirtualTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,17 @@ public override IEnumerable<QueryParameter> GetParameters()
/// <inheritdoc/>
public override IList<string> GetColumnNames()
{
if (Query is IReadQuery q)
if (Query is SelectQuery sq)
{
var s = sq.GetOrNewSelectQuery().SelectClause;
if (s == null)
{
var source = sq.GetQuerySources().Where(x => x.Query.Equals(sq)).First();
return source.ColumnNames.ToList();
}
return s.Select(x => x.Alias).ToList();
}
else if (Query is IReadQuery q)
{
var s = q.GetOrNewSelectQuery().SelectClause;
if (s == null) return base.GetColumnNames();
Expand Down
46 changes: 46 additions & 0 deletions test/Carbunql.Building.Test/ToCTETest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,29 @@ public void Old()

Monitor.Log(sq);

var expect = """
WITH
x AS (
SELECT
id,
val
FROM
table_a AS a
),
alias AS (
SELECT
x.id
FROM
x
)
SELECT
alias.id
FROM
alias
""";

Assert.Equal(expect, sq.ToText());

Assert.Equal(30, sq.GetTokens().ToList().Count);
}

Expand All @@ -42,6 +65,29 @@ public void Renew()

Monitor.Log(sq);

var expect = """
WITH
x AS (
SELECT
id,
val
FROM
table_a AS a
),
alias AS (
SELECT
x.id
FROM
x
)
SELECT
alias.id
FROM
alias
""";

Assert.Equal(expect, sq.ToText());

Assert.Equal(30, sq.GetTokens().ToList().Count);
}
}
104 changes: 104 additions & 0 deletions test/Carbunql.Fluent.Test/FluentTableTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -164,4 +164,108 @@ cte_v AS v

Assert.Equal(expect, sq.ToText());
}

[Fact]
public void SingleTableTest()
{
var a = FluentTable.Create("table_a", ["id", "value"], "a");

var sq = new SelectQuery()
.From(a)
.SelectAll(a);

Monitor.Log(sq);

var expect = """
SELECT
a.id,
a.value
FROM
table_a AS a
""";

Assert.Equal(expect, sq.ToText());
}

[Fact]
public void SingleTableCteTest_SelectAll()
{
var a = FluentTable.Create("table_a", ["id", "value"], "cte_a", "a");

var sq = new SelectQuery()
.From(a)
.SelectAll(a);

Monitor.Log(sq);

var expect = """
WITH
cte_a AS (
SELECT
*
FROM
table_a
)
SELECT
a.id,
a.value
FROM
cte_a AS a
""";

Assert.Equal(expect, sq.ToText());
}

[Fact]
public void SingleTableCteFilterTest()
{
var a = FluentTable.Create("table_a", ["id", "value"], "cte_a", "a");

var sq = new SelectQuery()
.From(a)
.Equal("id", 1);

Monitor.Log(sq);

var expect = """
WITH
cte_a AS (
SELECT
*
FROM
table_a
WHERE
table_a.id = 1
)
SELECT
*
FROM
cte_a AS a
""";

Assert.Equal(expect, sq.ToText());
}

[Fact]
public void SingleTableFilterTest()
{
var a = FluentTable.Create("table_a", ["id", "value"], "a");

var sq = new SelectQuery()
.From(a)
.Equal("id", 1);

Monitor.Log(sq);

var expect = """
SELECT
*
FROM
table_a AS a
WHERE
a.id = 1
""";

Assert.Equal(expect, sq.ToText());
}
}

0 comments on commit f7a4f72

Please sign in to comment.