static Expression RecursivelyGetSubselects(GetExpression get, Expression filterexpr, bool includeFilter, Type itemType, int depth = 0) { if (get.Subselect == null) { var sourceExpr = includeFilter ? filterexpr : null; Expression reduceexpr = ReduceExpressionGeneration.GetMapreduceExpression(sourceExpr, get._selects.ToArray(), get._dimensions.Any() ? get._dimensions.ToArray() : null, itemType, get, null, "sc" + depth); return(reduceexpr); } else { var sub = RecursivelyGetSubselects(get.Subselect, filterexpr, includeFilter, itemType, depth + 1); var lambda = sub as LambdaExpression; var body = lambda.Body; var param = lambda.Parameters.FirstOrDefault(); var resultType = body.Type; var targetType = ReduceExpressionGeneration.GetTypeOfEnumerable(resultType); Expression reduceexpr = ReduceExpressionGeneration.GetMapreduceExpression(null, get._selects.ToArray(), get._dimensions.Any() ? get._dimensions.ToArray() : null, targetType, get, body, "sc" + depth); //reduceexpr = ParameterRebinder.ReplaceParameters(reduceexpr, "sc", param); //return reduceexpr; var reducebody = (reduceexpr as LambdaExpression).Body; var newlambda = Expression.Lambda(reducebody, param); return(newlambda); } }
public Expression GetPagingExpression(Type itemType) { EvoQLExpression parse = ParseQuery(); if (parse.Tree is GetExpression) { GetExpression get = (GetExpression)parse.Tree; var res = ReduceExpressionGeneration.GetPagingExpression(get, itemType); return(res); //return new ExpressionResult { Expression = res, Collections = GetCollections(parse) }; } return(null); }
void OrderClause(GetExpression expression) { Expect(19); Expect(20); var ordering = new DimensionExpression(); expression.Ordering = ordering; Primary(ordering, true); if (la.kind == 21) { Get(); expression.OrderDescending = true; } if (la.kind == 22) { Get(); Expect(1); expression.Take = Int32.Parse(t.val); if (la.kind == 18) { Get(); Expect(1); expression.Skip = expression.Take; expression.Take = Int32.Parse(t.val); } } }
void FromClause(GetExpression expression) { Expect(32); if (la.kind == 7) { GetExpression subselect = new GetExpression(); expression.Subselect = subselect; Get(); QlClause(subselect); Expect(8); } else if (la.kind == 3 || la.kind == 4 || la.kind == 31) { var identifier = new IdentifierExpression(); string alias = null; Identifier(identifier); if (la.kind == 3 || la.kind == 4 || la.kind == 28) { if (la.kind == 28) { Get(); } AliasClause(ref alias); } expression.AddCollection(identifier.LastPart, alias); while (la.kind == 18) { Get(); var identifier2 = new IdentifierExpression(); string alias2 = null; Identifier(identifier); if (la.kind == 3 || la.kind == 4 || la.kind == 28) { if (la.kind == 28) { Get(); } AliasClause(ref alias); } expression.AddCollection(identifier2.LastPart, alias2); } } else SynErr(46); }
void SelectClause(GetExpression expression) { Expect(29); if (la.kind == 24) { Get(); Expect(1); expression.Take = Int32.Parse(t.val); } if (StartOf(7)) { if (StartOf(4)) { var argList = new ArgumentListExpression(); argList.SetParent(expression); SelectField(argList); while (la.kind == 18) { Get(); SelectField(argList); } expression.AddSelects(argList.GetChildren()); } if (la.kind == 32) { FromClause(expression); } if (la.kind == 30) { GroupByClause(expression); } } }
void GetClause(GetExpression expression) { Expect(15); Expect(3); expression.AddGet(t.val); while (la.kind == 18) { Get(); Expect(3); expression.AddGet(t.val); } }
void QlClause(GetExpression expression) { if (la.kind == 29) { SelectClause(expression); } if (la.kind == 32) { FromClause(expression); } if (la.kind == 16) { WhereClause(expression); } if (la.kind == 19) { OrderClause(expression); } }
public void SetFrom(GetExpression source) { _fromSource = source; }
void HavingClause(GetExpression expression) { Expect(33); var having = new HavingExpression(); ConditionGroup conditions = new ConditionGroup(); expression.SetHaving(having); having.SetChild(conditions); Unary(conditions, false); while (StartOf(4)) { Unary(conditions, false); } }
public static Expression GetMapreduceExpression(Expression filter, DimensionExpression[] selects, DimensionExpression[] groupBy, Type itemType, GetExpression get, Expression source, string paramname) { var hash = (filter == null ? 0 : filter.ToString().GetHashCode()) + "|" + (selects == null ? "" : string.Join(",", selects.Select(x => x.GetChecksum()))) + "|" + (groupBy == null ? "" : string.Join(",", groupBy.Select(x => x.GetChecksum()))) + "|" + (get == null ? null : get.Take); Expression expr; var containsAggregates = selects != null && selects.Any(x => x.IsAggregate); LinkDimensions(groupBy, selects); var resultType = InferClrType(selects, groupBy, itemType); if (expressionCache.TryGetValue(hash, out expr)) { return expr; } //a flat select transformation if (selects != null && groupBy == null && !containsAggregates) { expr = MakeSelectExpression(filter, selects, itemType, resultType, get, source, paramname); } else { //a non-grouping aggregate like "SELECT COUNT(*) FROM table" if (groupBy == null || !groupBy.Any()) groupBy = new DimensionExpression[] { new DimensionExpression { Source = null, Function = null } }; expr = MakeMapreduceExpression(filter, selects, groupBy, itemType, resultType, get, source, paramname); } expressionCache[hash] = expr; return expr; }
static Expression MakeMapreduceExpression(Expression filter, DimensionExpression[] selects, DimensionExpression[] groupBy, Type itemType, Type resultType, GetExpression get, Expression source, string paramname) { var elementType = itemType; //if (OneToManyGroupByTypes == null) OneToManyGroupByTypes = typeof(GroupByTypes).GetEnumValues().OfType<GroupByTypes>().Where(x => GetAttribute<OneToManyAttribute>(x) != null).ToArray(); var collectionParameter = Expression.Parameter(typeof(IEnumerable <>).MakeGenericType(elementType), paramname); //var associatedTypes = GetAttribute<AssociatedTypesAttribute>(elementType); //if (associatedTypes == null) throw new Exception("Unknown associated types, please declare an AssociatedTypes attribute for " + elementType.Name); //Expression lambdaBody = MakeSelectExpression(filter, groupBy, interval, select, collectionParameter, elementType, associatedTypes.MetadataType, associatedTypes.GroupingType, typeof(TOut)); var metadataType = typeof(ItemMetadata <>).MakeGenericType(itemType); Expression lambdaBody = MakeSelectExpressionEx(filter, groupBy, selects, source ?? collectionParameter, elementType, metadataType, null, resultType); if (get != null && get.Take.HasValue) { lambdaBody = AppendTake(typeof(Enumerable), resultType, lambdaBody, get.Take.Value); } var delegateType = typeof(Func <,>).MakeGenericType(typeof(IEnumerable <>).MakeGenericType(elementType), typeof(IEnumerable <>).MakeGenericType(resultType)); var lambda = Expression.Lambda ( delegateType: delegateType, parameters: collectionParameter, body: lambdaBody ); return(lambda); }
public static Expression GetPagingExpression(GetExpression paging, Type itemType) { var collectionType = typeof(IEnumerable <>).MakeGenericType(itemType); var collectionParameter = Expression.Parameter(collectionType, "col"); Expression result = null; if (paging.Ordering != null) { string[] properties = paging.Ordering.Source.Split('.'); string methodName = paging.OrderDescending ? "OrderByDescending" : "OrderBy"; var xParameter = Expression.Parameter(itemType, "x"); Expression currentExpression = xParameter; var type = itemType; foreach (string current in properties) { var member = GetMember(type, current); currentExpression = Expression.MakeMemberAccess(currentExpression, member); type = GetMemberType(member); } Type delegateType = typeof(Func <,>).MakeGenericType(itemType, type); LambdaExpression lambda = Expression.Lambda(delegateType, currentExpression, xParameter); var methodInfo = typeof(Enumerable).GetMethods().Single(method => method.Name == methodName && method.IsGenericMethodDefinition && method.GetGenericArguments().Length == 2 && method.GetParameters().Length == 2).MakeGenericMethod(itemType, type); result = Expression.Call ( method: methodInfo, arg0: collectionParameter, arg1: lambda ); } if (paging.Skip.HasValue) { int skip = paging.Skip.Value; if (skip < 0) { throw new ArgumentException(); } result = AttachMethodExpression(result, "Skip", skip, itemType); } if (paging.Take.HasValue) { int take = paging.Take.Value; if (take < 0) { throw new ArgumentException(); } result = AttachMethodExpression(result, "Take", take, itemType); } result = Expression.Lambda ( delegateType: typeof(Func <,>).MakeGenericType(collectionParameter.Type, collectionParameter.Type), parameters: collectionParameter, body: result ); return(result); }
public static Expression GetPagingExpression(GetExpression paging, Type itemType) { var collectionType = typeof(IEnumerable<>).MakeGenericType(itemType); var collectionParameter = Expression.Parameter(collectionType, "col"); Expression result = null; if (paging.Ordering != null) { string[] properties = paging.Ordering.Source.Split('.'); string methodName = paging.OrderDescending ? "OrderByDescending" : "OrderBy"; var xParameter = Expression.Parameter(itemType, "x"); Expression currentExpression = xParameter; var type = itemType; foreach (string current in properties) { var member = GetMember(type, current); currentExpression = Expression.MakeMemberAccess(currentExpression, member); type = GetMemberType(member); } Type delegateType = typeof(Func<,>).MakeGenericType(itemType, type); LambdaExpression lambda = Expression.Lambda(delegateType, currentExpression, xParameter); var methodInfo = typeof(Enumerable).GetMethods().Single(method => method.Name == methodName && method.IsGenericMethodDefinition && method.GetGenericArguments().Length == 2 && method.GetParameters().Length == 2).MakeGenericMethod(itemType, type); result = Expression.Call ( method: methodInfo, arg0: collectionParameter, arg1: lambda ); } if (paging.Skip.HasValue) { int skip = paging.Skip.Value; if (skip < 0) { throw new ArgumentException(); } result = AttachMethodExpression(result, "Skip", skip, itemType); } if (paging.Take.HasValue) { int take = paging.Take.Value; if (take < 0) { throw new ArgumentException(); } result = AttachMethodExpression(result, "Take", take, itemType); } result = Expression.Lambda ( delegateType: typeof(Func<,>).MakeGenericType(collectionParameter.Type, collectionParameter.Type), parameters: collectionParameter, body: result ); return result; }
void GroupByClause(GetExpression expression) { Expect(30); Expect(20); var groupByDimension = new DimensionExpression(); expression.AddDimension(groupByDimension); GroupByField(groupByDimension); while (la.kind == 18) { Get(); var groupByDimension2 = new DimensionExpression(); expression.AddDimension(groupByDimension2); GroupByField(groupByDimension2); } if (la.kind == 33) { HavingClause(expression); } }
public static Expression GetMapreduceExpression(Expression filter, DimensionExpression[] selects, DimensionExpression[] groupBy, Type itemType, GetExpression get, Expression source, string paramname) { var hash = (filter == null ? 0 : filter.ToString().GetHashCode()) + "|" + (selects == null ? "" : string.Join(",", selects.Select(x => x.GetChecksum()))) + "|" + (groupBy == null ? "" : string.Join(",", groupBy.Select(x => x.GetChecksum()))) + "|" + (get == null ? null : get.Take); Expression expr; var containsAggregates = selects != null && selects.Any(x => x.IsAggregate); LinkDimensions(groupBy, selects); var resultType = InferClrType(selects, groupBy, itemType); if (expressionCache.TryGetValue(hash, out expr)) { return(expr); } //a flat select transformation if (selects != null && groupBy == null && !containsAggregates) { expr = MakeSelectExpression(filter, selects, itemType, resultType, get, source, paramname); } else { //a non-grouping aggregate like "SELECT COUNT(*) FROM table" if (groupBy == null || !groupBy.Any()) { groupBy = new DimensionExpression[] { new DimensionExpression { Source = null, Function = null } } } ; expr = MakeMapreduceExpression(filter, selects, groupBy, itemType, resultType, get, source, paramname); } expressionCache[hash] = expr; return(expr); }
void EvoQL() { if (StartOf(1)) { GetExpression expression = new GetExpression(); RootTree = expression; EqlClause(expression); } else if (StartOf(2)) { GetExpression expression = new GetExpression(); RootTree = expression; QlClause(expression); } else if (StartOf(3)) { GetExpression expression = new GetExpression(); RootTree = expression; ConditionGroup conditions = new ConditionGroup(); RootTree.SetChild(conditions); Unary(conditions, false); while (StartOf(4)) { Unary(conditions, false); } } else SynErr(44); }
private static Expression MakeSelectExpression(Expression filter, DimensionExpression[] selects, Type itemType, Type resultType, GetExpression get, Expression source, string paramname) { var collectionParameter = Expression.Parameter(typeof(IEnumerable <>).MakeGenericType(itemType), paramname); var elementEnum = MakeWhereExpression(filter, source ?? collectionParameter, null, itemType); //.AsParallel() var res = AppendAsParallel(typeof(ParallelEnumerable), elementEnum); elementEnum = res; var selectLinqClass = typeof(ParallelEnumerable); var genericSelectInfos = selectLinqClass.GetMethods().Where(x => x.Name == "Select" && x.IsGenericMethod && x.GetParameters().Length == 2); var genericSelectInfo = genericSelectInfos.FirstOrDefault(); var selectInfo0 = genericSelectInfo.MakeGenericMethod(itemType, resultType); var selectParam = Expression.Parameter(type: itemType, name: "i"); var memberBindings = new List <MemberBinding>(); foreach (var select in selects) { if (select.IsStar) { foreach (var field in resultType.GetFields()) { var sourceMember = itemType.GetField(field.Name); var binding = Expression.Bind ( field, Expression.MakeMemberAccess(selectParam, sourceMember) ); memberBindings.Add(binding); } } else if (select.Function == null) { var targetField = GetField(resultType, GetTargetPath(select)); //var sourceField = GetField(itemType, select.Source); var sourceExpr = MakeDimensionExpression(itemType, selectParam, select); var binding = Expression.Bind ( member: targetField, expression: sourceExpr //Expression.MakeMemberAccess(selectParam, sourceField) ); memberBindings.Add(binding); } else { var targetField = GetField(resultType, GetTargetPath(select)); var functionExpr = MakeFunctionCallExpression(select, itemType, selectParam); var binding = Expression.Bind ( member: targetField, expression: functionExpr ); memberBindings.Add(binding); } } var newObjectDecl = Expression.MemberInit ( newExpression: Expression.New(resultType), bindings: memberBindings ); var lambda = Expression.Lambda(newObjectDecl, selectParam); Expression call = Expression.Call(method: selectInfo0, arg0: elementEnum, arg1: lambda); if (get != null && get.Take.HasValue) { call = AppendTake(typeof(Enumerable), resultType, call, get.Take.Value); } var result = Expression.Lambda(call, collectionParameter); return(result); }
void EqlClause(GetExpression expression) { if (la.kind == 15) { GetClause(expression); } if (StartOf(5)) { OptionalWhereClause(expression); } }