private static bool CheckShortCircuitSum(SubQueryExpression expression, MainQueryParts queryParts, Action<Expression> visitExpression) { var subquery = SubqueryGeneratorQueryModelVisitor.ParseSubquery(expression.QueryModel, queryParts, true); if (subquery.ShouldQueryInMemory) { throw new NotImplementedException("Unsupported subquery. Please provide more info about query."); //return false; } var sql = subquery.BuildSqlString(false); var cnt = queryParts.CurrentSelectIndex; var selector = expression.QueryModel.SelectClause.Selector as MemberExpression; if (selector == null) return false; var type = expression.QueryModel.ResultTypeOverride; if (type.IsNullable()) type = type.GetGenericArguments()[0]; queryParts.AddSelectPart( expression.QueryModel.MainFromClause, @"(SELECT SUM((""{1}"").""{3}"") FROM ({2}) ""{1}"") AS ""{0}""".With( "_subquery_" + cnt, expression.QueryModel.MainFromClause.ItemName, sql, selector.Member.Name), "_sum_" + cnt, expression.QueryModel.ResultTypeOverride, (_, dr) => dr.IsDBNull(cnt) ? 0 : Convert.ChangeType(dr.GetValue(cnt), type)); return true; }
public bool TryMatch(Expression expression, MainQueryParts queryParts, Action<Expression> visitExpression) { var sq = expression as SubQueryExpression; return sq != null && sq.QueryModel.ResultOperators.Count == 1 && sq.QueryModel.ResultOperators[0] is SumResultOperator && CheckShortCircuitSum(sq, queryParts, visitExpression); }
public bool TryMatch(Expression expression, MainQueryParts queryParts, Action<Expression> visitExpression, QueryContext context) { var sq = expression as SubQueryExpression; return sq != null && sq.QueryModel.ResultOperators.Count == 1 && (sq.QueryModel.ResultOperators[0] is CountResultOperator || sq.QueryModel.ResultOperators[0] is LongCountResultOperator) && CheckShortCircuitCount(sq, queryParts, visitExpression); }
public SqlCommandData(MainQueryParts query) { this.Query = query; Statement = query.BuildSqlString(); var mainIndex = query.Selects.FindIndex(it => it.QuerySource == query.MainFrom); if (mainIndex > 0) { var main = query.Selects[mainIndex]; query.Selects.RemoveAt(mainIndex); query.Selects.Insert(0, main); } }
private static bool CheckShortCircuitCount(SubQueryExpression expression, MainQueryParts queryParts, Action<Expression> visitExpression) { var subquery = SubqueryGeneratorQueryModelVisitor.ParseSubquery(expression.QueryModel, queryParts, true); if (subquery.ShouldQueryInMemory) { throw new NotImplementedException("Unsupported subquery. Please provide more info about query."); //return false; } var cnt = queryParts.CurrentSelectIndex; var mq = subquery.MainFrom.FromExpression as QuerySourceReferenceExpression; if (mq != null && subquery.Joins.Count == 0 && subquery.AdditionalJoins.Count == 0 && subquery.Conditions.Count == 0) { if (mq.ReferencedQuerySource.ItemType.IsGrouping()) { queryParts.AddSelectPart( expression.QueryModel.MainFromClause, "ARRAY_UPPER(\"{0}\".\"Values\", 1) AS \"_count_helper_{1}\"".With(mq.ReferencedQuerySource.ItemName, cnt), "_count_helper_" + cnt, expression.QueryModel.ResultTypeOverride, (_, dr) => dr.IsDBNull(cnt) ? 0 : Convert.ChangeType(dr.GetValue(cnt), expression.QueryModel.ResultTypeOverride)); return true; } } var sql = subquery.BuildSqlString(false); queryParts.AddSelectPart( expression.QueryModel.MainFromClause, @"(SELECT COUNT(""{1}"") FROM ({2}) ""{1}"") AS ""{0}"" ".With( "_subquery_" + cnt, expression.QueryModel.MainFromClause.ItemName, sql), "_count_" + cnt, expression.QueryModel.ResultTypeOverride, (_, dr) => dr.IsDBNull(cnt) ? 0 : Convert.ChangeType(dr.GetValue(cnt), expression.QueryModel.ResultTypeOverride)); return true; }
public static void AddFilter <TSource>( IServiceProvider Locator, IDatabaseQuery query, ISpecification <TSource> filter, StringBuilder sb) { var cf = Locator.Resolve <IPostgresConverterFactory>(); var ep = Locator.Resolve <IExtensibilityProvider>(); var qp = new MainQueryParts( Locator, cf, ep.ResolvePlugins <IQuerySimplification>(), ep.ResolvePlugins <IExpressionMatcher>(), ep.ResolvePlugins <IMemberMatcher>(), new IProjectionMatcher[0]); var linq = new Queryable <TSource>(new QueryExecutor(query, Locator, cf, ep)).Filter(filter); var parser = QueryParser.CreateDefault(); var model = parser.GetParsedQuery(linq.Expression); if (model.BodyClauses.Count > 0) { sb.AppendLine("WHERE"); for (int i = 0; i < model.BodyClauses.Count; i++) { var wc = model.BodyClauses[i] as WhereClause; if (wc == null) { continue; } sb.Append(" "); if (i > 0) { sb.Append("AND "); } sb.Append(qp.GetSqlExpression(wc.Predicate)); } } }
public SqlGeneratorQueryModelVisitor(MainQueryParts queryParts) { Contract.Requires(queryParts != null); this.QueryParts = queryParts; }