/// <summary> /// Detects when we can remove order /// </summary> /// <param name="selectQuery"></param> /// <param name="information"></param> /// <returns></returns> public static bool TryRemoveDistinct([NotNull] SelectQuery selectQuery, QueryInformation information) { if (selectQuery == null) { throw new ArgumentNullException(nameof(selectQuery)); } if (!selectQuery.Select.IsDistinct) { return(false); } var info = information.GetHierarchyInfo(selectQuery); switch (info?.HierarchyType) { case QueryInformation.HierarchyType.InnerQuery: { if (info.ParentElement is SqlFunction func && func.Name == "EXISTS") { // ORDER BY not needed for EXISTS function, even when Take and Skip specified selectQuery.Select.OrderBy.Items.Clear(); if (selectQuery.Select.SkipValue == null && selectQuery.Select.TakeValue == null) { // we can sefely remove DISTINCT selectQuery.Select.IsDistinct = false; selectQuery.Select.Columns.Clear(); return(true); } } } break; } return(false); }
/// <summary> /// Detects when we can remove order /// </summary> /// <param name="selectQuery"></param> /// <param name="flags"></param> /// <param name="information"></param> /// <returns></returns> public static bool CanRemoveOrderBy([NotNull] SelectQuery selectQuery, SqlProviderFlags flags, QueryInformation information) { if (selectQuery == null) { throw new ArgumentNullException(nameof(selectQuery)); } if (selectQuery.OrderBy.IsEmpty || selectQuery.ParentSelect == null) { return(false); } var current = selectQuery; do { if (current.Select.SkipValue != null || current.Select.TakeValue != null) { return(false); } if (current != selectQuery) { if (!current.OrderBy.IsEmpty || current.Select.IsDistinct) { return(true); } } var info = information.GetHierarchyInfo(current); if (info == null) { break; } switch (info.HierarchyType) { case QueryInformation.HierarchyType.From: if (!flags.IsSubQueryOrderBySupported) { return(true); } current = info.MasterQuery; break; case QueryInformation.HierarchyType.Join: return(true); case QueryInformation.HierarchyType.Union: // currently removing ordering for all UNION return(true); case QueryInformation.HierarchyType.InnerQuery: return(true); default: throw new ArgumentOutOfRangeException(); } } while (current != null); return(false); }