private static void DistinctTest(Table table, string column, string where) { int iterations = 1000; DistinctQuery query = new DistinctQuery(column, where, 100); DistinctResult result = null; Trace.Write("Aggregating Bugs..."); for (int i = 0; i < iterations; ++i) { result = table.Query(query); } ShowResult(result.Values); }
public void ITable_Distinct(Func <ITable> factoryMethod) { // Define columns and add sample data ITable table = factoryMethod(); AddSampleData(table); // Get Distinct Priority for all bugs, verify three (0, 1, 3) DistinctQuery query = new DistinctQuery("Priority", "", 5); DistinctResult result = table.Query(query); // sort the results because order is not garenteed by distinct query Array values = result.Values.GetColumn(0); Array.Sort(values); Assert.AreEqual("0, 1, 3", values.Join(", ")); Assert.IsTrue(result.AllValuesReturned); // Verify the result converts to a dimension properly AggregationDimension dimension = result.ToAggregationDimension(); Assert.AreEqual("Query [[Priority] = 0,[Priority] = 1,[Priority] = 3]", dimension.ToString()); // Verify distinct priority where priority is not 1 has only two values query.Where = QueryParser.Parse("Priority != 1"); result = table.Query(query); // sort the results because order is not garenteed by distinct query values = result.Values.GetColumn(0); Array.Sort(values); Assert.AreEqual("0, 3", result.Values.GetColumn(0).Join(", ")); Assert.IsTrue(result.AllValuesReturned); // Verify if we only ask for one value, query reports more values left query.Count = 1; result = table.Query(query); // either value could come back, it's a race to whichever partition completes first Assert.IsTrue( ("0" == result.Values.GetColumn(0).Join(", ")) || ("3" == result.Values.GetColumn(0).Join(", "))); Assert.IsFalse(result.AllValuesReturned); }
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(); } }
public async Task <DistinctResult> Distinct(DistinctQuery query) { return(await _client.SendObjectAsync <DistinctResult>(HttpMethod.Post, String.Format("table/{0}?action=distinct", _tableName), value : query)); }
/// <summary> /// Processes the specified DistinctQuery. /// </summary> /// <param name="distinctQuery">The DistinctQuery.</param> /// <param name="messageContext">The message context.</param> /// <param name="storeContext">The store context.</param> /// <returns>DistinctQueryResult</returns> internal static DistinctQueryResult Process(DistinctQuery distinctQuery, MessageContext messageContext, IndexStoreContext storeContext) { DistinctQueryResult distinctQueryResult; Dictionary <byte[], int> distinctValueCountMapping = null; bool indexExists = false; try { IndexTypeMapping indexTypeMapping = storeContext.StorageConfiguration.CacheIndexV3StorageConfig.IndexTypeMappingCollection[messageContext.TypeId]; Index targetIndexInfo = indexTypeMapping.IndexCollection[distinctQuery.TargetIndexName]; #region Prepare Result CacheIndexInternal targetIndex = IndexServerUtils.GetCacheIndexInternal(storeContext, messageContext.TypeId, messageContext.PrimaryId, distinctQuery.IndexId, targetIndexInfo.ExtendedIdSuffix, distinctQuery.TargetIndexName, (distinctQuery.ItemsToLookUp != null ? (int)distinctQuery.ItemsToLookUp : Int32.MaxValue), null, true, distinctQuery.IndexCondition, false, false, targetIndexInfo.PrimarySortInfo, targetIndexInfo.LocalIdentityTagList, targetIndexInfo.StringHashCodeDictionary, null, targetIndexInfo.IsMetadataPropertyCollection, null, DomainSpecificProcessingType.None, storeContext.DomainSpecificConfig, distinctQuery.FieldName, null, true); #endregion if (targetIndex != null) { indexExists = true; // update perf counter PerformanceCounters.Instance.SetCounterValue(PerformanceCounterEnum.NumOfItemsInIndexPerDistinctQuery, messageContext.TypeId, targetIndex.OutDeserializationContext.TotalCount); PerformanceCounters.Instance.SetCounterValue(PerformanceCounterEnum.NumOfItemsReadPerDistinctQuery, messageContext.TypeId, targetIndex.OutDeserializationContext.ReadItemCount); distinctValueCountMapping = targetIndex.OutDeserializationContext.DistinctValueCountMapping; } distinctQueryResult = new DistinctQueryResult { DistinctValueCountMapping = distinctValueCountMapping, IndexExists = indexExists, }; } catch (Exception ex) { distinctQueryResult = new DistinctQueryResult { DistinctValueCountMapping = null, IndexExists = false, ExceptionInfo = ex.Message }; LoggingUtil.Log.ErrorFormat("TypeId {0} -- Error processing DistinctQuery : {1}", messageContext.TypeId, ex); } return(distinctQueryResult); }