diff --git a/Orm/Xtensive.Orm.Tests.Core/Collections/PriorityQueueTest.cs b/Orm/Xtensive.Orm.Tests.Core/Collections/PriorityQueueTest.cs deleted file mode 100644 index 6e728f2398..0000000000 --- a/Orm/Xtensive.Orm.Tests.Core/Collections/PriorityQueueTest.cs +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (C) 2003-2010 Xtensive LLC. -// All rights reserved. -// For conditions of distribution and use, see license. -// Created by: Alex Gamzov -// Created: 2007.06.15 - -using System; -using NUnit.Framework; -using Xtensive.Collections; -using Xtensive.Core; - - -namespace Xtensive.Orm.Tests.Core.Collections -{ - [TestFixture] - public class PriorityQueueTest - { - [Test] - public void FastEnqueeDequeTest() - { - PriorityQueue pq = new PriorityQueue(); - int count = 10000; - using (new Measurement("Fast Enqueue test", count)) { - for (int i = 0; i < count; i++) - { - pq.Enqueue(DateTime.Now.ToString(), Guid.NewGuid().ToString()); - } - } - Assert.AreEqual(pq.Count, count); - using (new Measurement("Fast Dequeue test", count)) { - while (pq.Count > 0) - pq.Dequeue(); - } - } - - [Test] - public void EnqueueDequeTest() - { - PriorityQueue pqAsc = new PriorityQueue(Direction.Negative); - for (int i = 0; i < 10000; i++) - { - string data = Guid.NewGuid().ToString(); - pqAsc.Enqueue(data, data); - } - for (int i = 0; i < pqAsc.Count - 1; i++) - { - Assert.Greater(pqAsc[i], pqAsc[i + 1]); - } - - PriorityQueue pqDesc = new PriorityQueue(Direction.Positive); - for (int i = 0; i < 10000; i++) - { - string data = Guid.NewGuid().ToString(); - pqDesc.Enqueue(data, data); - } - for (int i = 0; i < pqDesc.Count - 1; i++) - { - Assert.Less(pqDesc[i], pqDesc[i + 1]); - } - - } - - [Test] - public void RemoveTest() - { - PriorityQueue pq = new PriorityQueue(); - string item = "item"; - Assert.Throws(() => { - pq.Enqueue("1", "s1"); - pq.Enqueue(item, "s2"); - pq.Enqueue("3", "s3"); - pq.Remove("fff"); - }); - } - - [Test] - public void DequeRangeTest() - { - PriorityQueue pq = new PriorityQueue(Direction.Positive); - pq.Enqueue("item1.1", "s1"); - pq.Enqueue("item1.2", "s1"); - pq.Enqueue("item2.1", "s2"); - pq.Enqueue("item2.2", "s2"); - pq.Enqueue("item3", "s3"); - string[] result = pq.DequeueRange("s2"); - Assert.AreEqual(5, pq.Count + result.Length); - Assert.AreEqual(4, result.Length); - - PriorityQueue pqDesc = new PriorityQueue(Direction.Negative); - pqDesc.Enqueue("item1.1", "s1"); - pqDesc.Enqueue("item1.2", "s1"); - pqDesc.Enqueue("item2.1", "s2"); - pqDesc.Enqueue("item2.2", "s2"); - pqDesc.Enqueue("item3", "s3"); - string[] resultDesc = pqDesc.DequeueRange("s2"); - Assert.AreEqual(5, pqDesc.Count + resultDesc.Length); - Assert.AreEqual(3, resultDesc.Length); - } - } -} \ No newline at end of file diff --git a/Orm/Xtensive.Orm/Collections/PriorityQueue.cs b/Orm/Xtensive.Orm/Collections/PriorityQueue.cs deleted file mode 100644 index 6a9a3321d5..0000000000 --- a/Orm/Xtensive.Orm/Collections/PriorityQueue.cs +++ /dev/null @@ -1,359 +0,0 @@ -// Copyright (C) 2003-2010 Xtensive LLC. -// All rights reserved. -// For conditions of distribution and use, see license. -// Created by: Alex Gamzov -// Created: 2007.06.13 - -using System; -using System.Collections.Generic; -using System.Collections; -using System.Diagnostics; -using System.Runtime.Serialization; -using System.Security; -using System.Security.Permissions; -using Xtensive.Comparison; -using Xtensive.Core; - - - -namespace Xtensive.Collections -{ - /// - /// Priority queue. - /// - /// of objects to be stored in queue. - /// of priority value. - [Serializable] - [DebuggerDisplay("Count = {Count}")] - public class PriorityQueue : IPriorityQueue, - ISerializable - where TPriority: IComparable - { - // Consts - private const int minimalCapacity = 16; - private const float defaultGrowFactor = 1.4f; - private const float trimThresholdFactor = 0.9f; - - // Fields - [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] - private Pair[] items; // Actual data buffer - private int version; // Version to detect consistency while enumeration executes - [DebuggerBrowsable(DebuggerBrowsableState.Never)] - private int count; // Count of items in queue - private readonly float growFactor = defaultGrowFactor; - [DebuggerBrowsable(DebuggerBrowsableState.Never)] - private readonly Direction direction; - private readonly PriorityQueueItemComparer comparer; - - #region IPriorityQueue Members - - /// - public int Capacity - { - [DebuggerStepThrough] - get { - return items.Length; - } - set { - if (value != items.Length) { - if (value < count) - throw new ArgumentOutOfRangeException("value", Strings.ExInvalidCapacity); - if (value < minimalCapacity) { - value = minimalCapacity; - } - Pair[] newItems = new Pair[value]; - Array.Copy(items, newItems, Count); - items = newItems; - version++; - } - } - } - - /// - public Direction Direction - { - [DebuggerStepThrough] - get { return direction; } - } - - /// - public long Count - { - [DebuggerStepThrough] - get { return count; } - } - - /// - public T this[int index] - { - get { - if (index < 0) - throw new ArgumentOutOfRangeException(Strings.ExArgumentValueMustBeGreaterThanOrEqualToZero); - if (index >= count) - throw new ArgumentOutOfRangeException(string.Format(Strings.ExIndexShouldBeInNMRange, 0, count-1)); - return items[count-index-1].First; - } - } - - /// - public bool Contains(T item) - { - Predicate> predicate = GetEqualityPredicate(item); - return Array.FindIndex(items, 0, count, predicate) >= 0; - } - - /// - public void Remove(T item) - { - Predicate> predicate = GetEqualityPredicate(item); - int index = Array.FindIndex(items, 0, count, predicate); - if (index<0) { - throw new InvalidOperationException(Strings.ExItemNotFound); - } - Array.Copy(items, index+1, items, index, count-index-1); - Array.Clear(items, count-1, 1); - count--; - } - - /// - public void TrimExcess() - { - int trimThreshold = (int)(items.Length * trimThresholdFactor); - if (count < trimThreshold) - Capacity = count; - } - - /// - public void Clear() - { - int capacity = items.Length; - Array.Clear(items, 0, capacity); - count = 0; - version++; - } - - /// - public void Enqueue(T item, TPriority priority) - { - int insertIndex = GetIndex(item, priority); - EnsureCapacity((int) (Count+1)); - if (insertIndex < Count) - { - Array.Copy(items, insertIndex, items, insertIndex + 1, Count - insertIndex); - } - items[insertIndex] = new Pair(item, priority); - count++; - version++; - } - - /// - public T Dequeue() - { - if (Count == 0){ - throw new InvalidOperationException(Strings.ExCollectionIsEmpty); - } - T result = items[Count - 1].First; - Array.Clear(items, (int) (Count - 1), 1); - count--; - TrimExcess(); - version++; - return result; - } - - /// - public T[] DequeueRange(TPriority priority) - { - int index = GetIndex(default(T), priority); - if (index < count){ - T[] result = new T[count - index]; - for (int i = index; i < count;i++ ) { - result[i - index] = items[i].First; - } - Array.Clear(items, index, count-index); - count = index; - return result; - } - else { - return new T[0]; - } - - } - - /// - public T Peek() - { - if (Count==0) { - throw new InvalidOperationException(Strings.ExCollectionIsEmpty); - } - version++; - return items[Count - 1].First; - } - - #endregion - - #region IEnumerable<...> Members - - /// - [DebuggerStepThrough] - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - /// - public IEnumerator GetEnumerator() - { - int initialVersion = version; - for (int i = 0; i < Count;i++ ) { - if (version != initialVersion) - throw new InvalidOperationException(Strings.ExCollectionHasBeenChanged); - yield return items[i].First; - } - } - - #endregion - - #region ICloneable Members - - /// - public object Clone() - { - return new PriorityQueue(this); - } - - #endregion - - #region Private \ internal members - - private int GetIndex(T item, TPriority priority) - { - Pair element = new Pair(item, priority); - int insertIndex = Array.BinarySearch(items, 0, (int)Count, element, comparer); - if (insertIndex < 0) { - insertIndex ^= -1; - } - while (insertIndex < Count && insertIndex > 0 && comparer.Compare(items[insertIndex-1], element) == 0) - { - insertIndex--; - } - return insertIndex; - } - - private static Predicate> GetEqualityPredicate(T item) - { - return delegate(Pair innerItem) - { - return AdvancedComparerStruct.System.Equals(innerItem.First, item); - }; - } - - private void EnsureCapacity(int requiredCapacity) - { - int currentCapacity = items.Length; - if (currentCapacity < requiredCapacity) - { - int newCapacity = currentCapacity == 0 - ? minimalCapacity - : Convert.ToInt32(currentCapacity * growFactor); - if (newCapacity < requiredCapacity) - newCapacity = requiredCapacity; - Capacity = newCapacity; - } - } - - #endregion - - - // Constructors - - private PriorityQueue(PriorityQueue source) - { - items = new Pair[source.Count]; - Array.Copy(source.items, items, source.Count); - count = items.Length; - direction = source.direction; - } - - /// - /// Initializes new instance of this type. - /// - public PriorityQueue() - : this(Direction.Positive) - { - } - - /// - /// Initializes new instance of this type. - /// - /// Initial property value. - public PriorityQueue(Direction direction) - : this(direction, minimalCapacity) - { - } - - - /// - /// Initializes new instance of this type. - /// - /// Initial property value. - /// Initial property value. - public PriorityQueue(Direction direction, int initialCapacity) - : this(direction, initialCapacity, defaultGrowFactor) - { - } - - /// - /// Initializes new instance of this type. - /// - /// Initial property value. - /// Initial property value. - /// Capacity grow factor. - public PriorityQueue(Direction direction, int initialCapacity, float growFactor) - { - if (direction==Direction.None) - throw Exceptions.InvalidArgument(direction, "direction"); - this.direction = direction; - if (initialCapacity < minimalCapacity) { - initialCapacity = minimalCapacity; - } - items = new Pair[initialCapacity]; - count = 0; - this.growFactor = growFactor; - comparer = new PriorityQueueItemComparer(direction); - } - - #region ISerializable Members - - /// - /// Serializes instance of this type. - /// - /// - /// - [SecurityCritical] - public virtual void GetObjectData(SerializationInfo info, StreamingContext context) - { - Pair[] arrItems = new Pair[count]; - Array.Copy(items, arrItems, count); - info.AddValue("Items", arrItems); - info.AddValue("GrowFactor", growFactor); - info.AddValue("Direction", direction); - } - - /// - /// Deserializes instance of this type. - /// - /// - /// - protected PriorityQueue(SerializationInfo info, StreamingContext context) - { - items = (Pair[])info.GetValue("Items", typeof(Pair[])); - growFactor = info.GetSingle("GrowFactor"); - direction = (Direction)info.GetValue("Direction", typeof(Direction)); - if (direction==Direction.None) - throw Exceptions.InvalidArgument(direction, "direction"); - count = items.Length; - } - - #endregion - } -} \ No newline at end of file diff --git a/Orm/Xtensive.Orm/Orm/Building/Builders/AttributeProcessor.cs b/Orm/Xtensive.Orm/Orm/Building/Builders/AttributeProcessor.cs index c6a24c455e..645331f053 100644 --- a/Orm/Xtensive.Orm/Orm/Building/Builders/AttributeProcessor.cs +++ b/Orm/Xtensive.Orm/Orm/Building/Builders/AttributeProcessor.cs @@ -471,7 +471,7 @@ private LambdaExpression GetExpressionFromProvider(Type providerType, string pro string.Format(Strings.ExMemberXShouldReturnValueThatIsAssignableToLambdaExpression, memberName)); } - var expression = (LambdaExpression) method.Invoke(null, new object[0]); + var expression = (LambdaExpression) method.Invoke(null, Array.Empty()); if (expression.Parameters.Count != 1 || !expression.Parameters[0].Type.IsAssignableFrom(parameterType)) { throw new DomainBuilderException(string.Format( Strings.ExLambdaExpressionReturnedByXShouldTakeOneParameterOfTypeYOrAnyBaseTypeOfIt, memberName, diff --git a/Orm/Xtensive.Orm/Orm/Linq/ExpressionExtensions.cs b/Orm/Xtensive.Orm/Orm/Linq/ExpressionExtensions.cs index 9da5e7637d..96179b1fba 100644 --- a/Orm/Xtensive.Orm/Orm/Linq/ExpressionExtensions.cs +++ b/Orm/Xtensive.Orm/Orm/Linq/ExpressionExtensions.cs @@ -220,7 +220,7 @@ public static ParameterInfo[] GetConstructorParameters(this NewExpression expres // ReSharper disable ConditionIsAlwaysTrueOrFalse // ReSharper disable HeuristicUnreachableCode if (expression.Constructor == null) { - return new ParameterInfo[0]; + return Array.Empty(); } // ReSharper restore ConditionIsAlwaysTrueOrFalse // ReSharper restore HeuristicUnreachableCode diff --git a/Orm/Xtensive.Orm/Orm/Linq/Translator.Expressions.cs b/Orm/Xtensive.Orm/Orm/Linq/Translator.Expressions.cs index 1fb83fa002..abe3097ac4 100644 --- a/Orm/Xtensive.Orm/Orm/Linq/Translator.Expressions.cs +++ b/Orm/Xtensive.Orm/Orm/Linq/Translator.Expressions.cs @@ -406,9 +406,12 @@ protected override Expression VisitMethodCall(MethodCallExpression mc) return Visit(customCompiler.Invoke(mc.Object, mc.Arguments.ToArray())); } + var methodDeclaringType = method.DeclaringType; + var methodName = method.Name; + // Visit Query. Deprecated. #pragma warning disable 612,618 - if (method.DeclaringType == WellKnownOrmTypes.Query) { + if (methodDeclaringType == WellKnownOrmTypes.Query) { // Query.All if (method.IsGenericMethodSpecificationOf(WellKnownMembers.Query.All)) { return ConstructQueryable(mc); @@ -439,7 +442,7 @@ protected override Expression VisitMethodCall(MethodCallExpression mc) throw new InvalidOperationException(String.Format(Strings.ExMethodCallExpressionXIsNotSupported, mc.ToString(true))); } // Visit QueryEndpoint. - if (method.DeclaringType == typeof(QueryEndpoint)) { + if (methodDeclaringType == typeof(QueryEndpoint)) { // Query.All if (method.IsGenericMethodSpecificationOf(WellKnownMembers.QueryEndpoint.All)) { return ConstructQueryable(mc); @@ -476,35 +479,32 @@ protected override Expression VisitMethodCall(MethodCallExpression mc) #pragma warning restore 612,618 // Visit Queryable extensions. - if (method.DeclaringType==typeof (QueryableExtensions)) - if (method.Name==WellKnownMembers.Queryable.ExtensionLeftJoin.Name) - return VisitLeftJoin(mc); - else if (method.Name=="In") - return VisitIn(mc); - else if (method.Name==WellKnownMembers.Queryable.ExtensionLock.Name) - return VisitLock(mc); - else if (method.Name==WellKnownMembers.Queryable.ExtensionTake.Name) - return VisitTake(mc.Arguments[0], mc.Arguments[1]); - else if (method.Name==WellKnownMembers.Queryable.ExtensionSkip.Name) - return VisitSkip(mc.Arguments[0], mc.Arguments[1]); - else if (method.Name==WellKnownMembers.Queryable.ExtensionElementAt.Name) - return VisitElementAt(mc.Arguments[0], mc.Arguments[1], context.IsRoot(mc), method.ReturnType, false); - else if (method.Name==WellKnownMembers.Queryable.ExtensionElementAtOrDefault.Name) - return VisitElementAt(mc.Arguments[0], mc.Arguments[1], context.IsRoot(mc), method.ReturnType, true); - else if (method.Name == WellKnownMembers.Queryable.ExtensionCount.Name) - return VisitAggregate(mc.Arguments[0], method, null, context.IsRoot(mc), mc); - else if (method.Name == WellKnownMembers.Queryable.ExtensionTag.Name) - return VisitTag(mc); - else - throw new InvalidOperationException(String.Format(Strings.ExMethodCallExpressionXIsNotSupported, mc.ToString(true))); + if (methodDeclaringType == typeof(QueryableExtensions)) { + return methodName switch { + nameof(QueryableExtensions.LeftJoin) => VisitLeftJoin(mc), + "In" => VisitIn(mc), + nameof(QueryableExtensions.Lock) => VisitLock(mc), + nameof(QueryableExtensions.Take) => VisitTake(mc.Arguments[0], mc.Arguments[1]), + nameof(QueryableExtensions.Skip) => VisitSkip(mc.Arguments[0], mc.Arguments[1]), + nameof(QueryableExtensions.ElementAt) => VisitElementAt(mc.Arguments[0], mc.Arguments[1], context.IsRoot(mc), method.ReturnType, false), + nameof(QueryableExtensions.ElementAtOrDefault) => VisitElementAt(mc.Arguments[0], mc.Arguments[1], context.IsRoot(mc), method.ReturnType, true), + nameof(QueryableExtensions.Count) => VisitAggregate(mc.Arguments[0], method, null, context.IsRoot(mc), mc), + nameof(QueryableExtensions.Tag) => VisitTag(mc), + _ => throw new InvalidOperationException(String.Format(Strings.ExMethodCallExpressionXIsNotSupported, mc.ToString(true))) + }; + } // Visit Collection extensions - if (method.DeclaringType==typeof(CollectionExtensionsEx)) - if (method.Name==WellKnownMembers.Collection.ExtensionContainsAny.Name) - return VisitContainsAny(mc.Arguments[0], mc.Arguments[1], context.IsRoot(mc), method.GetGenericArguments()[0]); - else if (method.Name==WellKnownMembers.Collection.ExtensionContainsAll.Name) - return VisitContainsAll(mc.Arguments[0], mc.Arguments[1], context.IsRoot(mc), method.GetGenericArguments()[0]); - else if (method.Name==WellKnownMembers.Collection.ExtensionContainsNone.Name) - return VisitContainsNone(mc.Arguments[0], mc.Arguments[1], context.IsRoot(mc), method.GetGenericArguments()[0]); + if (methodDeclaringType == typeof(CollectionExtensionsEx)) { + switch (methodName) { + case nameof(CollectionExtensionsEx.ContainsAny): + return VisitContainsAny(mc.Arguments[0], mc.Arguments[1], context.IsRoot(mc), method.GetGenericArguments()[0]); + case nameof(CollectionExtensionsEx.ContainsAll): + return VisitContainsAll(mc.Arguments[0], mc.Arguments[1], context.IsRoot(mc), method.GetGenericArguments()[0]); + case nameof(CollectionExtensionsEx.ContainsNone): + return VisitContainsNone(mc.Arguments[0], mc.Arguments[1], context.IsRoot(mc), method.GetGenericArguments()[0]); + } + } + // Process local collections if (mc.Object.IsLocalCollection(context)) { @@ -512,12 +512,12 @@ protected override Expression VisitMethodCall(MethodCallExpression mc) // List.Contains // Array.Contains ParameterInfo[] parameters = method.GetParameters(); - if (method.Name=="Contains" && parameters.Length==1) + if (methodName=="Contains" && parameters.Length==1) return VisitContains(mc.Object, mc.Arguments[0], false); } var result = base.VisitMethodCall(mc); - if (result!=mc && result.NodeType==ExpressionType.Call) { + if (result != mc && result.NodeType == ExpressionType.Call) { var visitedMethodCall = (MethodCallExpression) result; if (visitedMethodCall.Arguments.Any(arg => arg.IsProjection())) throw new InvalidOperationException(String.Format(Strings.ExMethodCallExpressionXIsNotSupported, mc.ToString(true))); diff --git a/Orm/Xtensive.Orm/Orm/Providers/SqlProvider.cs b/Orm/Xtensive.Orm/Orm/Providers/SqlProvider.cs index 73e7bf0e61..227990d31b 100644 --- a/Orm/Xtensive.Orm/Orm/Providers/SqlProvider.cs +++ b/Orm/Xtensive.Orm/Orm/Providers/SqlProvider.cs @@ -102,7 +102,7 @@ public SqlProvider(HandlerAccessor handlers, QueryRequest request, /// The provider. /// The permanent reference. public SqlProvider(SqlProvider provider, SqlTable permanentReference) - : base(provider.Origin, provider.Sources.Cast().ToArray()) + : base(provider.Origin, provider.Sources.Cast().ToArray(provider.Sources.Count)) { this.permanentReference = permanentReference; handlers = provider.handlers; diff --git a/Orm/Xtensive.Orm/Orm/Providers/SqlProviderPreparer.cs b/Orm/Xtensive.Orm/Orm/Providers/SqlProviderPreparer.cs index b62fcf0997..8504615137 100644 --- a/Orm/Xtensive.Orm/Orm/Providers/SqlProviderPreparer.cs +++ b/Orm/Xtensive.Orm/Orm/Providers/SqlProviderPreparer.cs @@ -1,9 +1,10 @@ -// Copyright (C) 2012 Xtensive LLC. -// All rights reserved. -// For conditions of distribution and use, see license. +// Copyright (C) 2012-2022 Xtensive LLC. +// This code is distributed under MIT license terms. +// See the License.txt file in the project root for more information. // Created by: Denis Krjuchkov // Created: 2012.01.29 +using System; using Xtensive.Core; using Xtensive.Orm.Rse; using Xtensive.Orm.Rse.Compilation; @@ -25,7 +26,7 @@ public ExecutableProvider Process(ExecutableProvider rootProvider) request.Prepare(); // Optional part - remove all underlying providers to save memory. return request.CheckOptions(QueryRequestOptions.AllowOptimization) - ? new SqlProvider(handlers, request, sqlProvider.Origin.MakeVoid(), new ExecutableProvider[0]) + ? new SqlProvider(handlers, request, sqlProvider.Origin.MakeVoid(), Array.Empty()) : rootProvider; } diff --git a/Orm/Xtensive.Orm/Orm/Providers/SqlSelectProcessor.cs b/Orm/Xtensive.Orm/Orm/Providers/SqlSelectProcessor.cs index 2f85f051ad..9266a08475 100644 --- a/Orm/Xtensive.Orm/Orm/Providers/SqlSelectProcessor.cs +++ b/Orm/Xtensive.Orm/Orm/Providers/SqlSelectProcessor.cs @@ -15,8 +15,7 @@ internal class SqlSelectProcessor : ISqlVisitor public void Visit(SqlAggregate node) { - if (node.Expression is not null) - Visit(node.Expression); + VisitNullable(node.Expression); } public void Visit(SqlAlterDomain node) @@ -47,8 +46,7 @@ public void Visit(SqlAssignment node) { if (node.Left!=null) Visit(node.Left); - if (node.Right is not null) - Visit(node.Right); + VisitNullable(node.Right); } public void Visit(SqlBatch node) @@ -57,20 +55,15 @@ public void Visit(SqlBatch node) public void Visit(SqlBetween node) { - if (node.Left is not null) - Visit(node.Left); - if (node.Right is not null) - Visit(node.Right); - if (!node.Expression) - Visit(node.Expression); + VisitNullable(node.Left); + VisitNullable(node.Right); + VisitNullable(node.Expression); } public void Visit(SqlBinary node) { - if (node.Left is not null) - Visit(node.Left); - if (node.Right is not null) - Visit(node.Right); + VisitNullable(node.Left); + VisitNullable(node.Right); } public void Visit(SqlBreak node) @@ -79,16 +72,13 @@ public void Visit(SqlBreak node) public void Visit(SqlCase node) { - if (node.Value is not null) - Visit(node.Value); - if (node.Else is not null) - Visit(node.Else); + VisitNullable(node.Value); + VisitNullable(node.Else); } public void Visit(SqlCast node) { - if (node.Operand is not null) - Visit(node.Operand); + VisitNullable(node.Operand); } public void Visit(SqlCloseCursor node) @@ -97,14 +87,12 @@ public void Visit(SqlCloseCursor node) public void Visit(SqlCollate node) { - if (node.Operand is not null) - Visit(node.Operand); + VisitNullable(node.Operand); } public void Visit(SqlColumnRef node) { - if (node.SqlColumn is not null) - Visit(node.SqlColumn); + VisitNullable(node.SqlColumn); } public void Visit(SqlConcat node) @@ -197,8 +185,7 @@ public void Visit(SqlDelete node) { if (node.Delete!=null) Visit(node.Delete); - if (node.Where is not null) - Visit(node.Where); + VisitNullable(node.Where); } public void Visit(SqlDropAssertion node) @@ -259,8 +246,7 @@ public void Visit(SqlPlaceholder node) public void Visit(SqlExtract node) { - if (node.Operand is not null) - Visit(node.Operand); + VisitNullable(node.Operand); } public void Visit(SqlFastFirstRowsHint node) @@ -303,8 +289,7 @@ public void Visit(SqlIf node) Visit(node.True); if (node.False!=null) Visit(node.False); - if (node.Condition is not null) - Visit(node.Condition); + VisitNullable(node.Condition); } public void Visit(SqlInsert node) @@ -319,11 +304,10 @@ public void Visit(SqlInsert node) public void Visit(SqlJoinExpression node) { - if (node.Expression is not null) - Visit(node.Expression); - if (node.Left!=null) + VisitNullable(node.Expression); + if (node.Left != null) Visit(node.Left); - if (node.Right!=null) + if (node.Right != null) Visit(node.Right); } @@ -333,12 +317,9 @@ public void Visit(SqlJoinHint node) public void Visit(SqlLike node) { - if (node.Expression is not null) - Visit(node.Expression); - if (node.Escape is not null) - Visit(node.Escape); - if (node.Pattern is not null) - Visit(node.Pattern); + VisitNullable(node.Expression); + VisitNullable(node.Escape); + VisitNullable(node.Pattern); } public void Visit(SqlLiteral node) @@ -347,8 +328,7 @@ public void Visit(SqlLiteral node) public void Visit(SqlMatch node) { - if (node.Value is not null) - Visit(node.Value); + VisitNullable(node.Value); if (node.SubQuery is not null) Visit(node.SubQuery); } @@ -375,8 +355,7 @@ public void Visit(SqlOpenCursor node) public void Visit(SqlOrder node) { - if (node.Expression is not null) - Visit(node.Expression); + VisitNullable(node.Expression); } public void Visit(SqlParameterRef node) @@ -385,10 +364,8 @@ public void Visit(SqlParameterRef node) public void Visit(SqlRound node) { - if (node.Argument is not null) - Visit(node.Argument); - if (node.Length is not null) - Visit(node.Length); + VisitNullable(node.Argument); + VisitNullable(node.Length); } public void Visit(SqlQueryExpression node) @@ -439,8 +416,7 @@ public void Visit(SqlTableRef node) public void Visit(SqlTrim node) { - if (node.Expression is not null) - Visit(node.Expression); + VisitNullable(node.Expression); } public void Visit(SqlSelect node) @@ -451,16 +427,12 @@ public void Visit(SqlSelect node) Visit(column); foreach (var column in node.OrderBy) Visit(column); - if (node.From!=null) + if (node.From != null) Visit(node.From); - if (node.Having is not null) - Visit(node.Having); - if (node.Limit is not null) - Visit(node.Limit); - if (node.Offset is not null) - Visit(node.Offset); - if (node.Where is not null) - Visit(node.Where); + VisitNullable(node.Having); + VisitNullable(node.Limit); + VisitNullable(node.Offset); + VisitNullable(node.Where); foreach (var hint in node.Hints) Visit(hint); @@ -478,7 +450,7 @@ public void Visit(SqlSelect node) rootSelect.Comment = SqlComment.Join(rootSelect.Comment, node.Comment); node.Comment = null; } - + var addOrderBy = hasPaging && node.OrderBy.Count==0 && providerInfo.Supports(ProviderFeatures.PagingRequiresOrderBy); @@ -495,8 +467,7 @@ public void Visit(SqlSubQuery node) public void Visit(SqlUnary node) { - if (node.Operand is not null) - Visit(node.Operand); + VisitNullable(node.Operand); } public void Visit(SqlMetadata node) @@ -510,8 +481,7 @@ public void Visit(SqlUpdate node) Visit(node.From); if (node.Update!=null) Visit(node.Update); - if (node.Where is not null) - Visit(node.Where); + VisitNullable(node.Where); foreach (var value in node.Values.Values) Visit(value); foreach (var hint in node.Hints) @@ -520,8 +490,7 @@ public void Visit(SqlUpdate node) public void Visit(SqlUserColumn node) { - if (node.Expression is not null) - Visit(node.Expression); + VisitNullable(node.Expression); } public void Visit(SqlUserFunctionCall node) @@ -544,8 +513,7 @@ public void Visit(SqlVariant node) public void Visit(SqlWhile node) { - if (node.Condition is not null) - Visit(node.Condition); + VisitNullable(node.Condition); if (node.Statement!=null) Visit(node.Statement); } @@ -572,6 +540,13 @@ public void Visit(SqlTable sqlTable) sqlTable.AcceptVisitor(this); } + private void VisitNullable(SqlExpression sqlExpression) + { + if (sqlExpression is not null) { + Visit(sqlExpression); + } + } + private void Visit(ISqlQueryExpression queryExpression) { queryExpression.AcceptVisitor(this); @@ -592,9 +567,9 @@ private void Visit(SqlHint sqlExpression) public void Visit(SqlComment comment) { - + } - + public static void Process(SqlSelect select, ProviderInfo providerInfo) { ArgumentValidator.EnsureArgumentNotNull(select, "select"); diff --git a/Orm/Xtensive.Orm/Orm/Rse/Providers/CompilableProvider.cs b/Orm/Xtensive.Orm/Orm/Rse/Providers/CompilableProvider.cs index 7e45c17828..5d631a298e 100644 --- a/Orm/Xtensive.Orm/Orm/Rse/Providers/CompilableProvider.cs +++ b/Orm/Xtensive.Orm/Orm/Rse/Providers/CompilableProvider.cs @@ -1,10 +1,11 @@ -// Copyright (C) 2003-2010 Xtensive LLC. -// All rights reserved. -// For conditions of distribution and use, see license. +// Copyright (C) 2003-2023 Xtensive LLC. +// This code is distributed under MIT license terms. +// See the License.txt file in the project root for more information. // Created by: Alexey Kochetov // Created: 2008.07.03 using System; +using System.Collections.Generic; namespace Xtensive.Orm.Rse.Providers { @@ -22,5 +23,10 @@ protected CompilableProvider(ProviderType type, params Provider[] sources) : base(type, sources) { } + + protected CompilableProvider(ProviderType type) + : this(type, Array.Empty()) + { + } } -} \ No newline at end of file +} diff --git a/Orm/Xtensive.Orm/Orm/Rse/Providers/ExecutableProvider.cs b/Orm/Xtensive.Orm/Orm/Rse/Providers/ExecutableProvider.cs index 44dab7161b..3fdfd41e48 100644 --- a/Orm/Xtensive.Orm/Orm/Rse/Providers/ExecutableProvider.cs +++ b/Orm/Xtensive.Orm/Orm/Rse/Providers/ExecutableProvider.cs @@ -173,7 +173,7 @@ public async Task GetRecordSetReaderAsync( /// /// The property value. /// The property value. - protected ExecutableProvider(CompilableProvider origin, params ExecutableProvider[] sources) + protected ExecutableProvider(CompilableProvider origin, IReadOnlyList sources) : base(origin.Type, sources) { Origin = origin; diff --git a/Orm/Xtensive.Orm/Orm/Rse/Providers/Provider.cs b/Orm/Xtensive.Orm/Orm/Rse/Providers/Provider.cs index 9d4aa1db99..b402ada76f 100644 --- a/Orm/Xtensive.Orm/Orm/Rse/Providers/Provider.cs +++ b/Orm/Xtensive.Orm/Orm/Rse/Providers/Provider.cs @@ -1,10 +1,11 @@ -// Copyright (C) 2008-2020 Xtensive LLC. +// Copyright (C) 2008-2022 Xtensive LLC. // This code is distributed under MIT license terms. // See the License.txt file in the project root for more information. // Created by: Alexey Kochetov // Created: 2008.07.03 using System; +using System.Collections.Generic; using System.Diagnostics; using System.Text; using Xtensive.Core; @@ -23,28 +24,18 @@ public abstract class Provider private const string ToString_Parameters = " ({0})"; private const int ToString_IndentSize = 2; - private Provider[] sources; private RecordSetHeader header; /// /// Gets of the current instance. /// - public ProviderType Type { get; private set; } + public ProviderType Type { get; } /// /// Gets or sets the source providers /// "consumed" by this provider to produce results of current provider. /// - public Provider[] Sources { - [DebuggerStepThrough] - get { return sources; } - [DebuggerStepThrough] - private set { - if (sources!=null) - throw Exceptions.AlreadyInitialized("Sources"); - sources = value; - } - } + public IReadOnlyList Sources { [DebuggerStepThrough] get; } /// /// Gets or sets the header of the record sequence this provide produces. @@ -136,7 +127,7 @@ protected virtual string ParametersToString() /// /// The type of the provider. /// property value. - protected Provider(ProviderType type, params Provider[] sources) + protected Provider(ProviderType type, IReadOnlyList sources) { Type = type; Sources = sources;