Skip to content

Commit

Permalink
[Hotfix] VectorIndexDefinition: Refactors Code to Remove Support for …
Browse files Browse the repository at this point in the history
…`VectorIndexShardKey` from Preview Contract (#4873)

# Pull Request Template

## Description

- Removes support for `VectorIndexShardKey` from Preview Contract.
- Fixes `null` check for `HybridSearchQueryInfo` .

## Type of change

Please delete options that are not relevant.

- [x] New feature (non-breaking change which adds functionality)

## Closing issues

To automatically close an issue: closes #IssueNumber

---------

Co-authored-by: sc978345 <[email protected]>
Co-authored-by: Kiran Kumar Kolli <[email protected]>
  • Loading branch information
3 people authored Nov 11, 2024
1 parent 018dd20 commit d41592f
Show file tree
Hide file tree
Showing 20 changed files with 3,626 additions and 565 deletions.
6 changes: 3 additions & 3 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ClientOfficialVersion>3.45.0</ClientOfficialVersion>
<ClientOfficialVersion>3.45.1</ClientOfficialVersion>
<ClientPreviewVersion>3.46.0</ClientPreviewVersion>
<ClientPreviewSuffixVersion>preview.0</ClientPreviewSuffixVersion>
<DirectVersion>3.36.1</DirectVersion>
<ClientPreviewSuffixVersion>preview.1</ClientPreviewSuffixVersion>
<DirectVersion>3.37.1</DirectVersion>
<EncryptionOfficialVersion>2.0.4</EncryptionOfficialVersion>
<EncryptionPreviewVersion>2.1.0</EncryptionPreviewVersion>
<EncryptionPreviewSuffixVersion>preview4</EncryptionPreviewSuffixVersion>
Expand Down
1,655 changes: 1,655 additions & 0 deletions Microsoft.Azure.Cosmos/contracts/API_3.45.1.txt

Large diffs are not rendered by default.

1,752 changes: 1,752 additions & 0 deletions Microsoft.Azure.Cosmos/contracts/API_3.46.0-preview.1.txt

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,7 @@ VectorIndexDefinition<T> WithIndexingSearchListSize(
/// applies to index types DiskANN and quantizedFlat.
/// </param>
/// <returns>An instance of the current <see cref="VectorIndexDefinition{T}"/>.</returns>
#if PREVIEW
public
#else
internal
#endif
VectorIndexDefinition<T> WithVectorIndexShardKey(
internal VectorIndexDefinition<T> WithVectorIndexShardKey(
string[] vectorIndexShardKey)
{
this.vectorIndexPath.VectorIndexShardKey = vectorIndexShardKey ?? throw new ArgumentNullException(nameof(vectorIndexShardKey));
Expand Down
262 changes: 0 additions & 262 deletions Microsoft.Azure.Cosmos/src/Query/Core/QueryPlan/QueryPlanHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ public async Task<TryCatch<PartitionedQueryExecutionInfo>> TryGetQueryPlanAsync(
Documents.ResourceType resourceType,
PartitionKeyDefinition partitionKeyDefinition,
VectorEmbeddingPolicy vectorEmbeddingPolicy,
QueryFeatures supportedQueryFeatures,
bool hasLogicalPartitionKey,
bool useSystemPrefix,
GeospatialType geospatialType,
Expand Down Expand Up @@ -59,63 +58,9 @@ public async Task<TryCatch<PartitionedQueryExecutionInfo>> TryGetQueryPlanAsync(
return tryGetQueryInfo;
}

if (QueryPlanExceptionFactory.TryGetUnsupportedException(
tryGetQueryInfo.Result.QueryInfo,
supportedQueryFeatures,
out Exception queryPlanHandlerException))
{
return TryCatch<PartitionedQueryExecutionInfo>.FromException(queryPlanHandlerException);
}

return tryGetQueryInfo;
}

/// <summary>
/// Used in the compute gateway to support legacy gateways query execution pattern.
/// </summary>
public async Task<TryCatch<(PartitionedQueryExecutionInfo queryPlan, bool supported)>> TryGetQueryInfoAndIfSupportedAsync(
QueryFeatures supportedQueryFeatures,
SqlQuerySpec sqlQuerySpec,
Documents.ResourceType resourceType,
PartitionKeyDefinition partitionKeyDefinition,
VectorEmbeddingPolicy vectorEmbeddingPolicy,
bool hasLogicalPartitionKey,
bool useSystemPrefix,
GeospatialType geospatialType,
CancellationToken cancellationToken = default)
{
if (sqlQuerySpec == null)
{
throw new ArgumentNullException(nameof(sqlQuerySpec));
}

if (partitionKeyDefinition == null)
{
throw new ArgumentNullException(nameof(partitionKeyDefinition));
}

cancellationToken.ThrowIfCancellationRequested();

TryCatch<PartitionedQueryExecutionInfo> tryGetQueryInfo = await this.TryGetQueryInfoAsync(
sqlQuerySpec,
resourceType,
partitionKeyDefinition,
vectorEmbeddingPolicy,
hasLogicalPartitionKey,
useSystemPrefix,
geospatialType,
cancellationToken);
if (tryGetQueryInfo.Failed)
{
return TryCatch<(PartitionedQueryExecutionInfo, bool)>.FromException(tryGetQueryInfo.Exception);
}

QueryFeatures neededQueryFeatures = QueryPlanSupportChecker.GetNeededQueryFeatures(
tryGetQueryInfo.Result.QueryInfo,
supportedQueryFeatures);
return TryCatch<(PartitionedQueryExecutionInfo, bool)>.FromResult((tryGetQueryInfo.Result, neededQueryFeatures == QueryFeatures.None));
}

private Task<TryCatch<PartitionedQueryExecutionInfo>> TryGetQueryInfoAsync(
SqlQuerySpec sqlQuerySpec,
Documents.ResourceType resourceType,
Expand All @@ -142,212 +87,5 @@ private Task<TryCatch<PartitionedQueryExecutionInfo>> TryGetQueryInfoAsync(
geospatialType: geospatialType,
cancellationToken: cancellationToken);
}

private static class QueryPlanSupportChecker
{
public static QueryFeatures GetNeededQueryFeatures(
QueryInfo queryInfo,
QueryFeatures supportedQueryFeatures)
{
QueryFeatures neededQueryFeatures = QueryFeatures.None;
neededQueryFeatures |= QueryPlanSupportChecker.GetNeededQueryFeaturesIfAggregateQuery(queryInfo, supportedQueryFeatures);
neededQueryFeatures |= QueryPlanSupportChecker.GetNeededQueryFeaturesIfDistinctQuery(queryInfo, supportedQueryFeatures);
neededQueryFeatures |= QueryPlanSupportChecker.GetNeedQueryFeaturesIfGroupByQuery(queryInfo, supportedQueryFeatures);
neededQueryFeatures |= QueryPlanSupportChecker.GetNeededQueryFeaturesIfOffsetLimitQuery(queryInfo, supportedQueryFeatures);
neededQueryFeatures |= QueryPlanSupportChecker.GetNeededQueryFeaturesIfOrderByQuery(queryInfo, supportedQueryFeatures);
neededQueryFeatures |= QueryPlanSupportChecker.GetNeededQueryFeaturesIfTopQuery(queryInfo, supportedQueryFeatures);

return neededQueryFeatures;
}

private static QueryFeatures GetNeededQueryFeaturesIfAggregateQuery(
QueryInfo queryInfo,
QueryFeatures supportedQueryFeatures)
{
QueryFeatures neededQueryFeatures = QueryFeatures.None;
if (queryInfo.HasAggregates)
{
bool isSingleAggregate = (queryInfo.Aggregates.Count == 1)
|| (queryInfo.GroupByAliasToAggregateType.Values.Where(aggregateOperator => aggregateOperator.HasValue).Count() == 1);
if (isSingleAggregate)
{
if (queryInfo.HasSelectValue)
{
if (!supportedQueryFeatures.HasFlag(QueryFeatures.Aggregate))
{
neededQueryFeatures |= QueryFeatures.Aggregate;
}
}
else
{
if (!supportedQueryFeatures.HasFlag(QueryFeatures.NonValueAggregate))
{
neededQueryFeatures |= QueryFeatures.NonValueAggregate;
}
}
}
else
{
if (!supportedQueryFeatures.HasFlag(QueryFeatures.NonValueAggregate))
{
neededQueryFeatures |= QueryFeatures.NonValueAggregate;
}

if (!supportedQueryFeatures.HasFlag(QueryFeatures.MultipleAggregates))
{
neededQueryFeatures |= QueryFeatures.MultipleAggregates;
}
}
}

return neededQueryFeatures;
}

private static QueryFeatures GetNeededQueryFeaturesIfDistinctQuery(
QueryInfo queryInfo,
QueryFeatures supportedQueryFeatures)
{
QueryFeatures neededQueryFeatures = QueryFeatures.None;
if (queryInfo.HasDistinct)
{
if (!supportedQueryFeatures.HasFlag(QueryFeatures.Distinct))
{
neededQueryFeatures |= QueryFeatures.Distinct;
}
}

return neededQueryFeatures;
}

private static QueryFeatures GetNeededQueryFeaturesIfTopQuery(
QueryInfo queryInfo,
QueryFeatures supportedQueryFeatures)
{
QueryFeatures neededQueryFeatures = QueryFeatures.None;
if (queryInfo.HasTop)
{
if (!supportedQueryFeatures.HasFlag(QueryFeatures.Top))
{
neededQueryFeatures |= QueryFeatures.Top;
}
}

return neededQueryFeatures;
}

private static QueryFeatures GetNeededQueryFeaturesIfOffsetLimitQuery(
QueryInfo queryInfo,
QueryFeatures supportedQueryFeatures)
{
QueryFeatures neededQueryFeatures = QueryFeatures.None;
if (queryInfo.HasLimit || queryInfo.HasOffset)
{
if (!supportedQueryFeatures.HasFlag(QueryFeatures.OffsetAndLimit))
{
neededQueryFeatures |= QueryFeatures.OffsetAndLimit;
}
}

return neededQueryFeatures;
}

private static QueryFeatures GetNeedQueryFeaturesIfGroupByQuery(
QueryInfo queryInfo,
QueryFeatures supportedQueryFeatures)
{
QueryFeatures neededQueryFeatures = QueryFeatures.None;
if (queryInfo.HasGroupBy)
{
if (!supportedQueryFeatures.HasFlag(QueryFeatures.GroupBy))
{
neededQueryFeatures |= QueryFeatures.GroupBy;
}
}

return neededQueryFeatures;
}

private static QueryFeatures GetNeededQueryFeaturesIfOrderByQuery(
QueryInfo queryInfo,
QueryFeatures supportedQueryFeatures)
{
QueryFeatures neededQueryFeatures = QueryFeatures.None;
if (queryInfo.HasOrderBy)
{
if (queryInfo.OrderByExpressions.Count == 1)
{
if (!supportedQueryFeatures.HasFlag(QueryFeatures.OrderBy))
{
neededQueryFeatures |= QueryFeatures.OrderBy;
}
}
else
{
if (!supportedQueryFeatures.HasFlag(QueryFeatures.MultipleOrderBy))
{
neededQueryFeatures |= QueryFeatures.MultipleOrderBy;
}
}
}

return neededQueryFeatures;
}
}

private static class QueryPlanExceptionFactory
{
private static readonly IReadOnlyList<QueryFeatures> QueryFeatureList = (QueryFeatures[])Enum.GetValues(typeof(QueryFeatures));
private static readonly ReadOnlyDictionary<QueryFeatures, ArgumentException> FeatureToUnsupportedException = new ReadOnlyDictionary<QueryFeatures, ArgumentException>(
QueryFeatureList
.ToDictionary(
x => x,
x => new ArgumentException(QueryPlanExceptionFactory.FormatExceptionMessage(x.ToString()))));

public static bool TryGetUnsupportedException(
QueryInfo queryInfo,
QueryFeatures supportedQueryFeatures,
out Exception queryPlanHandlerException)
{
QueryFeatures neededQueryFeatures = QueryPlanSupportChecker.GetNeededQueryFeatures(
queryInfo,
supportedQueryFeatures);
if (neededQueryFeatures != QueryFeatures.None)
{
List<Exception> queryPlanHandlerExceptions = new List<Exception>();
foreach (QueryFeatures queryFeature in QueryPlanExceptionFactory.QueryFeatureList)
{
if ((neededQueryFeatures & queryFeature) == queryFeature)
{
Exception unsupportedFeatureException = QueryPlanExceptionFactory.FeatureToUnsupportedException[queryFeature];
queryPlanHandlerExceptions.Add(unsupportedFeatureException);
}
}

queryPlanHandlerException = new QueryPlanHandlerException(queryPlanHandlerExceptions);
return true;
}

queryPlanHandlerException = default;
return false;
}

private static string FormatExceptionMessage(string feature)
{
return $"Query contained {feature}, which the calling client does not support.";
}

private sealed class QueryPlanHandlerException : AggregateException
{
private const string QueryContainsUnsupportedFeaturesExceptionMessage = "Query contains 1 or more unsupported features. Upgrade your SDK to a version that does support the requested features:";
public QueryPlanHandlerException(IEnumerable<Exception> innerExceptions)
: base(
QueryContainsUnsupportedFeaturesExceptionMessage
+ Environment.NewLine
+ string.Join(Environment.NewLine, innerExceptions.Select(innerException => innerException.Message)),
innerExceptions)
{
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ public static async Task<PartitionedQueryExecutionInfo> GetQueryPlanWithServiceI
resourceType,
partitionKeyDefinition,
vectorEmbeddingPolicy,
QueryPlanRetriever.SupportedQueryFeatures,
hasLogicalPartitionKey,
useSystemPrefix,
geospatialType,
Expand Down
10 changes: 3 additions & 7 deletions Microsoft.Azure.Cosmos/src/Resource/Settings/VectorIndexPath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public sealed class VectorIndexPath

/// <summary>
/// Gets or sets the quantization byte size for the vector index path. This is only applicable for the quantizedFlat and diskann vector index types.
/// The allowed range for this parameter is between 1 and 3.
/// The allowed range for this parameter is between 1 and the minimum of vector dimensions and 512.
/// </summary>
[JsonIgnore]
#if PREVIEW
Expand Down Expand Up @@ -102,14 +102,10 @@ int IndexingSearchListSize

/// <summary>
/// Gets or sets the vector index shard key for the vector index path. This is only applicable for the quantizedFlat and diskann vector index types.
/// The maximum length of the vector index shard key is 1.
/// </summary>
[JsonProperty(PropertyName = "vectorIndexShardKey", NullValueHandling = NullValueHandling.Ignore)]
#if PREVIEW
public
#else
internal
#endif
string[] VectorIndexShardKey { get; set; }
internal string[] VectorIndexShardKey { get; set; }

/// <summary>
/// This contains additional values for scenarios where the SDK is not aware of new fields.
Expand Down
Loading

0 comments on commit d41592f

Please sign in to comment.