示例#1
0
        public override void TryWhere(Operator op, T value, ShortSet result, ExecutionDetails details)
        {
            RangeToScan range   = new RangeToScan();
            bool        rangeOk = true;

            // For StartsWith, for ByteBlocks only, implement using IsPrefixOf
            if (op == Operator.StartsWith)
            {
                if (value is ByteBlock)
                {
                    IComparable <T> prefixComparer = (IComparable <T>)((ByteBlock)(object)value).GetExtendedIComparable(ByteBlock.Comparison.IsPrefixOf);     // trust me C#... I'm a professional...

                    int first = FindFirstWhere(prefixComparer);
                    int last  = FindLastWhere(prefixComparer);
                    if (!RangeToScan.TryBuild(Operator.Equals, first, last, this.Column.Count, ref range))
                    {
                        rangeOk = false;
                        if (details != null)
                        {
                            details.AddError(ExecutionDetails.ColumnDoesNotSupportOperator, op, this.Name);
                        }
                    }
                }
                else
                {
                    rangeOk = false;
                    if (details != null)
                    {
                        details.AddError(ExecutionDetails.ColumnDoesNotSupportOperator, op, this.Name);
                    }
                }
            }
            else
            {
                int first = FindFirstWhere(value);
                int last  = FindLastWhere(value);
                // Determine the range to scan to compute the result
                if (!RangeToScan.TryBuild(op, first, last, this.Column.Count, ref range))
                {
                    rangeOk = false;
                    if (details != null)
                    {
                        details.AddError(ExecutionDetails.ColumnDoesNotSupportOperator, op, this.Name);
                    }
                }
            }

            // Build the result set and return it
            if (rangeOk == true)
            {
                range.AddMatches(this.SortedIDs, result);
            }
        }
示例#2
0
        public void VerifyConsistency(VerificationLevel level, ExecutionDetails details)
        {
            _locker.EnterReadLock();
            try
            {
                if (_partitionBits != _partitions[0].Mask.BitCount || Math.Pow(2, _partitionBits) != this.PartitionCount)
                {
                    details.AddError(ExecutionDetails.TablePartitionBitsWrong, _partitionBits, _partitions[0].Mask.BitCount, this.PartitionCount);
                }

                if (this.RunParallel)
                {
                    Parallel.ForEach(_partitions, (p) =>
                    {
                        p.VerifyConsistency(level, details);
                    });
                }
                else
                {
                    foreach (Partition p in _partitions)
                    {
                        p.VerifyConsistency(level, details);
                    }
                }
            }
            finally
            {
                _locker.ExitReadLock();
            }
        }
示例#3
0
 public void TryWhere(Operator op, T value, ShortSet result, ExecutionDetails details)
 {
     // Base Column can't identify matches for any operator in bulk efficiently.
     if (details != null)
     {
         details.AddError(ExecutionDetails.ColumnDoesNotSupportOperator, op, this.Name);
     }
 }
示例#4
0
        public void VerifyConsistency(VerificationLevel level, ExecutionDetails details)
        {
            if (details == null)
            {
                throw new ArgumentNullException("details");
            }

            ushort expectedColumnSize = this.Count;

            // Verify each column internally
            foreach (IColumn column in this.Columns.Values)
            {
                column.VerifyConsistency(level, details);

                // Verify columns are all the same item count
                if (column.Count != expectedColumnSize)
                {
                    details.AddError(ExecutionDetails.ColumnSizeIsUnexpected, column.Name, column.Count, expectedColumnSize);
                }
            }

            // Verify all IDs are supposed to be in this partition, if this table has data yet
            // [Tables without data are allowed to not have any columns yet, do IDColumn would be null]
            if (this.Count > 0)
            {
                if (this.IDColumn == null)
                {
                    details.AddError(ExecutionDetails.PartitionHasNoIDColumn);
                }
                else
                {
                    Value            id       = Value.Create(null);
                    IColumn <object> idColumn = this.Columns[this.IDColumn.Name];
                    for (ushort i = 0; i < this.Count; ++i)
                    {
                        id.Assign(idColumn[i]);
                        int hashCode = id.GetHashCode();
                        if (!this.Mask.Matches(hashCode))
                        {
                            details.AddError(ExecutionDetails.ItemInWrongPartition, id, hashCode, this.Mask);
                        }
                    }
                }
            }
        }
