Пример #1
0
        protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
        {
            var subquery = SubqueryGeneratorQueryModelVisitor.ParseSubquery(expression.QueryModel, QueryParts, false, ContextName);

            SqlExpression.AppendFormat("({0})", subquery.BuildSqlString(true));
            return(expression);
        }
Пример #2
0
        public static SubqueryParts ParseSubquery(QueryModel queryModel, QueryParts parentQuery, bool canQueryInMemory, string contextName)
        {
            var visitor = new SubqueryGeneratorQueryModelVisitor(parentQuery, canQueryInMemory, queryModel.SelectClause.Selector, contextName);

            visitor.VisitQueryModel(queryModel);
            return(visitor.QueryParts);
        }
Пример #3
0
        protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
        {
            var sqParts = new SubqueryParts(Query, expression.QueryModel.SelectClause.Selector, Query.ContextName);
            var sq      = SubqueryGeneratorQueryModelVisitor.ParseSubquery(expression.QueryModel, sqParts);

            if (!Query.CanQueryInMemory)
            {
                Query.AddSelectPart(
                    null,
                    "(" + sq.BuildSqlString(true) + ")",
                    null,
                    expression.QueryModel.ResultTypeOverride ?? expression.QueryModel.SelectClause.Selector.Type,
                    null);
            }
            return(expression);
        }
 public static SubqueryParts ParseSubquery(QueryModel queryModel, QueryParts parentQuery, bool canQueryInMemory, string contextName)
 {
     var visitor = new SubqueryGeneratorQueryModelVisitor(parentQuery, canQueryInMemory, queryModel.SelectClause.Selector, contextName);
     visitor.VisitQueryModel(queryModel);
     return visitor.QueryParts;
 }
Пример #5
0
        protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
        {
            if (ProcessedExpressions.Contains(expression))
            {
                return(expression);
            }

            if (DataSources.Count == 0)
            {
                DataSources.Add(Query.MainFrom.FromExpression);
                DataSources.AddRange(Query.Joins.Select(it => it.InnerSequence));
                DataSources.AddRange(Query.AdditionalJoins.Select(it => it.FromExpression));
            }

            var model = expression.QueryModel;

            if (model.BodyClauses.Count == 0 &&
                DataSources.Contains(model.MainFromClause.FromExpression))
            {
                return(expression);
            }

            ProcessedExpressions.Add(expression);

            foreach (var candidate in Query.ProjectionMatchers)
            {
                if (candidate.TryMatch(expression, Query, exp => VisitExpression(exp)))
                {
                    return(expression);
                }
            }

            var subquery = SubqueryGeneratorQueryModelVisitor.ParseSubquery(expression.QueryModel, Query, true);

            var cnt = Query.CurrentSelectIndex;
            //TODO true or false
            var sql = subquery.BuildSqlString(true);

            var selector  = model.SelectClause.Selector;
            var projector = (IExecuteFunc)Activator.CreateInstance(typeof(GenericProjection <>).MakeGenericType(selector.Type), model);
            var ssd       = SelectSubqueryData.Create(Query, subquery);

            if (subquery.ResultOperators.Any(it => it is FirstResultOperator))
            {
                Query.AddSelectPart(
                    expression.QueryModel.MainFromClause,
                    @"(SELECT ""{1}"" FROM ({2}) ""{1}"" LIMIT 1) AS ""{0}""".With(
                        "_first_or_default_" + cnt,
                        expression.QueryModel.MainFromClause.ItemName,
                        sql),
                    "_first_or_default_" + cnt,
                    expression.QueryModel.ResultTypeOverride,
                    (rom, dr) =>
                {
                    if (dr.IsDBNull(cnt))
                    {
                        return(null);
                    }
                    var tuple  = new[] { dr.GetValue(cnt).ToString() };
                    var result = ssd.ProcessRow(rom, tuple);
                    return(projector.Eval(result));
                });
            }
            else
            {
                Query.AddSelectPart(
                    expression.QueryModel.MainFromClause,
                    @"(SELECT ARRAY_AGG(""{1}"") FROM ({2}) ""{1}"") AS ""{0}""".With(
                        "_subquery_" + cnt,
                        expression.QueryModel.MainFromClause.ItemName,
                        sql),
                    "_subquery_" + cnt,
                    expression.QueryModel.ResultTypeOverride,
                    (rom, dr) =>
                {
                    object[] array;
                    if (dr.IsDBNull(cnt))
                    {
                        array = new string[0];
                    }
                    else
                    {
                        var value = dr.GetValue(cnt);
                        if (value is string[])
                        {
                            array = value as string[];
                        }
                        else
                        {
                            var obj = dr.GetValue(cnt);
                            //TODO fix dead code usage
                            var tr = obj as TextReader;
                            if (tr != null)
                            {
                                array = PostgresRecordConverter.ParseArray(tr.ReadToEnd());
                            }
                            else
                            {
                                array = PostgresRecordConverter.ParseArray(obj as string);
                            }
                        }
                    }
                    var resultItems = new List <ResultObjectMapping>();
                    foreach (var it in array)
                    {
                        resultItems.Add(ssd.ProcessRow(rom, it));
                    }
                    return(projector.Process(resultItems));
                });
            }
            return(expression);
        }