/// <summary> /// Evaluates the expression and reduces to a constant expression, /// whose value is then returned. /// </summary> /// <param name="expression">The expression to evaluate.</param> /// <param name="context">The context used to evaluate the expression.</param> /// <returns> /// Returns a <see cref="Field"/> is the result of the /// <see cref="SqlExpression.Evaluate(Deveel.Data.Sql.Expressions.EvaluateContext)"/> /// is a <see cref="SqlConstantExpression"/>. /// </returns> /// <exception cref="InvalidOperationException"> /// If the expression could not be evaluated or if the result of the /// evaluation is not a <see cref="SqlConstantExpression"/>. /// </exception> /// <seealso cref="SqlExpression.Evaluate(Deveel.Data.Sql.Expressions.EvaluateContext)"/> /// <seealso cref="SqlConstantExpression"/> /// <seealso cref="SqlConstantExpression.Value"/> public static Field EvaluateToConstant(this SqlExpression expression, EvaluateContext context) { var evalExp = expression.Evaluate(context); if (evalExp == null) { throw new InvalidOperationException(); } var constantExp = evalExp as SqlConstantExpression; if (constantExp == null) { throw new InvalidOperationException(); } return(constantExp.Value); }
public void BetweenDates() { const string sql = "TODATE('2001-02-12') BETWEEN TODATE('2000-01-20') AND TODATE('2003-01-01')"; SqlExpression expression = null; Assert.DoesNotThrow(() => expression = SqlExpression.Parse(sql)); Assert.IsNotNull(expression); Assert.IsInstanceOf <SqlBinaryExpression>(expression); Assert.AreEqual(SqlExpressionType.And, expression.ExpressionType); SqlExpression resultExpression = null; Assert.DoesNotThrow(() => resultExpression = expression.Evaluate()); Assert.IsNotNull(resultExpression); Assert.AreEqual(SqlExpressionType.Constant, resultExpression.ExpressionType); var value = ((SqlConstantExpression)resultExpression).Value; Assert.IsInstanceOf <BooleanType>(value.Type); Assert.AreEqual(SqlBoolean.True, (SqlBoolean)value.Value); }
public void BetweenNumerics() { const string sql = "22 BETWEEN 10 AND 54"; SqlExpression expression = null; Assert.DoesNotThrow(() => expression = SqlExpression.Parse(sql)); Assert.IsNotNull(expression); Assert.IsInstanceOf <SqlBinaryExpression>(expression); Assert.AreEqual(SqlExpressionType.And, expression.ExpressionType); SqlExpression resultExpression = null; Assert.DoesNotThrow(() => resultExpression = expression.Evaluate()); Assert.IsNotNull(resultExpression); Assert.AreEqual(SqlExpressionType.Constant, resultExpression.ExpressionType); var value = ((SqlConstantExpression)resultExpression).Value; Assert.IsInstanceOf <BooleanType>(value.Type); Assert.AreEqual(SqlBoolean.True, (SqlBoolean)value.Value); }
public void DateSmallerThanOtherDate() { const string text = "TODATE('2013-03-01') < TODATE('2013-05-02')"; SqlExpression expression = null; Assert.DoesNotThrow(() => expression = SqlExpression.Parse(text)); Assert.IsNotNull(expression); Assert.IsInstanceOf <SqlBinaryExpression>(expression); SqlExpression evaluated = null; Assert.DoesNotThrow(() => evaluated = expression.Evaluate()); Assert.IsNotNull(evaluated); Assert.IsInstanceOf <SqlConstantExpression>(evaluated); var value = ((SqlConstantExpression)evaluated).Value; Assert.IsInstanceOf <SqlBoolean>(value.Value); Assert.AreEqual(SqlBoolean.True, value.Value); }
public static ITable ExhaustiveSelect(this ITable table, IQueryContext context, SqlExpression expression) { var result = table; // Exit early if there's nothing in the table to select from int rowCount = table.RowCount; if (rowCount > 0) { var tableResolver = table.GetVariableResolver(); List<int> selectedSet = new List<int>(rowCount); foreach (var row in table) { int rowIndex = row.RowId.RowNumber; var rowResolver = tableResolver.ForRow(rowIndex); // Resolve expression into a constant. var exp = expression.Evaluate(context, rowResolver); if (exp.ExpressionType != SqlExpressionType.Constant) throw new NotSupportedException(); var value = ((SqlConstantExpression) exp).Value; // If resolved to true then include in the selected set. if (!value.IsNull && value.Type is BooleanType && value == true) { selectedSet.Add(rowIndex); } } result = new VirtualTable(table, selectedSet); ; } return result; }
public static ITable SimpleSelect(this ITable table, IQueryContext context, ObjectName columnName, SqlExpressionType op, SqlExpression exp) { // Find the row with the name given in the condition. int column = table.FindColumn(columnName); if (column == -1) throw new ArgumentException(String.Format("Unable to find the column {0} in the condition.", columnName.Name)); // If we are doing a sub-query search if (op.IsSubQuery()) { // We can only handle constant expressions in the RHS expression, and // we must assume that the RHS is a Expression[] array. if (exp.ExpressionType != SqlExpressionType.Constant && exp.ExpressionType != SqlExpressionType.Tuple) throw new ArgumentException(); IEnumerable<SqlExpression> list; if (exp.ExpressionType == SqlExpressionType.Constant) { var tob = ((SqlConstantExpression) exp).Value; if (tob.Type is ArrayType) { var array = (SqlArray) tob.Value; list = array; } else { throw new Exception("Error with format or RHS expression."); } } else { list = ((SqlTupleExpression) exp).Expressions; } // Construct a temporary table with a single column that we are // comparing to. var col = table.TableInfo[column]; var ttable = TemporaryTable.SingleColumnTable(table.DatabaseContext, col.ColumnName, col.ColumnType); foreach (var expression in list) { var rowNum = ttable.NewRow(); var evalExp = (SqlConstantExpression)expression.Evaluate(context, null, null); ttable.SetValue(rowNum, 0, evalExp.Value); } ttable.BuildIndexes(); // Perform the any/all sub-query on the constant table. return table.SelectAnyAllNonCorrelated(new[] { columnName }, op, ttable); } { if (!exp.IsConstant()) throw new ArgumentException("The search expression is not constant."); var evalExp = exp.Evaluate(context, null); if (evalExp.ExpressionType != SqlExpressionType.Constant) throw new InvalidOperationException(); var value = ((SqlConstantExpression) evalExp).Value; IEnumerable<int> rows; if (op == SqlExpressionType.Like || op == SqlExpressionType.NotLike /* TODO: || op.IsOfType(BinaryOperatorType.Regex)*/) { /* TODO: if (op.IsOfType(BinaryOperatorType.Regex)) { rows = SelectFromRegex(column, op, value); } else { */ rows = table.SelectFromPattern(column, op, value); } else { // Is the column we are searching on indexable? var colInfo = table.TableInfo[column]; if (!colInfo.IsIndexable) throw new InvalidOperationException(String.Format("Column {0} os type {1} cannot be searched.", colInfo.ColumnName, colInfo.ColumnType)); rows = table.SelectRows(column, op, value); } return new VirtualTable(table, rows.ToArray()) {SortColumn = column}; } }
private DataObject Evaluate(SqlExpression expression, IQueryContext queryContext) { var ignoreCase = queryContext.IgnoreIdentifiersCase(); // Resolve any variables to the table_def for this expression. expression = Table.TableInfo.ResolveColumns(ignoreCase, expression); // Get the variable resolver and evaluate over this data. IVariableResolver vresolver = VariableResolver; var reduced = expression.Evaluate(queryContext, vresolver, null); if (reduced.ExpressionType != SqlExpressionType.Constant) throw new InvalidOperationException("The DEFAULT expression of the column cannot be reduced to a constant"); return ((SqlConstantExpression) reduced).Value; }