示例#5
0
 public void VerifyConsistency(VerificationLevel level, ExecutionDetails details)
 {
     if (_itemCount > _values.Length)
     {
         if (details != null)
         {
             details.AddError(ExecutionDetails.ColumnDoesNotHaveEnoughValues, this.Name, _itemCount, _values.Length);
         }
     }
 }
示例#6
0
        public void TryWhere(Operator op, object value, ShortSet result, ExecutionDetails details)
        {
            T t;

            if (!TryConvert(value, out t))
            {
                if (details != null)
                {
                    details.AddError(ExecutionDetails.UnableToConvertType, value, this.Name, typeof(T).Name);
                }
            }
            else
            {
                _column.TryWhere(op, t, result, details);
            }
        }
示例#7
0
        public void TryWhere(Operator op, bool value, ShortSet result, ExecutionDetails details)
        {
            if (result == null)
            {
                throw new ArgumentNullException("result");
            }

            bool matchesTrue = (value == true);

            switch (op)
            {
            case Operator.Equals:
            case Operator.Matches:
            case Operator.MatchesExact:
                break;

            case Operator.NotEquals:
                matchesTrue = !matchesTrue;
                break;

            default:
                if (details != null)
                {
                    details.AddError(ExecutionDetails.ColumnDoesNotSupportOperator, op, this.Name);
                }
                return;
            }

            if (matchesTrue)
            {
                result.Or(_trueItems);
            }
            else
            {
                result.OrNot(_trueItems);
            }
        }
