示例#1
0
        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;
        }
示例#2
0
 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);
 }
示例#3
0
 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);
 }
示例#4
0
 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);
     }
 }
示例#5
0
        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;
        }
示例#6
0
        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;
		}