Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
6b43bbd
feat(csharp): support native SEA metadata results
vuanhphung Oct 1, 2026
2938936
fix(csharp): align native metadata with existing ADBC results
vuanhphung Oct 1, 2026
09d95b0
fix(csharp): compile native metadata across target frameworks
vuanhphung Oct 1, 2026
5d82105
fix(csharp): distinguish catalog misses from native request errors
vuanhphung Oct 1, 2026
b4d40ea
test(csharp): cover native GetObjects catalog filtering
vuanhphung Oct 1, 2026
464686d
refactor(csharp): always request native SEA metadata
vuanhphung Oct 1, 2026
0ca3b38
fix(csharp): honor literal catalog filters in native metadata
vuanhphung Oct 1, 2026
8c8ad67
refactor(csharp): trust manifest for native metadata detection
vuanhphung Oct 1, 2026
c22a1d1
Restore existing catalog fan-out error behavior
vuanhphung Oct 1, 2026
5194948
Filter native metadata column fan-out by catalog
vuanhphung Oct 1, 2026
1af4a1a
Fix native column filter local name collision
vuanhphung Oct 1, 2026
967a193
fix(csharp): resolve GetObjects catalog patterns and validate native …
vuanhphung Oct 6, 2026
4906708
fix(csharp): propagate native metadata validation errors
vuanhphung Oct 7, 2026
cf939e4
refactor(csharp): share native and SHOW metadata decoding
vuanhphung Oct 7, 2026
e8d1d36
fix(csharp): share native metadata rules and enforce CI coverage
vuanhphung Oct 7, 2026
95d1620
test(csharp): always require native responses in SEA metadata E2Es
vuanhphung Oct 7, 2026
8a07022
fix(csharp): enforce exact catalog scope in GetTableSchema
vuanhphung Oct 7, 2026
091c585
fix(csharp): preserve existing SHOW metadata behavior
vuanhphung Oct 7, 2026
1d73109
test(csharp): simplify native metadata coverage
vuanhphung Oct 7, 2026
ea23639
fix(csharp): match Thrift native metadata null defaults
vuanhphung Oct 7, 2026
92db613
fix(csharp): unify native metadata decoding and catalog filters
vuanhphung Oct 9, 2026
f0ccb1d
fix(csharp): preserve native metadata patterns and mixed column fields
vuanhphung Oct 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 59 additions & 2 deletions csharp/src/FlatColumnsResultBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@
*/

