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

Simplify handling of lazy property groups #2239

Closed
wants to merge 4 commits into from
Closed
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
7 changes: 4 additions & 3 deletions src/NHibernate/Hql/Ast/ANTLR/Tree/FromElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -337,9 +337,10 @@ public string RenderIdentifierSelect(int size, int k)
/// <returns>the property select SQL fragment.</returns>
public string RenderPropertySelect(int size, int k)
{
return IsAllPropertyFetch
? _elementType.RenderPropertySelect(size, k, IsAllPropertyFetch)
: _elementType.RenderPropertySelect(size, k, _fetchLazyProperties);
return _elementType.RenderPropertySelect(
size,
k,
IsAllPropertyFetch || _fetchLazyProperties?.Contains(TableAlias) == true);
}

public override SqlString RenderText(Engine.ISessionFactoryImplementor sessionFactory)
Expand Down
22 changes: 4 additions & 18 deletions src/NHibernate/Hql/Ast/ANTLR/Tree/FromElementType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -195,31 +195,17 @@ public virtual string RenderScalarIdentifierSelect(int i)
/// </summary>
/// <param name="size">The total number of returned types.</param>
/// <param name="k">The sequence of the current returned type.</param>
/// <param name="allProperties"></param>
/// <param name="fetch"></param>
/// <returns>the property select SQL fragment.</returns>
public string RenderPropertySelect(int size, int k, bool allProperties)
{
return RenderPropertySelect(size, k, null, allProperties);
}

public string RenderPropertySelect(int size, int k, string[] fetchLazyProperties)
{
return RenderPropertySelect(size, k, fetchLazyProperties, false);
}

private string RenderPropertySelect(int size, int k, string[] fetchLazyProperties, bool allProperties)
public string RenderPropertySelect(int size, int k, bool fetch)
{
CheckInitialized();

var queryable = Queryable;
if (queryable == null)
return "";
return string.Empty;

// Use the old method when fetchProperties is null to prevent any breaking changes
// 6.0 TODO: simplify condition by removing the fetchProperties part
string fragment = fetchLazyProperties == null || allProperties
? queryable.PropertySelectFragment(TableAlias, GetSuffix(size, k), allProperties)
: queryable.PropertySelectFragment(TableAlias, GetSuffix(size, k), fetchLazyProperties);
var fragment = queryable.PropertySelectFragment(TableAlias, GetSuffix(size, k), fetch);

return TrimLeadingCommaAndSpaces(fragment);
}
Expand Down
43 changes: 4 additions & 39 deletions src/NHibernate/Persister/Entity/AbstractEntityPersister.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1636,54 +1636,19 @@ public virtual string IdentifierSelectFragment(string name, string suffix)
.ToSqlStringFragment(false);
}

public string PropertySelectFragment(string name, string suffix, bool allProperties)
public string PropertySelectFragment(string name, string suffix, bool fetch)
{
return PropertySelectFragment(name, suffix, null, allProperties);
}

public string PropertySelectFragment(string name, string suffix, string[] fetchProperties)
{
return PropertySelectFragment(name, suffix, fetchProperties, false);
}

private string PropertySelectFragment(string name, string suffix, string[] fetchProperties, bool allProperties)
{
SelectFragment select = new SelectFragment(Factory.Dialect)
var select = new SelectFragment(Factory.Dialect)
.SetSuffix(suffix)
.SetUsedAliases(IdentifierAliases);

int[] columnTableNumbers = SubclassColumnTableNumberClosure;
string[] columnAliases = SubclassColumnAliasClosure;
string[] columns = SubclassColumnClosure;
HashSet<string> fetchColumnsAndFormulas = null;
Copy link
Member Author

@hazzik hazzik Oct 6, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my mind fetchColumnsAndFormulas?.Contains(column[i]) == true is equivalent to fetchProperties?.Contains(name) == true.

if (fetchProperties != null)
{
fetchColumnsAndFormulas = new HashSet<string>();
foreach (var fetchProperty in fetchProperties)
{
var index = GetSubclassPropertyIndex(fetchProperty);
if (index < 0)
{
throw new InvalidOperationException($"Property {fetchProperty} does not exist on entity {EntityName}");
}

var columnNames = SubclassPropertyColumnNameClosure[index];
// Formulas will have all null values
if (columnNames.All(o => o == null))
{
columnNames = SubclassPropertyFormulaTemplateClosure[index];
}

foreach (var columnName in columnNames)
{
fetchColumnsAndFormulas.Add(columnName);
}
}
}

for (int i = 0; i < columns.Length; i++)
{
bool selectable = (allProperties || !subclassColumnLazyClosure[i] || fetchColumnsAndFormulas?.Contains(columns[i]) == true) &&
bool selectable = (fetch || !subclassColumnLazyClosure[i]) &&
!IsSubclassTableSequentialSelect(columnTableNumbers[i]) &&
subclassColumnSelectableClosure[i];
if (selectable)
Expand All @@ -1698,7 +1663,7 @@ private string PropertySelectFragment(string name, string suffix, string[] fetch
string[] formulaAliases = SubclassFormulaAliasClosure;
for (int i = 0; i < formulaTemplates.Length; i++)
{
bool selectable = (allProperties || !subclassFormulaLazyClosure[i] || fetchColumnsAndFormulas?.Contains(formulaTemplates[i]) == true) &&
bool selectable = (fetch || !subclassFormulaLazyClosure[i]) &&
!IsSubclassTableSequentialSelect(formulaTableNumbers[i]);
if (selectable)
{
Expand Down
13 changes: 0 additions & 13 deletions src/NHibernate/Persister/Entity/IQueryable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,6 @@ public enum Declarer
SuperClass
}

internal static class AbstractEntityPersisterExtensions
{
/// <summary>
/// Given a query alias and an identifying suffix, render the property select fragment.
/// </summary>
//6.0 TODO: Merge into IQueryable
public static string PropertySelectFragment(this IQueryable query, string alias, string suffix, string[] fetchProperties)
{
return ReflectHelper.CastOrThrow<AbstractEntityPersister>(query, "individual lazy property fetches")
.PropertySelectFragment(alias, suffix, fetchProperties);
}
}

/// <summary>
/// Extends the generic <c>ILoadable</c> contract to add operations required by HQL
/// </summary>
Expand Down