-
Notifications
You must be signed in to change notification settings - Fork 347
Add Support for Vector Data Type in SQL for REST #3677
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
a0bd291
1064d7f
96f5324
3f5b597
280151b
1a7d309
a6ecbb9
5544ef4
5e3175b
f840076
ed820fb
3735ff4
a808e13
abb49d1
fbb8159
f3f5583
bd87fa0
d19a55f
3cc1c0b
2fea5ce
1e49376
98e6434
0137653
e7d72c8
36ff6eb
8a0edd2
c657910
ebe6b28
7e45fe2
aef7af9
e479927
0e96e32
84b73b1
99954f6
6404bdc
786f98f
f96fefb
8f2eb92
c357a59
d0d0978
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,6 +13,7 @@ | |
| using Azure.DataApiBuilder.Core.Models; | ||
| using Azure.DataApiBuilder.Service.Exceptions; | ||
| using Microsoft.AspNetCore.Http; | ||
| using Microsoft.Data.SqlTypes; | ||
| using Microsoft.Extensions.Logging; | ||
| using Polly; | ||
| using Polly.Retry; | ||
|
|
@@ -502,7 +503,7 @@ public async Task<DbResultSet> | |
| { | ||
| if (!ConfigProvider.GetConfig().MaxResponseSizeLogicEnabled()) | ||
| { | ||
| dbResultSetRow.Columns.Add(columnName, dbDataReader[columnName]); | ||
| dbResultSetRow.Columns.Add(columnName, GetColumnInformation(dbDataReader, columnName)); | ||
| } | ||
| else | ||
| { | ||
|
|
@@ -554,7 +555,7 @@ public DbResultSet | |
| { | ||
| if (!ConfigProvider.GetConfig().MaxResponseSizeLogicEnabled()) | ||
| { | ||
| dbResultSetRow.Columns.Add(columnName, dbDataReader[columnName]); | ||
| dbResultSetRow.Columns.Add(columnName, GetColumnInformation(dbDataReader, columnName)); | ||
| } | ||
| else | ||
| { | ||
|
|
@@ -822,7 +823,7 @@ internal int StreamDataIntoDbResultSetRow(DbDataReader dbDataReader, DbResultSet | |
| { | ||
| dataRead = columnSize; | ||
| ValidateSize(availableBytes, dataRead); | ||
| dbResultSetRow.Columns.Add(columnName, dbDataReader[columnName]); | ||
| dbResultSetRow.Columns.Add(columnName, GetColumnInformation(dbDataReader, columnName)); | ||
| } | ||
|
|
||
| return dataRead; | ||
|
|
@@ -885,6 +886,22 @@ private void ValidateSize(long availableSizeBytes, long sizeToBeReadBytes) | |
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Helper function to get column information from the DbDataReader and handle special cases like SqlVector<float>. | ||
| /// </summary> | ||
| /// <param name="dbDataReader"></param> | ||
| /// <param name="columnName"></param> | ||
| /// <returns></returns> | ||
| private static object GetColumnInformation(DbDataReader dbDataReader, string columnName) | ||
|
RubenCerna2079 marked this conversation as resolved.
|
||
| { | ||
| if (dbDataReader[columnName] is SqlVector<float> columnValue) | ||
| { | ||
| return columnValue.Memory; | ||
| } | ||
|
|
||
| return dbDataReader[columnName]; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are 2 reads here, which ordinarily would not be a problem, however, if the config is set with MaxResponseSizeLogicEnabled, then the reader's command behavior is set to Sequential Access. That can cause problems with a double read. easy fix though, something like this should do it |
||
| } | ||
|
|
||
| internal virtual void AddDbExecutionTimeToMiddlewareContext(long time) | ||
| { | ||
| HttpContext? httpContext = HttpContextAccessor?.HttpContext; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ | |
| using System.Data; | ||
| using System.Globalization; | ||
| using System.Net; | ||
| using System.Text.Json; | ||
| using Azure.DataApiBuilder.Auth; | ||
| using Azure.DataApiBuilder.Config.DatabasePrimitives; | ||
| using Azure.DataApiBuilder.Config.ObjectModel; | ||
|
|
@@ -452,10 +453,50 @@ protected static object ParseParamAsSystemType(string param, Type systemType) | |
| "Guid" => Guid.Parse(param), | ||
| "TimeOnly" => TimeOnly.Parse(param), | ||
| "TimeSpan" => TimeOnly.Parse(param), | ||
| "Single[]" => ParseArrayIntoSystemType(param, systemType), | ||
| _ => throw new NotSupportedException($"{systemType.Name} is not supported") | ||
| }; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Takes the array of the parameter we are going to parse and converts each element to the specified system type. | ||
| /// </summary> | ||
| /// <param name="param"></param> | ||
| /// <param name="systemType"></param> | ||
| /// <returns></returns> | ||
| /// <exception cref="NotSupportedException"></exception> | ||
| /// <exception cref="FormatException"></exception> | ||
| private static object ParseArrayIntoSystemType(string param, Type systemType) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With this pattern we can also write to other array values such as the ones found in PostgreSQL. Let me know if you think this is viable.
RubenCerna2079 marked this conversation as resolved.
|
||
| { | ||
| Type typeOfArray; | ||
| switch (systemType.Name) | ||
| { | ||
| case "Single[]": | ||
| typeOfArray = typeof(Single); | ||
| break; | ||
|
|
||
| default: | ||
| throw new NotSupportedException($"{systemType.Name} is not supported"); | ||
| } | ||
|
|
||
| try | ||
| { | ||
| List<object> list = new(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: this list appears to be unused. |
||
| object[] values = JsonSerializer.Deserialize<object[]>(param) ?? Array.Empty<object>(); | ||
| for (int i = 0; i < values.Length; i++) | ||
| { | ||
| string stringValue = values[i]?.ToString() ?? string.Empty; | ||
| values[i] = ParseParamAsSystemType(stringValue, typeOfArray); | ||
| } | ||
|
|
||
| return values; | ||
| } | ||
| catch | ||
| { | ||
| throw new FormatException($"Expected an array for {systemType.Name} but got an unexpected value"); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Very similar to GQLArgumentToDictParams but only extracts the argument names from | ||
| /// the specified field which means that the method does not need a middleware context | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.