using System.Collections.Generic;
using AdbcDrivers.Databricks.StatementExecution;using AdbcDrivers.HiveServer2;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AdbcDrivers.Databricks.StatementExecution;
using AdbcDrivers.HiveServer2;
using AdbcDrivers.HiveServer2.Hive2;
using Apache.Arrow;
using Apache.Arrow.Adbc;
Expand All @@ -29,6 +33,58 @@ namespace AdbcDrivers.Databricks
/// </summary>
internal static class FlatColumnsResultBuilder
{
internal static async Task<QueryResult> BuildFlatColumnsResultAsync(
ColumnMetadataResult columns, CancellationToken cancellationToken)
{
var schema = MetadataSchemaFactory.CreateColumnMetadataSchema();
if (columns.IsNative)
return NativeMetadataResultBuilder.Build(columns.Results, schema, MetadataOperation.GetColumns);
if (!columns.Results.Any(result => result.IsNative && result.Batches.Count > 0))
return BuildFlatColumnsResult(columns.Rows);

// Normalize each response independently so SHOW fallback cannot discard native fields.
var batches = new List<RecordBatch>();
try
{
for (int index = 0; index < columns.Results.Count; index++)
{
var result = columns.Results[index];
var flat = result.IsNative
? NativeMetadataResultBuilder.Build(result, schema, MetadataOperation.GetColumns)
: BuildFlatColumnsResult(columns.RowsByResult[index]);
using var stream = flat.Stream!;
var batch = await stream.ReadNextRecordBatchAsync(cancellationToken).ConfigureAwait(false);
if (batch != null) batches.Add(batch);
}

var arrays = Enumerable.Range(0, schema.FieldsList.Count)
.Select(column => ArrowArrayFactory.BuildArray(ArrayDataConcatenator.Concatenate(
batches.Select(batch => batch.Column(column).Data).ToList())!))
.ToArray();
return new QueryResult(batches.Sum(batch => batch.Length), new HiveInfoArrowStream(schema, arrays));
}
finally
{
foreach (var batch in batches) batch.Dispose();
}
}

private static QueryResult BuildFlatColumnsResult(IEnumerable<ColumnRow> columns)
{
var tableInfos = new Dictionary<string, (string catalog, string schema, string table, TableInfo info)>();
foreach (var column in columns)
{
if (column.Catalog == null || column.Schema == null || column.Table == null) continue;
string key = $"{column.Catalog}.{column.Schema}.{column.Table}";
if (!tableInfos.ContainsKey(key))
tableInfos[key] = (column.Catalog, column.Schema, column.Table, new TableInfo("TABLE"));
ColumnMetadataHelper.PopulateTableInfoFromTypeName(
tableInfos[key].info, column.Name, column.TypeName, column.Ordinal, column.Nullable,
columnDefault: column.Default, isAutoIncrement: column.IsAutoIncrement);
}
return BuildFlatColumnsResult(tableInfos.Values);
}

internal static QueryResult BuildFlatColumnsResult(
IEnumerable<(string catalog, string schema, string table, TableInfo info)> tables)
{
Expand Down Expand Up @@ -81,7 +137,8 @@ internal static QueryResult BuildFlatColumnsResult(

nullableBuilder.Append(info.Nullable[i]);
remarksBuilder.Append("");
columnDefBuilder.AppendNull();
if (string.IsNullOrEmpty(info.ColumnDefault[i])) columnDefBuilder.AppendNull();
else columnDefBuilder.Append(info.ColumnDefault[i]);

sqlDataTypeBuilder.Append(info.ColType[i]);

Expand Down
30 changes: 25 additions & 5 deletions csharp/src/StatementExecution/ColumnMetadataHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,24 @@ internal static string GetBaseTypeName(string typeName)
};
}

internal static (long ColumnSize, long DecimalDigits) NormalizePrecisionAndScale(
string? typeName, long? columnSize, long? decimalDigits)
{
if (typeName != null)
{
string baseName = GetBaseTypeName(typeName);
if (baseName is "DECIMAL" or "NUMERIC")
{
columnSize = GetColumnSizeDefault(typeName);
decimalDigits = GetDecimalDigitsDefault(typeName);
}
else if (s_charBaseTypes.Contains(baseName))
columnSize = GetColumnSizeDefault(typeName);
}
// Thrift defaults null sizes and digits to zero before type-specific overrides.
return (columnSize ?? 0, decimalDigits ?? 0);
}

internal static int? GetBufferLength(string typeName)
{
string baseName = GetBaseTypeName(typeName);
Expand Down Expand Up @@ -242,19 +260,21 @@ internal static void PopulateTableInfoFromTypeName(
int ordinalPosition,
bool isNullable = true,
string? comment = null,
string? columnDefault = null)
string? columnDefault = null,
bool isAutoIncrement = false)
{
tableInfo.ColumnName.Add(columnName);
tableInfo.TypeName.Add(typeName);
tableInfo.ColType.Add(GetDataTypeCode(typeName));
tableInfo.BaseTypeName.Add(GetBaseTypeName(typeName));
tableInfo.Precision.Add(GetColumnSizeDefault(typeName));
int? scale = GetDecimalDigitsDefault(typeName);
tableInfo.Scale.Add(scale.HasValue ? (short)scale.Value : null);
var precisionAndScale = NormalizePrecisionAndScale(
typeName, GetColumnSizeDefault(typeName), GetDecimalDigitsDefault(typeName));
tableInfo.Precision.Add(checked((int)precisionAndScale.ColumnSize));
tableInfo.Scale.Add((short)precisionAndScale.DecimalDigits);
tableInfo.OrdinalPosition.Add(ordinalPosition);
tableInfo.Nullable.Add(isNullable ? (short)1 : (short)0);
tableInfo.IsNullable.Add(isNullable ? "YES" : "NO");
tableInfo.IsAutoIncrement.Add(false);
tableInfo.IsAutoIncrement.Add(isAutoIncrement);
tableInfo.ColumnDefault.Add(columnDefault ?? "");
}

Expand Down
Loading
Loading