예제 #1
0
 /// <summary>
 /// Appends a single part, including (useless) optimizations
 /// </summary>
 /// <param name="parts"></param>
 /// <param name="index"></param>
 /// <param name="part"></param>
 public static void InsertPart(IList<SqlPart> parts, int index, SqlPart part)
 {
     // optimization if top part is a literal, and the one we're adding is a literal too
     // in this case, we combine both
     // (this is useless, just pretty)
     if (part is SqlLiteralPart && index > 0 && parts[index - 1] is SqlLiteralPart)
     {
         parts[index - 1] = new SqlLiteralPart(parts[index - 1].Sql + part.Sql);
     }
     else
         parts.Insert(index, part);
 }
예제 #2
0
 /// <summary>
 /// Appends a single part, including (useless) optimizations
 /// </summary>
 /// <param name="parts"></param>
 /// <param name="index"></param>
 /// <param name="part"></param>
 public static void InsertPart(IList <SqlPart> parts, int index, SqlPart part)
 {
     // optimization if top part is a literal, and the one we're adding is a literal too
     // in this case, we combine both
     // (this is useless, just pretty)
     if (part is SqlLiteralPart && index > 0 && parts[index - 1] is SqlLiteralPart)
     {
         parts[index - 1] = new SqlLiteralPart(parts[index - 1].Sql + part.Sql);
     }
     else
     {
         parts.Insert(index, part);
     }
 }
예제 #3
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));
        }
예제 #4
0
        protected virtual SqlStatement BuildExpression(Expression expression)
        {
            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);
        }