protected override Expression VisitSubQueryExpression(SubQueryExpression expression) { var subquery = SubqueryGeneratorQueryModelVisitor.ParseSubquery(expression.QueryModel, QueryParts, false, Context); SqlExpression.AppendFormat("({0})", subquery.BuildSqlString(true)); 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); }
protected override Expression VisitSubQueryExpression(SubQueryExpression expression) { var sqParts = new SubqueryParts(Query, expression.QueryModel.SelectClause.Selector, Query.Context); 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, QueryContext context) { var visitor = new SubqueryGeneratorQueryModelVisitor(parentQuery, canQueryInMemory, queryModel.SelectClause.Selector, context); visitor.VisitQueryModel(queryModel); return visitor.QueryParts; }
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), Query.Context)) { 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, reader, dr) => { if (dr.IsDBNull(cnt)) { return(null); } var tuple = new[] { dr.GetValue(cnt).ToString() }; var result = ssd.ProcessRow(rom, reader, 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, reader, 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 ResultObjectMapping[array.Length]; for (int i = 0; i < array.Length; i++) { resultItems[i] = ssd.ProcessRow(rom, reader, array[i]); } return(projector.Process(resultItems)); }); } return(expression); }