Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[QP-6630] Where절에서 사용한 컬럼에 대한 정보를 제공합니다. #82

Merged
merged 5 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Qsi.Debugger/MainWindow.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@
<Rectangle Margin="0,6" Fill="{DynamicResource ThemeBackgroundBrush}" Height="2" />
</TreeDataTemplate>

<TreeDataTemplate DataType="md:QsiLabelTreeItem">
<TextBlock Foreground="LightGray" Text="{Binding Label}"></TextBlock>
</TreeDataTemplate>

<TreeDataTemplate DataType="md:QsiColumnTreeItem" ItemsSource="{Binding Items}">
<StackPanel Orientation="Horizontal">
<TextBlock Foreground="{Binding Converter={cvt:ColumnBrushConverter}}"
Expand Down
9 changes: 8 additions & 1 deletion Qsi.Debugger/MainWindow.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -457,9 +457,16 @@ private void BuildQsiTableTree(IList<QsiTableStructure> tables)
items.Add(new QsiSplitTreeItem());

items.AddRange(tables[i].Columns.Select(c => new QsiColumnTreeItem(c)));

// Indirect columns
if (tables[i].IndirectColumns is not { } indirectColumns)
continue;

items.Add(new QsiLabelTreeItem("Indirect Columns"));
items.AddRange(indirectColumns.Select(c => new QsiColumnTreeItem(c)));
}

_tvResult.Items = items;
}
#endregion
}
}
11 changes: 11 additions & 0 deletions Qsi.Debugger/Models/QsiLabelTreeItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Qsi.Debugger.Models;

public class QsiLabelTreeItem
{
public string Label { get; }

public QsiLabelTreeItem(string label)
{
Label = label;
}
}
4 changes: 3 additions & 1 deletion Qsi/Analyzers/Table/Context/TableCompileContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public sealed class TableCompileContext : AnalyzerContextWrapper, IDisposable

public List<QsiTableStructure> JoinedSouceTables { get; }

public bool IsIndirectSource { get; set; }

private readonly List<QsiTableStructure> _directives;
private Stack<QsiQualifiedIdentifier> _identifierScope;

Expand Down Expand Up @@ -109,4 +111,4 @@ void IDisposable.Dispose()
_identifierScope?.Clear();
JoinedSouceTables.Clear();
}
}
}
33 changes: 33 additions & 0 deletions Qsi/Analyzers/Table/QsiTableAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,34 @@ table.Parent is IQsiDerivedColumnNode &&
}
}

scopedContext.IsIndirectSource = true;
declaredTable.IndirectColumns = GetIndirectColumns(scopedContext, table).ToArray() ?? Array.Empty<QsiTableColumn>();
scopedContext.IsIndirectSource = false;

return declaredTable;
}

private IEnumerable<QsiTableColumn> GetIndirectColumns(TableCompileContext context, IQsiDerivedTableNode table)
{
// Indirect columns from sources
foreach (var t in context.GetAllSourceTables())
{
if (t.IndirectColumns is not { } indirectColumns)
continue;

foreach (var c in indirectColumns)
yield return c;
}

if (table.Where is not { } where)
yield break;

IEnumerable<QsiTableColumn> columns = ResolveColumnsInExpression(context, where.Expression);

foreach (var c in columns)
yield return c;
}

protected virtual QsiIdentifier ResolveCompoundColumnName(TableCompileContext context, IQsiDerivedTableNode table, IQsiColumnNode column, QsiTableColumn refColumn)
{
return refColumn.Name;
Expand Down Expand Up @@ -951,12 +976,20 @@ protected virtual IEnumerable<QsiTableColumn> ResolveColumnsInExpression(TableCo

case IQsiTableExpressionNode e:
{
var isIndirectSource = context.IsIndirectSource;

using var scopedContext = new TableCompileContext(context);
var structure = BuildTableStructure(scopedContext, e.Table).Result;

foreach (var c in structure.Columns)
yield return c;

if (!isIndirectSource)
break;

foreach (var c in structure.IndirectColumns)
yield return c;

break;
}

Expand Down
18 changes: 16 additions & 2 deletions Qsi/Data/Table/QsiTableStructure.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using Qsi.Shared.Extensions;

Expand All @@ -18,6 +19,17 @@ public sealed class QsiTableStructure

public IList<QsiTableColumn> Columns => _columns;

/// <summary>
/// 테이블을 직접적으로 구성하는 컬럼이 아닌 간접적으로 참조하는 컬럼을 의미합니다.
/// </summary>
/// <remarks>
/// <ul>
/// <li>WHERE문이나 HAVING문의 조건에서 사용하는 컬럼이나, 서브쿼리 내에 들어 있는 컬럼 등을 포함합니다.</li>
/// <li>주석 작성일 기준으로 해당 필드의 값은 WHERE절 내부에서 사용하는 컬럼들만 포함하고 있습니다.</li>
/// </ul>
/// </remarks>
public QsiTableColumn[] IndirectColumns = Array.Empty<QsiTableColumn>();

internal IEnumerable<QsiTableColumn> VisibleColumns => _columns.Where(c => c.IsVisible);

private readonly QsiTableColumnCollection _columns;
Expand Down Expand Up @@ -46,6 +58,7 @@ public QsiTableStructure Clone()

table.References.AddRange(References);
table._columns.AddRange(_columns.Select(c => c.CloneInternal()));
table.IndirectColumns = (QsiTableColumn[])IndirectColumns.Clone();

return table;
}
Expand All @@ -62,7 +75,8 @@ public QsiTableStructure CloneVisibleOnly()

table.References.AddRange(References);
table._columns.AddRange(VisibleColumns.Select(c => c.CloneInternal()));
table.IndirectColumns = (QsiTableColumn[])IndirectColumns.Clone();

return table;
}
}
}
Loading