public string Format(int depth, int indentSize, string fuctionName, MethodCallExpression node) { var innerTranslator = new BigQueryTranslateVisitor(); var expr1 = innerTranslator.VisitAndClearBuffer(node.Arguments[0]); var arg = node.Arguments[1] as NewArrayExpression; var argMember = node.Arguments[1] as MemberExpression; string expr2; if (arg != null) { expr2 = string.Join(", ", arg.Expressions.Select(x => innerTranslator.VisitAndClearBuffer(x))); } else if (argMember != null) { var names = (Array)Expression.Lambda(argMember).Compile().DynamicInvoke(); expr2 = string.Join(", ", names.Cast <object>().Select(x => DataTypeFormatter.Format(x))); } else { throw new InvalidOperationException(); } return(string.Format("{0} {1}({2})", expr1, fuctionName, expr2)); }
protected override Expression VisitConstant(ConstantExpression node) { var expr = DataTypeFormatter.Format(node.Value); sb.Append(expr); return(node); }
bool FormatIfExprIsDateTime(Expression expr) { if (expr is NewExpression) { var node = expr as NewExpression; if (node.Constructor.DeclaringType == typeof(DateTime) || node.Constructor.DeclaringType == typeof(DateTimeOffset)) { var parameters = node.Arguments.Select(x => ExpressionHelper.GetValue(x)).ToArray(); var datetime = node.Constructor.Invoke(parameters); var v = DataTypeFormatter.Format(datetime); sb.Append(v); return(true); } } if (expr is MemberExpression) { var node = expr as MemberExpression; if (node.Member == now) { sb.Append(DataTypeFormatter.Format(DateTime.Now)); return(true); } if (node.Member == utcNow) { sb.Append(DataTypeFormatter.Format(DateTime.UtcNow)); return(true); } if (node.Member == nowOffset) { sb.Append(DataTypeFormatter.Format(DateTimeOffset.Now)); return(true); } if (node.Member == utcNowOffset) { sb.Append(DataTypeFormatter.Format(DateTimeOffset.UtcNow)); return(true); } } return(false); }
public static FirstWindowFunction <T, TColumn> Lag <T, TColumn>(T fieldSource, string columnName, int offset, TColumn defaultValue) { var arg1 = columnName.EscapeBq(); return(new FirstWindowFunction <T, TColumn>("LAG", arg1 + ", " + offset + ", " + DataTypeFormatter.Format(defaultValue))); }
public static FirstWindowFunction <T, TColumn> Lag <T, TColumn>(T fieldSource, Expression <Func <T, TColumn> > columnSelector, int offset, TColumn defaultValue) { var arg1 = BigQueryTranslateVisitor.BuildQuery(0, 0, columnSelector); return(new FirstWindowFunction <T, TColumn>("LAG", arg1 + ", " + offset + ", " + DataTypeFormatter.Format(defaultValue))); }
// append field access protected override Expression VisitMember(MemberExpression node) { // WindowFunction, relieve property call and compile. if (node.Member.GetCustomAttributes <WindowFunctionAttribute>().Any()) { var methodNode = node.Expression as MethodCallExpression; MethodCallExpression root; var paritionBy = (MethodCallExpression)methodNode.Object; if (paritionBy == null) { root = methodNode; } else { root = (MethodCallExpression)paritionBy.Object; if (root == null) { root = paritionBy; } } var para = root.Arguments[0] as ParameterExpression; var windowFunction = Expression.Lambda(methodNode, para); var compiledWindowFunction = windowFunction.Compile(); var windowQuery = compiledWindowFunction.DynamicInvoke(new object[1]); sb.Append(windowQuery.ToString()); return(node); } // specialize for DateTime if (FormatIfExprIsDateTime(node)) { return(node); } bool isRootIsParameter = false; // as external field or parameter var nodes = new List <MemberExpression>(); var next = node; while (next != null) { isRootIsParameter = next.Expression.NodeType == ExpressionType.Parameter; nodes.Add(next); var nextExpr = next.Expression; next = nextExpr as MemberExpression; if (next == null) { // skip indexer access for repeated field var binaryNext = nextExpr; while (binaryNext is BinaryExpression) { binaryNext = ((BinaryExpression)binaryNext).Left; if (binaryNext is MemberExpression) { next = (MemberExpression)binaryNext; break; } } } } if (isRootIsParameter) { sb.Append("["); for (int i = nodes.Count - 1; i >= 0; i--) { sb.Append(nodes[i].Member.Name); // If Nullable don't emit .Value if (nodes[i].Type.IsNullable()) { break; } if (nodes.Count != 1 && i != 0) { sb.Append("."); } } sb.Append("]"); } else { var v = ExpressionHelper.GetValue(nodes[0]); var str = DataTypeFormatter.Format(v); sb.Append(str); } return(node); }