Example #1
0
        /// <summary>
        /// The simple part: converts an expression to SQL
        /// This is not used for FROM clause
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="queryContext"></param>
        /// <returns></returns>
        protected virtual SqlStatement BuildExpression(Expression expression, QueryContext queryContext)
        {
            var sqlProvider       = queryContext.DataContext.Vendor.SqlProvider;
            var currentPrecedence = ExpressionQualifier.GetPrecedence(expression);
            // first convert operands
            var operands        = expression.GetOperands();
            var literalOperands = new List <SqlStatement>();

            foreach (var operand in operands)
            {
                var operandPrecedence = ExpressionQualifier.GetPrecedence(operand);
                var literalOperand    = BuildExpression(operand, queryContext);
                if (operandPrecedence > currentPrecedence)
                {
                    literalOperand = sqlProvider.GetParenthesis(literalOperand);
                }
                literalOperands.Add(literalOperand);
            }

            // then converts expression
            if (expression is SpecialExpression)
            {
                return(sqlProvider.GetLiteral(((SpecialExpression)expression).SpecialNodeType, literalOperands));
            }
            if (expression is EntitySetExpression)
            {
                expression = ((EntitySetExpression)expression).TableExpression;
            }
            if (expression is TableExpression)
            {
                var tableExpression = (TableExpression)expression;
                if (tableExpression.Alias != null) // if we have an alias, use it
                {
                    return(sqlProvider.GetColumn(sqlProvider.GetTableAlias(tableExpression.Alias),
                                                 sqlProvider.GetColumns()));
                }
                return(sqlProvider.GetColumns());
            }
            if (expression is ColumnExpression)
            {
                var columnExpression = (ColumnExpression)expression;
                if (columnExpression.Table.Alias != null)
                {
                    return(sqlProvider.GetColumn(sqlProvider.GetTableAlias(columnExpression.Table.Alias),
                                                 columnExpression.Name));
                }
                return(sqlProvider.GetColumn(columnExpression.Name));
            }
            if (expression is InputParameterExpression)
            {
                var inputParameterExpression = (InputParameterExpression)expression;
                if (expression.Type.IsArray)
                {
                    int i = 0;
                    List <SqlStatement> inputParameters = new List <SqlStatement>();
                    foreach (object p in (Array)inputParameterExpression.GetValue())
                    {
                        inputParameters.Add(new SqlStatement(new SqlParameterPart(sqlProvider.GetParameterName(inputParameterExpression.Alias + i.ToString()),
                                                                                  inputParameterExpression.Alias + i.ToString())));
                        ++i;
                    }
                    return(new SqlStatement(sqlProvider.GetLiteral(inputParameters.ToArray())));
                }
                return
                    (new SqlStatement(new SqlParameterPart(sqlProvider.GetParameterName(inputParameterExpression.Alias),
                                                           inputParameterExpression.Alias)));
            }
            if (expression is SelectExpression)
            {
                return(Build((SelectExpression)expression, queryContext));
            }
            if (expression is ConstantExpression)
            {
                return(sqlProvider.GetLiteral(((ConstantExpression)expression).Value));
            }
            if (expression is GroupExpression)
            {
                return(BuildExpression(((GroupExpression)expression).GroupedExpression, queryContext));
            }

            StartIndexOffsetExpression indexExpression = expression as StartIndexOffsetExpression;

            if (indexExpression != null)
            {
                if (indexExpression.StartsAtOne)
                {
                    literalOperands.Add(BuildExpression(Expression.Constant(1), queryContext));
                    return(sqlProvider.GetLiteral(ExpressionType.Add, literalOperands));
                }
                else
                {
                    return(literalOperands.First());
                }
            }
            if (expression.NodeType == ExpressionType.Convert || expression.NodeType == ExpressionType.ConvertChecked)
            {
                var unaryExpression = (UnaryExpression)expression;
                var firstOperand    = literalOperands.First();
                if (IsConversionRequired(unaryExpression))
                {
                    return(sqlProvider.GetLiteralConvert(firstOperand, unaryExpression.Type));
                }
                return(firstOperand);
            }
            return(sqlProvider.GetLiteral(expression.NodeType, literalOperands));
        }
