public virtual VfpExpression Visit(VfpLimitExpression expression)
 {
     return(new VfpLimitExpression(expression.ResultType,
                                   expression.Argument.Accept(this),
                                   expression.Limit.Accept(this),
                                   expression.WithTies));
 }
        private static VfpLimitExpression GetVfpLimitExpression(VfpLimitExpression limitExpression, VfpProjectExpression projectExpression)
        {
            var keyMembers = GetKeyMembers(projectExpression);

            if (!keyMembers.Any())
            {
                return(null);
            }

            var sortBinding = GetSortBinding(keyMembers, projectExpression.Input, projectExpression);
            var newProject  = sortBinding.Project(projectExpression.Projection);

            return(new VfpLimitExpression(limitExpression.ResultType,
                                          newProject,
                                          limitExpression.Limit,
                                          limitExpression.WithTies));
        }
        private static VfpLimitExpression GetVfpLimitExpression(VfpLimitExpression limitExpression, VfpFilterExpression filterExpression)
        {
            var keyMembers = GetKeyMembers(filterExpression);

            if (!keyMembers.Any())
            {
                return(null);
            }

            var sortBinding = GetSortBinding(keyMembers, filterExpression.Input, filterExpression);
            var newFilter   = sortBinding.Filter(filterExpression.Predicate);

            return(new VfpLimitExpression(limitExpression.ResultType,
                                          newFilter,
                                          limitExpression.Limit,
                                          limitExpression.WithTies));
        }
        public override VfpExpression Visit(VfpLimitExpression expression)
        {
            var sortExpression = expression.Argument as VfpSortExpression;

            if (sortExpression == null)
            {
                var newLimitExpression = GetVfpLimitExpression(expression, expression.Argument as VfpProjectExpression) ??
                                         GetVfpLimitExpression(expression, expression.Argument as VfpFilterExpression) ??
                                         GetVfpLimitExpression(expression, expression.Argument as VfpScanExpression);

                if (newLimitExpression != null)
                {
                    return(base.Visit(newLimitExpression));
                }
            }

            return(base.Visit(expression));
        }
        private VfpLimitExpression GetVfpLimitExpression(VfpLimitExpression limitExpression, VfpScanExpression scanExpression)
        {
            if (scanExpression == null)
            {
                return(null);
            }

            var keyMembers = GetKeyMembers(scanExpression.Target.ElementType.KeyMembers);

            if (!keyMembers.Any())
            {
                return(null);
            }

            var variableReference = new VfpVariableReferenceExpression(scanExpression.ResultType, GetUniqueVariableName());
            var expressionBinding = new VfpExpressionBinding(scanExpression, variableReference);
            var sortClauses       = GetSortClauses(keyMembers, expressionBinding).ToList().AsReadOnly();
            var sortExpression    = new VfpSortExpression(scanExpression.ResultType, expressionBinding, sortClauses);

            return(new VfpLimitExpression(limitExpression.ResultType,
                                          sortExpression,
                                          limitExpression.Limit,
                                          limitExpression.WithTies));
        }