protected override Expression VisitSqlConstant(SqlConstantExpression sqlConstantExpression) { _relationalCommandBuilder .Append(sqlConstantExpression.TypeMapping.GenerateSqlLiteral(sqlConstantExpression.Value)); return(sqlConstantExpression); }
public NpgsqlStringMethodTranslator(ISqlExpressionFactory sqlExpressionFactory, NpgsqlTypeMappingSource npgsqlTypeMappingSource) { _sqlExpressionFactory = sqlExpressionFactory; _whitespace = _sqlExpressionFactory.Constant( @" \t\n\r", // TODO: Complete this npgsqlTypeMappingSource.EStringTypeMapping); }
public override void Constant(SqlConstantExpression node) { if (node.Value == null) { SqlBuilder.Append("Null"); } else { var type = node.Value.GetType(); var typeCode = Type.GetTypeCode(type); switch (typeCode) { case TypeCode.DateTime: SqlBuilder.Append("'").Append(((DateTime)node.Value).ToString("yyyy-MM-dd HH:mm:ss")).Append("'"); break; case TypeCode.String: SqlBuilder.Append("'").Append(node.Value).Append("'"); break; default: SqlBuilder.Append(node.Value); break; } } }
protected override Expression VisitSqlConstant(SqlConstantExpression sqlConstantExpression) { Check.NotNull(sqlConstantExpression, nameof(sqlConstantExpression)); _isNullable = sqlConstantExpression.Value == null; return(sqlConstantExpression); }
public override SqlExpression VisitConstant(SqlConstantExpression constant) { var value = constant.Value; // TODO: if this is an array ... return(base.VisitConstant(constant)); }
/// <summary> /// Visits the specified SQL constant expression. /// </summary> /// <param name="sqlConstantExpression">The SQL constant expression.</param> /// <returns> /// Returns processed value from espression. /// </returns> string ISqlVisitor <string> .Visit(SqlConstantExpression sqlConstantExpression) { if (!_paremeters.ContainsKey(sqlConstantExpression)) { var paramName = "@p" + (_parameterCounter++); _paremeters.Add(sqlConstantExpression, new SqlParameter(sqlConstantExpression, paramName)); } return(_paremeters[sqlConstantExpression].Name); }
public override SqlExpression VisitConstant(SqlConstantExpression constant) { if (constant.Value.Type is QueryType) { hasSubQuery = true; } return(base.VisitConstant(constant)); }
public NpgsqlStringMethodTranslator( [NotNull] NpgsqlTypeMappingSource typeMappingSource, [NotNull] ISqlExpressionFactory sqlExpressionFactory) { _sqlExpressionFactory = sqlExpressionFactory; _whitespace = _sqlExpressionFactory.Constant( @" \t\n\r", // TODO: Complete this typeMappingSource.EStringTypeMapping); _textTypeMapping = (RelationalTypeMapping)typeMappingSource.FindMapping(typeof(string)); }
public NpgsqlStringMethodTranslator( NpgsqlTypeMappingSource typeMappingSource, ISqlExpressionFactory sqlExpressionFactory, IModel model) { _sqlExpressionFactory = sqlExpressionFactory; _whitespace = _sqlExpressionFactory.Constant( @" \t\n\r", // TODO: Complete this typeMappingSource.EStringTypeMapping); _textTypeMapping = typeMappingSource.FindMapping(typeof(string), model) !; }
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.HasDbFunction( typeof(DbJsonValueExtensions).GetMethod(nameof(DbJsonValueExtensions.JSON_VALUE), new System.Type[] { typeof(string), typeof(string) })) .HasTranslation(args => { var arguments = args.ToList(); SqlUnaryExpression sqlUnaryExp = null; SqlConstantExpression sqlConstExp = null; string sql = ""; if (arguments[0] is SqlUnaryExpression) { sqlUnaryExp = arguments[0] as SqlUnaryExpression; } if (arguments[1] is SqlConstantExpression) { sqlConstExp = arguments[1] as SqlConstantExpression; } if (sqlUnaryExp != null) { var sqlColumnExp = sqlUnaryExp.Operand as ColumnExpression; return(new SqlFunctionExpression( null, null, "JSON_VALUE", false, new[] { sqlColumnExp as SqlExpression, sqlConstExp }, true, typeof(string), null )); } else { return(new SqlFunctionExpression( null, null, "JSON_VALUE", false, args, true, typeof(string), null )); } }); modelBuilder.ConfigureMGSurveyDbContext(_mgSurveyStoreOptions); base.OnModelCreating(modelBuilder); }
protected override SqlExpression Visit(SqlConstantExpression expression) { if (expression.Value is bool) { var nodeType = ((bool)expression.Value) ? SqlNodeType.Equal : SqlNodeType.NotEqual; return(new SqlBinaryExpression(nodeType, new SqlConstantExpression(typeof(int), 1), new SqlConstantExpression(typeof(int), 1))); } return(base.Visit(expression)); }
private SqlExpression SimplifyBoolConstantComparisonExpression( ExpressionType operatorType, SqlExpression left, SqlExpression right, SqlConstantExpression leftBoolConstant, SqlConstantExpression rightBoolConstant, RelationalTypeMapping typeMapping) { if (leftBoolConstant != null && rightBoolConstant != null) { return(operatorType == ExpressionType.Equal ? SqlExpressionFactory.Constant((bool)leftBoolConstant.Value == (bool)rightBoolConstant.Value, typeMapping) : SqlExpressionFactory.Constant((bool)leftBoolConstant.Value != (bool)rightBoolConstant.Value, typeMapping)); } if (rightBoolConstant != null && CanOptimize(left)) { // a == true -> a // a == false -> !a // a != true -> !a // a != false -> a // only correct when f(x) can't be null return(operatorType == ExpressionType.Equal ? (bool)rightBoolConstant.Value ? left : SimplifyUnaryExpression(ExpressionType.Not, left, typeof(bool), typeMapping) : (bool)rightBoolConstant.Value ? SimplifyUnaryExpression(ExpressionType.Not, left, typeof(bool), typeMapping) : left); } if (leftBoolConstant != null && CanOptimize(right)) { // true == a -> a // false == a -> !a // true != a -> !a // false != a -> a // only correct when a can't be null return(operatorType == ExpressionType.Equal ? (bool)leftBoolConstant.Value ? right : SimplifyUnaryExpression(ExpressionType.Not, right, typeof(bool), typeMapping) : (bool)leftBoolConstant.Value ? SimplifyUnaryExpression(ExpressionType.Not, right, typeof(bool), typeMapping) : right); } return(SqlExpressionFactory.MakeBinary(operatorType, left, right, typeMapping));
private string GenerateConstant(SqlConstantExpression constant) { switch (constant.FieldType) { case FieldType.Int: case FieldType.Double: return(constant.Value.ToString()); case FieldType.String: case FieldType.Char: return($"'{constant.Value.ToString()}'"); } throw new NotImplementedException($"Cannot generate constant of type {constant.FieldType}"); }
public override SqlExpression VisitConstant(SqlConstantExpression constant) { var value = constant.Value; if (!value.IsNull && value.Value is SqlQueryObject && ((SqlQueryObject)value.Value).QueryPlan != null) { var queryObject = (SqlQueryObject)value.Value; var planNode = queryObject.QueryPlan; TableNames = planNode.DiscoverTableNames(); } return(base.VisitConstant(constant)); }
public override SqlExpression VisitConstant(SqlConstantExpression constant) { var value = constant.Value; if (value.Type is ArrayType) { var array = (SqlArray)value.Value; foreach (var element in array) { columnNames.AddRange(element.DiscoverReferences()); } } return(base.VisitConstant(constant)); }
protected override Expression VisitSqlConstant(SqlConstantExpression sqlConstantExpression) { var shouldExplicitStringLiteralTypes = _fbOptions.ExplicitStringLiteralTypes && sqlConstantExpression.Type == typeof(string); if (shouldExplicitStringLiteralTypes) { Sql.Append("CAST("); } base.VisitSqlConstant(sqlConstantExpression); if (shouldExplicitStringLiteralTypes) { Sql.Append(" AS "); Sql.Append((Dependencies.SqlGenerationHelper as IFbSqlGenerationHelper).StringLiteralQueryType(sqlConstantExpression.Value as string)); Sql.Append(")"); } return(sqlConstantExpression); }
public virtual SqlExpression ApplyTypeMapping(SqlExpression sqlExpression, RelationalTypeMapping typeMapping) { if (sqlExpression == null || sqlExpression.TypeMapping != null) { return(sqlExpression); } return(sqlExpression switch { CaseExpression e => ApplyTypeMappingOnCase(e, typeMapping), LikeExpression e => ApplyTypeMappingOnLike(e), SqlBinaryExpression e => ApplyTypeMappingOnSqlBinary(e, typeMapping), SqlUnaryExpression e => ApplyTypeMappingOnSqlUnary(e, typeMapping), SqlConstantExpression e => e.ApplyTypeMapping(typeMapping), SqlFragmentExpression e => e, SqlFunctionExpression e => e.ApplyTypeMapping(typeMapping), SqlParameterExpression e => e.ApplyTypeMapping(typeMapping), _ => sqlExpression });
protected internal override Expression VisitSqlConstant(SqlConstantExpression c) { if (c.Value == null) { sb.Append("NULL"); } else { if (!schema.Settings.IsDbType(c.Value.GetType().UnNullify())) { throw new NotSupportedException(string.Format("The constant for {0} is not supported", c.Value)); } if (!isPostgres && c.Value.Equals(true)) { sb.Append('1'); } else if (!isPostgres && c.Value.Equals(false)) { sb.Append('0'); } else if (c.Value is string s) { sb.Append(s == "" ? "''" : ("'" + s + "'")); } else if (c.Value is TimeSpan ts) { sb.Append(@$ "CONVERT(time, '{ts}')"); } else if (ReflectionTools.IsDecimalNumber(c.Value.GetType())) { sb.Append(((IFormattable)c.Value).ToString("0.00####", CultureInfo.InvariantCulture)); } else { sb.Append(c.ToString()); } } return(c); }
/// <inheritdoc /> public virtual SqlExpression ApplyTypeMapping(SqlExpression sqlExpression, RelationalTypeMapping typeMapping) { #pragma warning disable IDE0046 // Convert to conditional expression if (sqlExpression == null #pragma warning restore IDE0046 // Convert to conditional expression || sqlExpression.TypeMapping != null) { return(sqlExpression); } return(sqlExpression switch { CaseExpression e => ApplyTypeMappingOnCase(e, typeMapping), CollateExpression e => ApplyTypeMappingOnCollate(e, typeMapping), LikeExpression e => ApplyTypeMappingOnLike(e), SqlBinaryExpression e => ApplyTypeMappingOnSqlBinary(e, typeMapping), SqlUnaryExpression e => ApplyTypeMappingOnSqlUnary(e, typeMapping), SqlConstantExpression e => e.ApplyTypeMapping(typeMapping), SqlFragmentExpression e => e, SqlFunctionExpression e => e.ApplyTypeMapping(typeMapping), SqlParameterExpression e => e.ApplyTypeMapping(typeMapping), _ => sqlExpression });
private static string BuildConstant(SqlConstantExpression constant) { if (constant.Constant == null) { return("null"); } switch (constant.ReturnType.SqlTypeEnum) { case SqlTypeEnum.Boolean: return(((bool)constant.Constant) ? "1" : "0"); case SqlTypeEnum.Decimal: case SqlTypeEnum.Integer: return(((IConvertible)constant.Constant).ToString(USCultureInfo.Value)); case SqlTypeEnum.Varchar: return($"'{constant.Constant.ToString()}'"); case SqlTypeEnum.DateTime: return($"'{((DateTime)constant.Constant):yyyy-MM-dd}'"); } throw new NotImplementedException("Constant builder"); }
protected abstract Expression VisitSqlConstant(SqlConstantExpression sqlConstantExpression);
protected virtual void ParseParameter(SqlConstantExpression constant) { builder.AppendValue(constant.Value); }
private SqlConstantExpression VisitSqlConstantExpression(SqlConstantExpression sqlConstantExpression) { _isNullable = sqlConstantExpression.Value == null; return(sqlConstantExpression); }
protected override Expression VisitSqlConstant(SqlConstantExpression sqlConstantExpression) { return(sqlConstantExpression); }
protected virtual SqlExpression Visit(SqlConstantExpression expression) { return(expression); }
protected override Expression VisitSqlConstant(SqlConstantExpression sqlConstantExpression) { return(ApplyConversion(sqlConstantExpression, condition: false)); }
protected override SqlExpression Visit(SqlConstantExpression expression) { sql.Append(FormatConstant(expression.Value)); return(expression); }
internal static void PatchInExpressions(this InExpression expression, RelationalQueryContext context, List <string> usedParams = null) { if (context is null || expression is null) { return; } expression.Item.PatchInExpressions(context, usedParams); expression.Subquery?.PatchInExpressions(context, usedParams); if (expression.Values is null) { return; } // The version of VisitIn in EF Core 3.1.1 has two requirements. // 1) The Values must be from a SqlConstantExpression // 2) The Value from the SqlConstantExpression must be castable to IEnumerable<object> var currentValue = expression.Values; switch (currentValue) { case SqlParameterExpression paramEx: { // Fix issue 1 & 2 by grabbing the parameter and converting to a constant IEnumerable<object>. var value = context.ParameterValues[paramEx.Name]; if (usedParams != null && !usedParams.Contains(paramEx.Name)) { usedParams.Add(paramEx.Name); } var newVal = (value as IEnumerable)?.Cast <object>().ToArray() ?? new object[0]; var newEx = new SqlConstantExpression(Expression.Constant(newVal), paramEx.TypeMapping); if (!expression.SetNonPublicProperty("Values", newEx)) { throw new InvalidOperationException("Could not update Values for InExpression."); } break; } case SqlConstantExpression sqlConstEx: { // Fix issue 2, castable to IEnumerable<object> var constEx = sqlConstEx.GetNonPublicField <ConstantExpression>("_constantExpression"); var newVal = ((IEnumerable)constEx.Value).Cast <object>().ToArray(); var newEx = new SqlConstantExpression(Expression.Constant(newVal), sqlConstEx.TypeMapping); if (!expression.SetNonPublicProperty("Values", newEx)) { throw new InvalidOperationException("Could not update Values for InExpression."); } break; } default: throw new InvalidOperationException($"Don't know how to convert {currentValue.GetType()} to SqlConstantExpression."); } }
protected virtual Expression VisitSqlConstant(SqlConstantExpression sce) { return sce; }
public virtual SqlExpression Translate( SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { if (_indexOfMethodInfo.Equals(method)) { return(new MySqlStringComparisonMethodTranslator(_sqlExpressionFactory, _options) .MakeIndexOfExpression(instance, arguments[0])); } if (_replaceMethodInfo.Equals(method)) { var stringTypeMapping = ExpressionExtensions.InferTypeMapping(instance, arguments[0], arguments[1]); var replacementArgument = _sqlExpressionFactory.ApplyTypeMapping(arguments[1], stringTypeMapping); var replaceCall = _sqlExpressionFactory.NullableFunction( "REPLACE", new[] { _sqlExpressionFactory.ApplyTypeMapping(instance, stringTypeMapping), _sqlExpressionFactory.ApplyTypeMapping(arguments[0], stringTypeMapping), _sqlExpressionFactory.ApplyTypeMapping(arguments[1], stringTypeMapping) }, method.ReturnType, stringTypeMapping); // Due to a bug in all versions of MariaDB and all MySQL versions below 8.0.x (exact version that fixed the issue is // currently unclear), using `null` as the replacement argument in a REPLACE() call leads to unexpected results, in which // the call returns the original string, instead of `null`. // See https://jira.mariadb.org/browse/MDEV-24263 return(_sqlExpressionFactory.Case( new[] { new CaseWhenClause( _sqlExpressionFactory.IsNotNull(replacementArgument), replaceCall) }, _sqlExpressionFactory.Constant(null, RelationalTypeMapping.NullMapping))); } if (_toLowerMethodInfo.Equals(method) || _toUpperMethodInfo.Equals(method)) { return(_sqlExpressionFactory.NullableFunction( _toLowerMethodInfo.Equals(method) ? "LOWER" : "UPPER", new[] { instance }, method.ReturnType, instance.TypeMapping)); } if (_substringMethodInfoWithOneArg.Equals(method)) { return(_sqlExpressionFactory.Function( "SUBSTRING", new[] { instance, _sqlExpressionFactory.Add( arguments[0], _sqlExpressionFactory.Constant(1)), _sqlExpressionFactory.NullableFunction( "CHAR_LENGTH", new[] { instance }, typeof(int)) }, nullable: true, argumentsPropagateNullability: new[] { true, true, true }, method.ReturnType, instance.TypeMapping)); } if (_substringMethodInfoWithTwoArgs.Equals(method)) { return(_sqlExpressionFactory.NullableFunction( "SUBSTRING", new[] { instance, _sqlExpressionFactory.Add( arguments[0], _sqlExpressionFactory.Constant(1)), arguments[1] }, method.ReturnType, instance.TypeMapping)); } if (_isNullOrWhiteSpaceMethodInfo.Equals(method)) { return(_sqlExpressionFactory.OrElse( _sqlExpressionFactory.IsNull(arguments[0]), _sqlExpressionFactory.Equal( ProcessTrimMethod(arguments[0], null, null), _sqlExpressionFactory.Constant(string.Empty)))); } if (_trimStartMethodInfoWithoutArgs?.Equals(method) == true || _trimStartMethodInfoWithCharArg?.Equals(method) == true || _trimStartMethodInfoWithCharArrayArg.Equals(method)) { return(ProcessTrimMethod(instance, arguments.Count > 0 ? arguments[0] : null, "LEADING")); } if (_trimEndMethodInfoWithoutArgs?.Equals(method) == true || _trimEndMethodInfoWithCharArg?.Equals(method) == true || _trimEndMethodInfoWithCharArrayArg.Equals(method)) { return(ProcessTrimMethod(instance, arguments.Count > 0 ? arguments[0] : null, "TRAILING")); } if (_trimMethodInfoWithoutArgs?.Equals(method) == true || _trimMethodInfoWithCharArg?.Equals(method) == true || _trimMethodInfoWithCharArrayArg.Equals(method)) { return(ProcessTrimMethod(instance, arguments.Count > 0 ? arguments[0] : null, null)); } if (_containsMethodInfo.Equals(method)) { return(new MySqlStringComparisonMethodTranslator(_sqlExpressionFactory, _options) .MakeContainsExpression(instance, arguments[0])); } if (_startsWithMethodInfo.Equals(method)) { return(new MySqlStringComparisonMethodTranslator(_sqlExpressionFactory, _options) .MakeStartsWithExpression(instance, arguments[0])); } if (_endsWithMethodInfo.Equals(method)) { return(new MySqlStringComparisonMethodTranslator(_sqlExpressionFactory, _options) .MakeEndsWithExpression(instance, arguments[0])); } if (_padLeftWithOneArg.Equals(method)) { return(TranslatePadLeftRight( true, instance, arguments[0], _sqlExpressionFactory.Constant(" "), method.ReturnType)); } if (_padRightWithOneArg.Equals(method)) { return(TranslatePadLeftRight( false, instance, arguments[0], _sqlExpressionFactory.Constant(" "), method.ReturnType)); } if (_padLeftWithTwoArgs.Equals(method)) { return(TranslatePadLeftRight( true, instance, arguments[0], arguments[1], method.ReturnType)); } if (_padRightWithTwoArgs.Equals(method)) { return(TranslatePadLeftRight( false, instance, arguments[0], arguments[1], method.ReturnType)); } if (_firstOrDefaultMethodInfoWithoutArgs.Equals(method)) { return(_sqlExpressionFactory.NullableFunction( "SUBSTRING", new[] { arguments[0], _sqlExpressionFactory.Constant(1), _sqlExpressionFactory.Constant(1) }, method.ReturnType)); } if (_lastOrDefaultMethodInfoWithoutArgs.Equals(method)) { return(_sqlExpressionFactory.NullableFunction( "SUBSTRING", new[] { arguments[0], _sqlExpressionFactory.NullableFunction( "CHAR_LENGTH", new[] { arguments[0] }, typeof(int)), _sqlExpressionFactory.Constant(1) }, method.ReturnType)); } if (_removeMethodInfoWithOneArg.Equals(method)) { return(_sqlExpressionFactory.NullableFunction( "SUBSTRING", new[] { instance, _sqlExpressionFactory.Constant(1), arguments[0], }, method.ReturnType, instance.TypeMapping)); } if (_removeMethodInfoWithTwoArgs.Equals(method)) { var firstSubString = _sqlExpressionFactory.NullableFunction( "SUBSTRING", new[] { instance, _sqlExpressionFactory.Constant(1), arguments[0] }, method.ReturnType, instance.TypeMapping); var secondSubString = _sqlExpressionFactory.NullableFunction( "SUBSTRING", new[] { instance, _sqlExpressionFactory.Add( _sqlExpressionFactory.Add( arguments[0], arguments[1]), _sqlExpressionFactory.Constant(1)), _sqlExpressionFactory.Subtract( _sqlExpressionFactory.NullableFunction( "CHAR_LENGTH", new[] { instance }, typeof(int)), _sqlExpressionFactory.Add( arguments[0], arguments[1])), }, method.ReturnType, instance.TypeMapping); var concat = _sqlExpressionFactory.NullableFunction( "CONCAT", new[] { firstSubString, secondSubString }, method.ReturnType, instance.TypeMapping); return(concat); } if (_concatMethodInfos.Contains( (method.IsGenericMethod ? method.GetGenericMethodDefinition() : null) ?? method)) { // Handle // string[] // IEnumerable<string> // object[] // IEnumerable<T> // and // string, ... // object, ... // // Some call signature variants can never reach this code, because they will be directly called and thus only their result // is translated. var concatArguments = arguments[0] is MySqlComplexFunctionArgumentExpression mySqlComplexFunctionArgumentExpression ? new SqlExpression[] { mySqlComplexFunctionArgumentExpression } : arguments.Select( e => e switch { SqlConstantExpression c => _sqlExpressionFactory.Constant(c.Value.ToString()), SqlParameterExpression p => p.ApplyTypeMapping( ((MySqlStringTypeMapping)_typeMappingSource.GetMapping(typeof(string))).Clone(forceToString: true)), _ => e, })
/// <summary> /// Visits the children of the sql constant expression. /// </summary> /// <param name="sqlConstantExpression"> The expression to visit. </param> /// <returns> The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. </returns> protected abstract Expression VisitSqlConstant([NotNull] SqlConstantExpression sqlConstantExpression);
protected override Expression VisitSqlConstant(SqlConstantExpression c) { if (c.Value == null) sb.Append("NULL"); else { if (!Schema.Current.Settings.IsDbType(c.Value.GetType().UnNullify())) throw new NotSupportedException(string.Format("The constant for {0} is not supported", c.Value)); if (c.Value.Equals(true)) sb.Append("1"); else if (c.Value.Equals(false)) sb.Append("0"); else if (c.Value is string) sb.Append(((string)c.Value == "") ? "''" : ("'" + c.Value + "'")); else sb.Append(c.ToString()); } return c; }