示例#8
0
        protected void ApplyTableSecurity <T>(IQuery <T> query, Func <SecurityIdentity, bool> isCurrentUserIn, ExecutionDetails details)
        {
            SecurityPermissions security = this.Security(query.TableName);

            // If table has row restrictions and one matches, restrict rows and allow
            // NOTE: If restricted rows are returned, columns are NOT restricted.
            foreach (var rowRestriction in security.RowRestrictedUsers)
            {
                if (isCurrentUserIn(rowRestriction.Key))
                {
                    query.Where = new AndExpression(QueryParser.Parse(rowRestriction.Value), query.Where);
                    return;
                }
            }

            // If table has column restrictions, build a list of excluded columns
            IList <string> restrictedColumns = GetRestrictedColumns(query.TableName, isCurrentUserIn);

            // If no columns were restricted, return query as-is
            if (restrictedColumns == null)
            {
                return;
            }

            // Exclude disallowed columns from where clauses
            // If a disallowed column is requested specifically, block the query and return an error
            ColumnSecurityCorrector c = new ColumnSecurityCorrector(restrictedColumns);

            try
            {
                query.Correct(c);
            }
            catch (ArribaColumnAccessDeniedException e)
            {
                query.Where = new EmptyExpression();
                details.AddDeniedColumn(e.Message);
                details.AddError(ExecutionDetails.DisallowedColumnQuery, e.Message);
            }

            // If columns are excluded, remove those from the select list
            IQuery <T> primaryQuery = query;

            if (query is JoinQuery <T> )
            {
                primaryQuery = ((JoinQuery <T>)query).PrimaryQuery;
            }

            if (primaryQuery.GetType().Equals(typeof(SelectQuery)))
            {
                SelectQuery   sq = (SelectQuery)primaryQuery;
                List <string> filteredColumns = null;

                if (sq.Columns.Count == 1 && sq.Columns[0] == "*")
                {
                    filteredColumns = new List <string>();
                    foreach (ColumnDetails column in this[sq.TableName].ColumnDetails)
                    {
                        if (restrictedColumns.Contains(column.Name))
                        {
                            details.AddDeniedColumn(column.Name);
                        }
                        else
                        {
                            filteredColumns.Add(column.Name);
                        }
                    }
                }
                else
                {
                    foreach (string columnName in sq.Columns)
                    {
                        if (restrictedColumns.Contains(columnName))
                        {
                            if (filteredColumns == null)
                            {
                                filteredColumns = new List <string>(sq.Columns);
                            }
                            filteredColumns.Remove(columnName);

                            details.AddDeniedColumn(columnName);
                        }
                    }
                }

                if (filteredColumns != null)
                {
                    sq.Columns = filteredColumns;
                }
            }
            else if (primaryQuery.GetType().Equals(typeof(AggregationQuery)))
            {
                AggregationQuery aq = (AggregationQuery)primaryQuery;
                if (aq.AggregationColumns != null)
                {
                    foreach (string columnName in aq.AggregationColumns)
                    {
                        if (restrictedColumns.Contains(columnName))
                        {
                            details.AddDeniedColumn(columnName);
                            details.AddError(ExecutionDetails.DisallowedColumnQuery, columnName);
                            aq.Where = new EmptyExpression();
                        }
                    }
                }
            }
            else if (primaryQuery.GetType().Equals(typeof(DistinctQuery)))
            {
                DistinctQuery dq = (DistinctQuery)primaryQuery;
                if (restrictedColumns.Contains(dq.Column))
                {
                    details.AddDeniedColumn(dq.Column);
                    details.AddError(ExecutionDetails.DisallowedColumnQuery, dq.Column);
                    dq.Where = new EmptyExpression();
                }
            }
            else
            {
                // IQuery is extensible; there's no way to ensure that user-implemented
                // queries respect security rules.
                details.AddError(ExecutionDetails.DisallowedQuery, primaryQuery.GetType().Name);
                primaryQuery.Where = new EmptyExpression();
            }
        }
示例#9
0
        public override void VerifyConsistency(VerificationLevel level, ExecutionDetails details)
        {
            base.VerifyConsistency(level, details);

            // Verify SortedIDCount agrees with ItemCount
            if (this.SortedIDCount != this.Count)
            {
                if (details != null)
                {
                    details.AddError(ExecutionDetails.ColumnDoesNotHaveEnoughValues, this.Name, this.SortedIDCount, this.Count);
                }
            }

            // Verify that all IDs are in SortedIDs, all values are ordered, and no unexpected values are found
            ushort      lastID    = 0;
            IComparable lastValue = null;

            ShortSet idsInList = new ShortSet(this.Count);

            for (int i = 0; i < this.Count; ++i)
            {
                ushort id = this.SortedIDs[i];

                if (id >= this.Count)
                {
                    if (details != null)
                    {
                        details.AddError(ExecutionDetails.SortedIdOutOfRange, this.Name, id, this.Count);
                    }
                }
                else if (idsInList.Contains(id))
                {
                    if (details != null)
                    {
                        details.AddError(ExecutionDetails.SortedIdAppearsMoreThanOnce, this.Name, id);
                    }
                }
                else
                {
                    idsInList.Add(id);

                    IComparable value = (IComparable)this[id];
                    if (lastValue != null)
                    {
                        int compareResult = lastValue.CompareTo(value);
                        if (compareResult > 0)
                        {
                            if (details != null)
                            {
                                details.AddError(ExecutionDetails.SortedValuesNotInOrder, this.Name, lastID, lastValue, id, value);
                            }
                        }
                    }

                    lastValue = value;
                    lastID    = id;
                }
            }

            idsInList.Not();
            if (idsInList.Count() > 0)
            {
                if (details != null)
                {
                    details.AddError(ExecutionDetails.SortedColumnMissingIDs, this.Name, String.Join(", ", idsInList.Values));
                }
            }
        }