Esempio n. 1
0
        public override ISqlPredicate ConvertPredicateImpl(ISqlPredicate predicate, ConvertVisitor <RunOptimizationContext> visitor)
        {
            if (predicate is SqlPredicate.ExprExpr exprExpr)
            {
                var leftType  = QueryHelper.GetDbDataType(exprExpr.Expr1);
                var rightType = QueryHelper.GetDbDataType(exprExpr.Expr2);

                if ((IsDateTime(leftType) || IsDateTime(rightType)) &&
                    !(exprExpr.Expr1.TryEvaluateExpression(visitor.Context.OptimizationContext.Context, out var value1) && value1 == null ||
                      exprExpr.Expr2.TryEvaluateExpression(visitor.Context.OptimizationContext.Context, out var value2) && value2 == null))
                {
                    if (!(exprExpr.Expr1 is SqlFunction func1 && (func1.Name == PseudoFunctions.CONVERT || func1.Name == "DateTime")))
                    {
                        var left = PseudoFunctions.MakeConvert(new SqlDataType(leftType), new SqlDataType(leftType), exprExpr.Expr1);
                        exprExpr = new SqlPredicate.ExprExpr(left, exprExpr.Operator, exprExpr.Expr2, null);
                    }

                    if (!(exprExpr.Expr2 is SqlFunction func2 && (func2.Name == PseudoFunctions.CONVERT || func2.Name == "DateTime")))
                    {
                        var right = PseudoFunctions.MakeConvert(new SqlDataType(rightType), new SqlDataType(rightType), exprExpr.Expr2);
                        exprExpr = new SqlPredicate.ExprExpr(exprExpr.Expr1, exprExpr.Operator, right, null);
                    }

                    predicate = exprExpr;
                }
            }

            predicate = base.ConvertPredicateImpl(predicate, visitor);
            return(predicate);
        }
Esempio n. 2
0
        public override ISqlPredicate ConvertSearchStringPredicate(SqlPredicate.SearchString predicate, ConvertVisitor <RunOptimizationContext> visitor)
        {
            ISqlExpression expr;

            var caseSensitive = predicate.CaseSensitive.EvaluateBoolExpression(visitor.Context.OptimizationContext.Context);

            // for explicit case-sensitive search we apply "CAST({0} AS BLOB)" to searched string as COLLATE's collation is character set-dependent
            switch (predicate.Kind)
            {
            case SqlPredicate.SearchString.SearchKind.EndsWith:
            {
                if (caseSensitive == false)
                {
                    predicate = new SqlPredicate.SearchString(
                        PseudoFunctions.MakeToLower(predicate.Expr1),
                        predicate.IsNot,
                        PseudoFunctions.MakeToLower(predicate.Expr2), predicate.Kind,
                        predicate.CaseSensitive);
                }
                else if (caseSensitive == true)
                {
                    predicate = new SqlPredicate.SearchString(
                        new SqlExpression(typeof(string), "CAST({0} AS BLOB)", Precedence.Primary, predicate.Expr1),
                        predicate.IsNot,
                        predicate.Expr2,
                        predicate.Kind,
                        predicate.CaseSensitive);
                }

                return(ConvertSearchStringPredicateViaLike(predicate, visitor));
            }

            case SqlPredicate.SearchString.SearchKind.StartsWith:
            {
                expr = new SqlExpression(typeof(bool),
                                         predicate.IsNot ? "{0} NOT STARTING WITH {1}" : "{0} STARTING WITH {1}",
                                         Precedence.Comparison,
                                         TryConvertToValue(
                                             caseSensitive == false
                                                                ? PseudoFunctions.MakeToLower(predicate.Expr1)
                                                                : caseSensitive == true
                                                                        ? new SqlExpression(typeof(string), "CAST({0} AS BLOB)", Precedence.Primary, predicate.Expr1)
                                                                        : predicate.Expr1,
                                             visitor.Context.OptimizationContext.Context),
                                         TryConvertToValue(
                                             caseSensitive == false
                                                                ? PseudoFunctions.MakeToLower(predicate.Expr2)
                                                                : predicate.Expr2, visitor.Context.OptimizationContext.Context))
                {
                    CanBeNull = false
                };
                break;
            }

            case SqlPredicate.SearchString.SearchKind.Contains:
            {
                if (caseSensitive == false)
                {
                    expr = new SqlExpression(typeof(bool),
                                             predicate.IsNot ? "{0} NOT CONTAINING {1}" : "{0} CONTAINING {1}",
                                             Precedence.Comparison,
                                             TryConvertToValue(predicate.Expr1, visitor.Context.OptimizationContext.Context),
                                             TryConvertToValue(predicate.Expr2, visitor.Context.OptimizationContext.Context))
                    {
                        CanBeNull = false
                    };
                }
                else
                {
                    if (caseSensitive == true)
                    {
                        predicate = new SqlPredicate.SearchString(
                            new SqlExpression(typeof(string), "CAST({0} AS BLOB)", Precedence.Primary, predicate.Expr1),
                            predicate.IsNot,
                            predicate.Expr2,
                            predicate.Kind,
                            new SqlValue(false));
                    }

                    return(ConvertSearchStringPredicateViaLike(predicate, visitor));
                }
                break;
            }

            default:
                throw new InvalidOperationException($"Unexpected predicate: {predicate.Kind}");
            }

            return(new SqlSearchCondition(new SqlCondition(false, new SqlPredicate.Expr(expr))));
        }