public void Logical(ResultSetBuilder left, ResultSetBuilder right, ExpressionType op) { if (op == ExpressionType.And) { _planHead = OptimizeIntersect(left._planHead, right._planHead); } else if (op == ExpressionType.Or) { if (left._planHead is TimestampRangePlanItem && right._planHead is TimestampRangePlanItem) { _planHead = left._planHead; _planHead.Timestamps.Union(right._planHead.Timestamps); return; } if (left._planHead is RowScanPlanItem && right._planHead is RowScanPlanItem) { var rowScan1 = (RowScanPlanItem)left._planHead; var rowScan2 = (RowScanPlanItem)right._planHead; if (rowScan1.TryUnion(rowScan2)) { _planHead = left.PlanItem; return; } } _planHead = new UnionPlanItem(left._planHead, right._planHead); } else { throw new NotImplementedException(); } }
private ResultSetBuilder VisitContains(SymbolContainsExpression exp) { var memberName = ExHelper.GetMemberName(exp.Match, _itemType, exp); var result = new ResultSetBuilder(_journal, _tx); var vals = ExHelper.GetLiteralValue(exp.Values, _parameters, exp); if (!(vals is IEnumerable)) { throw QueryExceptionExtensions.ExpressionNotSupported( string.Format("Parameter {0} does not implement IEnumerable.", exp.Values), exp); } try { result.IndexCollectionScan(memberName, (IEnumerable)vals, exp); } catch (InvalidCastException ex) { throw QueryExceptionExtensions.ExpressionNotSupported( string.Format("Parameter {0} value of type '{1}' cannot be used in " + "IN statement with column '{2}'. {3}", exp.Values, vals.GetType(), memberName, ex.Message), exp); } return(result); }
private ResultSetBuilder VisitSet(Expression left, Expression right, ExpressionType operation) { var res = new ResultSetBuilder(_journal, _tx); res.Logical(Visit(left), Visit(right), operation); return(res); }
private ResultSetBuilder EvaluateLogical(Expression expression) { var left = Visit(expression.GetLeft()); var right = Visit(expression.GetRight()); var result = new ResultSetBuilder(_journal, _tx); var operation = expression.NodeType; if (operation == ExpressionType.AndAlso) { operation = ExpressionType.And; } if (operation == ExpressionType.OrElse) { operation = ExpressionType.Or; } result.Logical(left, right, operation); return(result); }
public void ApplyFilter(ResultSetBuilder filter) { _planHead = OptimizeIntersect(_planHead, filter._planHead); }
private static void CreateColumnNotEqualScan <TT>(IColumnMetadata column, object literal, ResultSetBuilder builder) { if (literal == null) { builder.ColumnNotNullScan(column); } else { var value = (TT)column.ToTypedValue(literal); var lambda = (Func <TT, bool>)(t => !object.Equals(t, value)); builder.ColumnLambdaScan(column, lambda); } }
private static void CreateColumnScan <TT>(IColumnMetadata column, object literal, ResultSetBuilder builder) { if (literal == null) { builder.ColumnNullScan(column); } else { var value = (TT)column.ToTypedValue(literal); builder.ColumnScan <TT>(column, value); } }
private ResultSetBuilder EvaluateEquals(Expression expression) { if (expression.NodeType == ExpressionType.Equal || expression.NodeType == ExpressionType.NotEqual) { var literal = ExHelper.GetLiteralValue(expression, _parameters); var memberName = ExHelper.GetMemberName(expression, _itemType); IColumnMetadata column; try { column = _journal.Metadata.GetColumnByPropertyName(memberName); } catch (NFSdbConfigurationException) { throw QueryExceptionExtensions.ExpressionNotSupported( string.Format("Column {0} does not exist", memberName), expression); } if (_journal.Metadata.TimestampColumnID == column.ColumnID) { if (expression.NodeType == ExpressionType.Equal) { if (literal is long || literal is DateTime) { if (GetTimestamp(_journal.Metadata) != null && GetTimestamp(_journal.Metadata).PropertyName == memberName) { DateInterval filterInterval; if (literal is long) { var timestamp = (long)literal; filterInterval = new DateInterval(DateUtils.UnixTimestampToDateTime(timestamp), DateUtils.UnixTimestampToDateTime(timestamp + 1)); } else { var timestamp = (DateTime)literal; filterInterval = new DateInterval(timestamp, new DateTime(timestamp.Ticks + 1, timestamp.Kind)); } var result = new ResultSetBuilder(_journal, _tx); result.TimestampInterval(filterInterval); return(result); } } } } var res = new ResultSetBuilder(_journal, _tx); try { if (literal != null) { if (expression.NodeType == ExpressionType.Equal) { ReflectionHelper.CallStaticPrivateGeneric("CreateColumnScan", this, column.DataType.Clazz, column, literal, res); } else if (expression.NodeType == ExpressionType.NotEqual) { ReflectionHelper.CallStaticPrivateGeneric("CreateColumnNotEqualScan", this, column.DataType.Clazz, column, literal, res); } } else { if (expression.NodeType == ExpressionType.Equal) { ReflectionHelper.CallStaticPrivateGeneric("CreateColumnScan", this, column.DataType.Clazz, column, null, res); } else if (expression.NodeType == ExpressionType.NotEqual) { ReflectionHelper.CallStaticPrivateGeneric("CreateColumnNotEqualScan", this, column.DataType.Clazz, column, null, res); } } } catch (NFSdbQueryableNotSupportedException ex) { throw QueryExceptionExtensions.ExpressionNotSupported(ex.Message, expression); } catch (InvalidCastException ex) { throw QueryExceptionExtensions.ExpressionNotSupported(ex.Message, expression); } return(res); } throw new NotSupportedException( string.Format("Unable to translate expression {0} to journal operation", expression)); }
private ResultSetBuilder EvaluateCompare(Expression exp) { var memberName = ExHelper.GetMemberName(exp, _itemType); var literal = ExHelper.GetLiteralValue(exp, _parameters); var columnMetadata = GetTimestamp(_journal.Metadata); if (columnMetadata != null && string.Equals(columnMetadata.PropertyName, memberName, StringComparison.OrdinalIgnoreCase) && (literal is long || literal is DateTime)) { DateInterval filterInterval; var nodeType = exp.NodeType; if (exp.GetLeft().NodeType == ExpressionType.Constant) { nodeType = InvertComarison(nodeType); } switch (nodeType) { case ExpressionType.GreaterThan: var timestamp = literal is long ?DateUtils.UnixTimestampToDateTime((long)literal + 1) : ((DateTime)literal).AddTicks(1); filterInterval = DateInterval.From(timestamp); break; case ExpressionType.GreaterThanOrEqual: timestamp = literal is long ?DateUtils.UnixTimestampToDateTime((long)literal) : (DateTime)literal; filterInterval = DateInterval.From(timestamp); break; case ExpressionType.LessThan: timestamp = literal is long ?DateUtils.UnixTimestampToDateTime((long)literal) : (DateTime)literal; filterInterval = DateInterval.To(timestamp); break; case ExpressionType.LessThanOrEqual: timestamp = literal is long ?DateUtils.UnixTimestampToDateTime((long)literal + 1) : ((DateTime)literal).AddTicks(1); filterInterval = DateInterval.To(timestamp); break; default: throw QueryExceptionExtensions.ExpressionNotSupported(string.Format( "Timestamp column operation {0} is not supported. Supported operations are <, >, <=, >=", nodeType), exp); } var result = new ResultSetBuilder(_journal, _tx); result.TimestampInterval(filterInterval); return(result); } throw QueryExceptionExtensions.ExpressionNotSupported( "Comparison is supported for timestamp column only. Unable to bind '{0} to journal query operation", exp); }