From 1dd2d1ac1579e5486b5859cc833a44ace7618e9b Mon Sep 17 00:00:00 2001 From: Roman Artiukhin Date: Tue, 28 May 2019 17:14:27 +0300 Subject: [PATCH 1/5] Optimize usages of SqlString.Append --- src/NHibernate/Criterion/Distinct.cs | 5 ++--- src/NHibernate/Criterion/SubqueryProjection.cs | 2 +- src/NHibernate/Dialect/Oracle8iDialect.cs | 2 +- src/NHibernate/Dialect/PostgreSQL81Dialect.cs | 2 +- src/NHibernate/Dialect/PostgreSQLDialect.cs | 2 +- .../Driver/BasicResultSetsCommand.cs | 2 +- src/NHibernate/Engine/JoinSequence.cs | 2 +- .../ANTLR/Tree/EntityJoinJoinSequenceImpl.cs | 14 ++++++++------ src/NHibernate/Loader/JoinWalker.cs | 2 +- .../Loader/OuterJoinableAssociation.cs | 4 ++-- src/NHibernate/SqlCommand/SqlString.cs | 18 +++++++++++++++++- src/NHibernate/SqlCommand/SqlUpdateBuilder.cs | 2 +- 12 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/NHibernate/Criterion/Distinct.cs b/src/NHibernate/Criterion/Distinct.cs index 993f403167a..60adf13f4af 100644 --- a/src/NHibernate/Criterion/Distinct.cs +++ b/src/NHibernate/Criterion/Distinct.cs @@ -17,8 +17,7 @@ public Distinct(IProjection proj) public virtual SqlString ToSqlString(ICriteria criteria, int position, ICriteriaQuery criteriaQuery) { - return new SqlString("distinct ") - .Append(projection.ToSqlString(criteria, position, criteriaQuery)); + return new SqlString("distinct ", projection.ToSqlString(criteria, position, criteriaQuery)); } public virtual SqlString ToGroupSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery) @@ -77,4 +76,4 @@ public override string ToString() return "distinct " + projection.ToString(); } } -} \ No newline at end of file +} diff --git a/src/NHibernate/Criterion/SubqueryProjection.cs b/src/NHibernate/Criterion/SubqueryProjection.cs index c7a68afdbfc..763af33fc50 100644 --- a/src/NHibernate/Criterion/SubqueryProjection.cs +++ b/src/NHibernate/Criterion/SubqueryProjection.cs @@ -42,7 +42,7 @@ public override IType[] GetTypes(ICriteria criteria, ICriteriaQuery criteriaQuer public override SqlString ToSqlString(ICriteria criteria, int loc, ICriteriaQuery criteriaQuery) { return _subQuery.ToSqlString(criteria, criteriaQuery) - .Append(new SqlString(" as y", loc.ToString(), "_")); + .Append(" as y", loc.ToString(), "_"); } public override SqlString ToGroupSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery) diff --git a/src/NHibernate/Dialect/Oracle8iDialect.cs b/src/NHibernate/Dialect/Oracle8iDialect.cs index f3a943a3b8e..cdbf67a35d6 100644 --- a/src/NHibernate/Dialect/Oracle8iDialect.cs +++ b/src/NHibernate/Dialect/Oracle8iDialect.cs @@ -435,7 +435,7 @@ public override string GetSelectSequenceNextValString(string sequenceName) public override SqlString AddIdentifierOutParameterToInsert(SqlString insertString, string identifierColumnName, string parameterName) { - return insertString.Append(" returning " + identifierColumnName + " into :" + parameterName); + return insertString.Append(string.Concat(" returning ", identifierColumnName, " into :", parameterName)); } public override string GetCreateSequenceString(string sequenceName) diff --git a/src/NHibernate/Dialect/PostgreSQL81Dialect.cs b/src/NHibernate/Dialect/PostgreSQL81Dialect.cs index 81b062bafdd..a94ee56a60d 100644 --- a/src/NHibernate/Dialect/PostgreSQL81Dialect.cs +++ b/src/NHibernate/Dialect/PostgreSQL81Dialect.cs @@ -111,7 +111,7 @@ public override SqlString AppendIdentitySelectToInsert(SqlString insertSql) public override SqlString AppendIdentitySelectToInsert(SqlString insertString, string identifierColumnName) { - return insertString.Append(" returning ").Append(identifierColumnName); + return insertString.Append(" returning " + identifierColumnName); } public override bool SupportsInsertSelectIdentity diff --git a/src/NHibernate/Dialect/PostgreSQLDialect.cs b/src/NHibernate/Dialect/PostgreSQLDialect.cs index d1353bb037b..5cad0006cdd 100644 --- a/src/NHibernate/Dialect/PostgreSQLDialect.cs +++ b/src/NHibernate/Dialect/PostgreSQLDialect.cs @@ -177,7 +177,7 @@ public override string GetDropSequenceString(string sequenceName) public override SqlString AddIdentifierOutParameterToInsert(SqlString insertString, string identifierColumnName, string parameterName) { - return insertString.Append(" returning ").Append(identifierColumnName); + return insertString.Append(" returning " + identifierColumnName); } public override InsertGeneratedIdentifierRetrievalMethod InsertGeneratedIdentifierRetrievalMethod diff --git a/src/NHibernate/Driver/BasicResultSetsCommand.cs b/src/NHibernate/Driver/BasicResultSetsCommand.cs index 36e6a8a8485..4749f7cd9ce 100644 --- a/src/NHibernate/Driver/BasicResultSetsCommand.cs +++ b/src/NHibernate/Driver/BasicResultSetsCommand.cs @@ -32,7 +32,7 @@ public BasicResultSetsCommand(ISessionImplementor session) public virtual void Append(ISqlCommand command) { Commands.Add(command); - sqlString = sqlString.Append(command.Query).Append(_statementTerminator).Append(Environment.NewLine); + sqlString = sqlString.Append(command.Query, _statementTerminator, Environment.NewLine); } public bool HasQueries diff --git a/src/NHibernate/Engine/JoinSequence.cs b/src/NHibernate/Engine/JoinSequence.cs index 8d5a20b15ab..12520798f46 100644 --- a/src/NHibernate/Engine/JoinSequence.cs +++ b/src/NHibernate/Engine/JoinSequence.cs @@ -204,7 +204,7 @@ internal virtual JoinFragment ToJoinFragment( { if (join.Alias.Equals(withClauseJoinAlias)) { - condition = condition.Append(" and ").Append(withClauseFragment); + condition = condition.Append(" and ", withClauseFragment); } } diff --git a/src/NHibernate/Hql/Ast/ANTLR/Tree/EntityJoinJoinSequenceImpl.cs b/src/NHibernate/Hql/Ast/ANTLR/Tree/EntityJoinJoinSequenceImpl.cs index 21040c961bc..28276076e59 100644 --- a/src/NHibernate/Hql/Ast/ANTLR/Tree/EntityJoinJoinSequenceImpl.cs +++ b/src/NHibernate/Hql/Ast/ANTLR/Tree/EntityJoinJoinSequenceImpl.cs @@ -30,12 +30,14 @@ internal override JoinFragment ToJoinFragment( { var joinFragment = new ANSIJoinFragment(); - var on = withClauseFragment ?? new SqlString(); - var filters = _entityType.GetOnCondition(_tableAlias, Factory, enabledFilters); - if (!string.IsNullOrEmpty(filters)) - { - on.Append(" and ").Append(filters); - } + var on = withClauseFragment ?? SqlString.Empty; + //Note: filters logic commented as GetOnCondition always returns empty string for entity join (as IsReferenceToPrimaryKey is always true) + //TODO: If filters for entity join really make sense we need to inline GetOnCondition part that retrieves filters +// var filters = _entityType.GetOnCondition(_tableAlias, Factory, enabledFilters); +// if (!string.IsNullOrEmpty(filters)) +// { +// on = on.Append(filters); +// } joinFragment.AddJoin(_tableName, _tableAlias, Array.Empty(), Array.Empty(), _joinType, on); return joinFragment; } diff --git a/src/NHibernate/Loader/JoinWalker.cs b/src/NHibernate/Loader/JoinWalker.cs index 5e1398f4607..23aae65620b 100644 --- a/src/NHibernate/Loader/JoinWalker.cs +++ b/src/NHibernate/Loader/JoinWalker.cs @@ -805,7 +805,7 @@ protected SqlString MergeOrderings(SqlString ass, SqlString orderBy) else if (orderBy.Length == 0) return ass; else - return ass.Append(StringHelper.CommaSpace).Append(orderBy); + return ass.Append(StringHelper.CommaSpace, orderBy); } protected SqlString MergeOrderings(string ass, SqlString orderBy) { diff --git a/src/NHibernate/Loader/OuterJoinableAssociation.cs b/src/NHibernate/Loader/OuterJoinableAssociation.cs index 106ef7dd067..a5c52587e23 100644 --- a/src/NHibernate/Loader/OuterJoinableAssociation.cs +++ b/src/NHibernate/Loader/OuterJoinableAssociation.cs @@ -49,7 +49,7 @@ public OuterJoinableAssociation(IAssociationType joinableType, String lhsAlias, rhsColumns = JoinHelper.GetRHSColumnNames(joinableType, factory); on = new SqlString(joinableType.GetOnCondition(rhsAlias, factory, enabledFilters)); if (SqlStringHelper.IsNotEmpty(withClause)) - on = on.Append(" and ( ").Append(withClause).Append(" )"); + on = on.Append(" and ( ", withClause, " )"); this.enabledFilters = enabledFilters; // needed later for many-to-many/filter application } @@ -166,7 +166,7 @@ public void AddManyToManyJoin(JoinFragment outerjoin, IQueryableCollection colle SqlString condition = string.Empty.Equals(manyToManyFilter) ? on : SqlStringHelper.IsEmpty(on) ? new SqlString(manyToManyFilter) : - on.Append(" and ").Append(manyToManyFilter); + on.Append(" and ", manyToManyFilter); outerjoin.AddJoin(joinable.TableName, rhsAlias, lhsColumns, rhsColumns, joinType, condition); outerjoin.AddJoins(joinable.FromJoinFragment(rhsAlias, false, true), diff --git a/src/NHibernate/SqlCommand/SqlString.cs b/src/NHibernate/SqlCommand/SqlString.cs index 71870969fa5..86aeb3bbc41 100644 --- a/src/NHibernate/SqlCommand/SqlString.cs +++ b/src/NHibernate/SqlCommand/SqlString.cs @@ -347,7 +347,23 @@ public SqlString Append(string text) { if (string.IsNullOrEmpty(text)) return this; if (_length == 0) return new SqlString(text); - return new SqlString(new object[] { this, text }); + return new SqlString(this, text); + } + + public SqlString Append(params object[] parts) + { + return _length == 0 + ? new SqlString(parts) + : new SqlString(GetAppendParts(parts)); + } + + private IEnumerable GetAppendParts(object[] parts) + { + yield return this; + foreach (var part in parts) + { + yield return part; + } } /// diff --git a/src/NHibernate/SqlCommand/SqlUpdateBuilder.cs b/src/NHibernate/SqlCommand/SqlUpdateBuilder.cs index def92f8fe50..809b22ee0d8 100644 --- a/src/NHibernate/SqlCommand/SqlUpdateBuilder.cs +++ b/src/NHibernate/SqlCommand/SqlUpdateBuilder.cs @@ -134,7 +134,7 @@ private void AddColumnWithValueOrType(string columnName, object valueOrType) public SqlUpdateBuilder AppendAssignmentFragment(SqlString fragment) { // SqlString is immutable - assignments = assignments == null ? fragment : assignments.Append(", ").Append(fragment); + assignments = assignments == null ? fragment : assignments.Append(", ", fragment); return this; } From 291a05b16337b44eabee9c89a0f2a4f2bd825b20 Mon Sep 17 00:00:00 2001 From: Roman Artiukhin Date: Tue, 28 May 2019 18:51:59 +0300 Subject: [PATCH 2/5] Revert useless change --- src/NHibernate/Dialect/Oracle8iDialect.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NHibernate/Dialect/Oracle8iDialect.cs b/src/NHibernate/Dialect/Oracle8iDialect.cs index cdbf67a35d6..f3a943a3b8e 100644 --- a/src/NHibernate/Dialect/Oracle8iDialect.cs +++ b/src/NHibernate/Dialect/Oracle8iDialect.cs @@ -435,7 +435,7 @@ public override string GetSelectSequenceNextValString(string sequenceName) public override SqlString AddIdentifierOutParameterToInsert(SqlString insertString, string identifierColumnName, string parameterName) { - return insertString.Append(string.Concat(" returning ", identifierColumnName, " into :", parameterName)); + return insertString.Append(" returning " + identifierColumnName + " into :" + parameterName); } public override string GetCreateSequenceString(string sequenceName) From df066432cff88527592ae1ae4a4d2127e7c86f53 Mon Sep 17 00:00:00 2001 From: Roman Artiukhin Date: Mon, 3 Jun 2019 12:24:57 +0300 Subject: [PATCH 3/5] Addressed comments and small refactoring --- src/NHibernate/Dialect/PostgreSQL81Dialect.cs | 2 +- src/NHibernate/Dialect/PostgreSQLDialect.cs | 2 +- src/NHibernate/Driver/BasicResultSetsCommand.cs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NHibernate/Dialect/PostgreSQL81Dialect.cs b/src/NHibernate/Dialect/PostgreSQL81Dialect.cs index a94ee56a60d..77953561029 100644 --- a/src/NHibernate/Dialect/PostgreSQL81Dialect.cs +++ b/src/NHibernate/Dialect/PostgreSQL81Dialect.cs @@ -111,7 +111,7 @@ public override SqlString AppendIdentitySelectToInsert(SqlString insertSql) public override SqlString AppendIdentitySelectToInsert(SqlString insertString, string identifierColumnName) { - return insertString.Append(" returning " + identifierColumnName); + return insertString.Append(" returning ", identifierColumnName); } public override bool SupportsInsertSelectIdentity diff --git a/src/NHibernate/Dialect/PostgreSQLDialect.cs b/src/NHibernate/Dialect/PostgreSQLDialect.cs index 5cad0006cdd..b81c2df86a8 100644 --- a/src/NHibernate/Dialect/PostgreSQLDialect.cs +++ b/src/NHibernate/Dialect/PostgreSQLDialect.cs @@ -177,7 +177,7 @@ public override string GetDropSequenceString(string sequenceName) public override SqlString AddIdentifierOutParameterToInsert(SqlString insertString, string identifierColumnName, string parameterName) { - return insertString.Append(" returning " + identifierColumnName); + return insertString.Append(" returning ", identifierColumnName); } public override InsertGeneratedIdentifierRetrievalMethod InsertGeneratedIdentifierRetrievalMethod diff --git a/src/NHibernate/Driver/BasicResultSetsCommand.cs b/src/NHibernate/Driver/BasicResultSetsCommand.cs index 4749f7cd9ce..748698adfa8 100644 --- a/src/NHibernate/Driver/BasicResultSetsCommand.cs +++ b/src/NHibernate/Driver/BasicResultSetsCommand.cs @@ -22,7 +22,7 @@ public BasicResultSetsCommand(ISessionImplementor session) { Commands = new List(); Session = session; - _statementTerminator = session.Factory.Dialect.StatementTerminator.ToString(); + _statementTerminator = session.Factory.Dialect.StatementTerminator.ToString() + Environment.NewLine; } protected List Commands { get; private set; } @@ -32,7 +32,7 @@ public BasicResultSetsCommand(ISessionImplementor session) public virtual void Append(ISqlCommand command) { Commands.Add(command); - sqlString = sqlString.Append(command.Query, _statementTerminator, Environment.NewLine); + sqlString = sqlString.Append(command.Query, _statementTerminator); } public bool HasQueries From f026d161d9f81b7bfcf8f4efc88c4ab4263cbac9 Mon Sep 17 00:00:00 2001 From: Roman Artiukhin Date: Thu, 13 Jun 2019 07:38:22 +0300 Subject: [PATCH 4/5] Adjust comment --- .../Hql/Ast/ANTLR/Tree/EntityJoinJoinSequenceImpl.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/NHibernate/Hql/Ast/ANTLR/Tree/EntityJoinJoinSequenceImpl.cs b/src/NHibernate/Hql/Ast/ANTLR/Tree/EntityJoinJoinSequenceImpl.cs index 28276076e59..99d7d69e54b 100644 --- a/src/NHibernate/Hql/Ast/ANTLR/Tree/EntityJoinJoinSequenceImpl.cs +++ b/src/NHibernate/Hql/Ast/ANTLR/Tree/EntityJoinJoinSequenceImpl.cs @@ -31,12 +31,14 @@ internal override JoinFragment ToJoinFragment( var joinFragment = new ANSIJoinFragment(); var on = withClauseFragment ?? SqlString.Empty; - //Note: filters logic commented as GetOnCondition always returns empty string for entity join (as IsReferenceToPrimaryKey is always true) - //TODO: If filters for entity join really make sense we need to inline GetOnCondition part that retrieves filters + //Note: filters logic commented due to following issues + //1) Original code is non functional as SqlString is immutable and so all Append results are lost. Correct code would look like: on = on.Append(filters); + //2) Also it seems GetOnCondition always returns empty string for entity join (as IsReferenceToPrimaryKey is always true). + // So if filters for entity join really make sense we need to inline GetOnCondition part that retrieves filters // var filters = _entityType.GetOnCondition(_tableAlias, Factory, enabledFilters); // if (!string.IsNullOrEmpty(filters)) // { -// on = on.Append(filters); +// on.Append(" and ").Append(filters); // } joinFragment.AddJoin(_tableName, _tableAlias, Array.Empty(), Array.Empty(), _joinType, on); return joinFragment; From 7f8b2d2e0bfa5a912423e7e239d8c67f7471eaf1 Mon Sep 17 00:00:00 2001 From: Alexander Zaytsev Date: Thu, 11 Jul 2019 23:17:18 +1200 Subject: [PATCH 5/5] Optimize one more append --- src/NHibernate/Criterion/Order.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/NHibernate/Criterion/Order.cs b/src/NHibernate/Criterion/Order.cs index 6f1e466a0e7..de1bc797257 100644 --- a/src/NHibernate/Criterion/Order.cs +++ b/src/NHibernate/Criterion/Order.cs @@ -40,12 +40,9 @@ public virtual SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteria { if (projection != null) { - SqlString sb = SqlString.Empty; - SqlString produced = this.projection.ToSqlString(criteria, 0, criteriaQuery); + SqlString produced = projection.ToSqlString(criteria, 0, criteriaQuery); SqlString truncated = SqlStringHelper.RemoveAsAliasesFromSql(produced); - sb = sb.Append(truncated); - sb = sb.Append(ascending ? " asc" : " desc"); - return sb; + return new SqlString(truncated, ascending ? " asc" : " desc"); } string[] columns = criteriaQuery.GetColumnAliasesUsingProjection(criteria, propertyName);