Example #2
0
        protected virtual SqlStatement BuildExpression(Expression expression, bool allowNull = false)
        {
            if (expression == null)
            {
                Util.Check(allowNull, "Expression argument may not be null.");
                return(null);
            }
            if (expression is ConstantExpression)
            {
                return(_sqlProvider.GetLiteral(((ConstantExpression)expression).Value));
            }

            var currentPrecedence = ExpressionUtil.GetPrecedence(expression);
            // first convert operands
            var operands        = expression.GetOperands();
            var literalOperands = new List <SqlStatement>();

            foreach (var operand in operands)
            {
                var operandPrecedence = ExpressionUtil.GetPrecedence(operand);
                var literalOperand    = BuildExpression(operand);
                if (operandPrecedence > currentPrecedence)
                {
                    literalOperand = _sqlProvider.GetParenthesis(literalOperand);
                }
                literalOperands.Add(literalOperand);
            }

            if (expression is AliasedExpression)
            {
                var aliasExpr = (AliasedExpression)expression;
                return(BuildExpression(aliasExpr.Expression)); //Alias will be added later
            }
            // then converts expression
            if (expression is SqlFunctionExpression)
            {
                var specExpr = (SqlFunctionExpression)expression;
                //RI: Special case for multiple "*" operands
                if (specExpr.FunctionType == SqlFunctionType.Count && literalOperands.Count > 0)
                {
                    literalOperands.Clear();
                    literalOperands.Add("*");
                }
                return(_sqlProvider.GetSqlFunction(specExpr.FunctionType, specExpr.ForceIgnoreCase, literalOperands));
            }
            if (expression is TableExpression)
            {
                var tableExpression = (TableExpression)expression;
                if (tableExpression.Alias != null) // if we have an alias, use it
                {
                    return(_sqlProvider.GetColumn(_sqlProvider.GetTableAlias(tableExpression.Alias),
                                                  _sqlProvider.GetColumns()));
                }
                return(_sqlProvider.GetColumns());
            }

            //RI: We might have NewExpression here! Query: (from b in books select new {b.Title}).Count();
            // in this case the NewExpression is 'hidden' inside subquery and it is not visible to CutOutOperands
            // We just return list of arguments (columns) of New expression
            if (expression is NewExpression)
            {
                return(new SqlStatement(literalOperands));
            }
            //RI: adding this
            if (expression is MetaTableExpression)
            {
                var metaTable = (MetaTableExpression)expression;
                return(_sqlProvider.GetColumns());
            }

            if (expression is ColumnExpression)
            {
                var columnExpression = (ColumnExpression)expression;
                if (columnExpression.Table.Alias != null)
                {
                    return(_sqlProvider.GetColumn(_sqlProvider.GetTableAlias(columnExpression.Table.Alias),
                                                  columnExpression.Name));
                }
                //RI: changed this to keep output type
                var sqlPart = new SqlLiteralPart(_sqlProvider.GetColumn(columnExpression.Name), expression.Type);
                return(new SqlStatement(sqlPart));
                //return _sqlProvider.GetColumn(columnExpression.Name);
            }

            if (expression is ExternalValueExpression)
            {
                var extValue = (ExternalValueExpression)expression;

                switch (extValue.SqlUse)
                {
                case ExternalValueSqlUse.Literal:
                    var sql = _sqlProvider.GetLiteral(extValue.LiteralValue);
                    return(sql);

                case ExternalValueSqlUse.Parameter:
                    // In SQL templates the first 2 args are reserved for { and } symbols
                    return(_sqlProvider.GetParameter(extValue));

                default:
                    // we should never get here
                    Util.Throw("LINQ engine error: encountered ExternalValueExpression with invalid Usage type: {0}, Expression: {1}",
                               extValue.SqlUse, extValue.SourceExpression);
                    return(null); //never happens
                }
            }
            if (expression is SelectExpression)
            {
                return(BuildSelectSql((SelectExpression)expression));
            }
            if (expression is GroupExpression)
            {
                return(BuildExpression(((GroupExpression)expression).GroupedExpression));
            }

            StartIndexOffsetExpression indexExpression = expression as StartIndexOffsetExpression;

            if (indexExpression != null)
            {
                if (indexExpression.StartsAtOne)
                {
                    literalOperands.Add(BuildExpression(Expression.Constant(1)));
                    return(_sqlProvider.GetLiteral(ExpressionType.Add, literalOperands));
                }
                else
                {
                    return(literalOperands.First());
                }
            }
            if (expression.NodeType == ExpressionType.Convert || expression.NodeType == ExpressionType.ConvertChecked)
            {
                var unaryExpression = (UnaryExpression)expression;
                var firstOperand    = literalOperands.First();
                if (IsConversionRequired(unaryExpression))
                {
                    return(_sqlProvider.GetLiteralConvert(firstOperand, unaryExpression.Type));
                }
                return(firstOperand);
            }
            if (expression is BinaryExpression || expression is UnaryExpression)
            {
                return(_sqlProvider.GetLiteral(expression.NodeType, literalOperands));
            }

            if (expression is TableFilterExpression)
            {
                return(_sqlProvider.GetTableFilter((TableFilterExpression)expression));
            }

            return(_sqlProvider.GetLiteral(expression.NodeType, literalOperands));
        }