internal static VfpExpression Rewrite(VfpExpression expression) { var rewriter = new XmlToCursorMoveToInnerExpressionRewriter(expression); if (!rewriter._xmlToCursors.Any()) { return(expression); } expression = rewriter.Visit(expression); foreach (var cursorName in rewriter._xmlToCursorsToBeRemoved) { expression = XmlToCursorExpressionRemover.Remove(expression, cursorName); } return(expression); }
protected override VfpExpressionBinding VisitVfpExpressionBinding(VfpExpressionBinding binding) { var isFilterBinding = binding.Expression is VfpFilterExpression; if (isFilterBinding) { _filterBindings.Push(binding); } binding = base.VisitVfpExpressionBinding(binding); if (isFilterBinding) { var expression = binding.Expression; foreach (var cursorName in _xmlToCursorsToBeRemoved) { expression = XmlToCursorExpressionRemover.Remove(expression, cursorName); } _xmlToCursorsToBeRemoved.Clear(); _filterBindings.Pop(); binding = expression.BindAs(binding.Variable.VariableName); } if (!_filterBindings.Any()) { return(binding); } var filterBinding = _filterBindings.Peek(); if (filterBinding == null) { return(binding); } var scan = binding.Expression as VfpScanExpression; if (scan == null) { return(binding); } if (!_xmlToCursors.ContainsKey(binding.VariableName)) { return(binding); } var xmlToCursors = _xmlToCursors[binding.VariableName]; if (!xmlToCursors.Any()) { return(binding); } foreach (var xmlToCursor in xmlToCursors) { var xmlToCursorExpression = xmlToCursor.XmlToCursor; _count++; var variableReference = xmlToCursorExpression.ItemType.ToTypeUsage().Variable("Xml" + _count); var xmlToCursorScan = VfpExpressionBuilder.XmlToCursorScan(xmlToCursorExpression.Parameter, xmlToCursorExpression.CursorName + "_j"); var xmlToCursorBinding = xmlToCursorScan.BindAs(variableReference.VariableName); var xmlToCursorProperty = VfpExpressionBuilder.XmlToCursorProperty(variableReference.ResultType, variableReference); var scanProperty = GetScanProperty(binding.Variable, xmlToCursorExpression.Property); var comparison = scanProperty.ExpressionEquals(xmlToCursorProperty); var joinVariableReference = binding.VariableType.Variable(binding.VariableName); var joinExpression = binding.InnerJoin(xmlToCursorBinding, comparison, binding.Expression.ResultType); _xmlToCursorsToBeRemoved.Add(xmlToCursorExpression.CursorName); binding = joinExpression.BindAs(joinVariableReference.VariableName); } return(binding); }