public static SubqueryParts ParseSubquery(QueryModel queryModel, QueryParts parentQuery, bool canQueryInMemory, string contextName, QueryContext context) { var visitor = new SubqueryGeneratorQueryModelVisitor(parentQuery, canQueryInMemory, queryModel.SelectClause.Selector, contextName, context); visitor.VisitQueryModel(queryModel); return(visitor.QueryParts); }
protected override Expression VisitSubQueryExpression(SubQueryExpression expression) { //TODO select, where? var subquery = SubqueryGeneratorQueryModelVisitor.ParseSubquery(expression.QueryModel, QueryParts, false, ContextName, Context); SqlExpression.AppendFormat("({0})", subquery.BuildSqlString(true)); return(expression); }
protected override Expression VisitSubQueryExpression(SubQueryExpression expression) { var sqParts = new SubqueryParts(Query, expression.QueryModel.SelectClause.Selector, Query.ContextName, Query.Context.Select()); var sq = SubqueryGeneratorQueryModelVisitor.ParseSubquery(expression.QueryModel, sqParts, Query.ContextName, Query.Context.Select()); if (!Query.CanQueryInMemory) { Query.AddSelectPart( null, "(" + sq.BuildSqlString(true) + ")", null, expression.QueryModel.ResultTypeOverride ?? expression.QueryModel.SelectClause.Selector.Type, null); } return(expression); }
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, Query.ContextName, Query.Context.Select()); 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)) { //TODO fix later Query.AddSelectPart( expression.QueryModel.MainFromClause, @"(SELECT ""{1}"" FROM ({2}) ""{1}"" WHERE RowNum = 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 { //TODO fix later 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) => { //TODO fix later return(null); /* * string[] array; * if (dr.IsDBNull(cnt)) * array = new string[0]; * else * { * var value = dr.GetValue(cnt); * array = value is string[] ? value as string[] : OracleRecordConverter.ParseArray(dr.GetString(cnt)); * } * var resultItems = new List<ResultObjectMapping>(); * array.Foreach(it => resultItems.Add(ssd.ProcessRow(rom, it))); * return projector.Process(resultItems);*/ }); } return(expression); }
public static SubqueryParts ParseSubquery(QueryModel queryModel, QueryParts parentQuery, bool canQueryInMemory, string contextName, QueryContext context) { var visitor = new SubqueryGeneratorQueryModelVisitor(parentQuery, canQueryInMemory, queryModel.SelectClause.Selector, contextName, context); visitor.VisitQueryModel(queryModel); return visitor.QueryParts; }