// Licensed to the LF AI & Data foundation under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// 移植自 milvus-io/milvus client/column/columns.go 的 `FieldDataColumn`
// 与 `parseScalarData`(Apache-2.0)。上游用 Go 泛型把「取数据 → 圈范围 →
// 处理 valid_data → 造列」摊成一层模板,这里按列类型写开——MoonBit 的
// 枚举没有和 Go 类型参数等价的东西,硬凑反而难读。
///|
/// 把一条 `FieldData` 解成一列。
///
/// `begin` / `end` 是行区间,`end` 为负表示到末尾(上游用 `-1` 表达这一点,
/// 这里照搬,因为查询/检索回读确实会按批次切片)。区间按**逻辑行**算:
/// 可空列先圈 `valid_data`,再据此找到数据里的对应段。
///
/// 这是本 Issue 的核心入口:`Query` / `Search` 返回的每一种列类型都从这里过。
pub fn from_field_data(
field : @schema.FieldData,
begin? : Int = 0,
end? : Int = -1,
) -> Column raise ColumnError {
let type_ = field.type_
if valid_data_conflicts(field) {
raise MalformedPayload(
"field \{field.field_name} carries conflicting legacy and field-specific valid_data",
)
}
let valid = field_valid_data(field)
match type_ {
@schema.DataType::Bool =>
build(
ColumnValue::Bool(scalar_bool(field, begin, end, valid)),
valid_slice(valid, begin, end),
)
@schema.DataType::Int8 =>
build(
ColumnValue::Int8(scalar_int(field, begin, end, valid).map(narrow_int8)),
valid_slice(valid, begin, end),
)
@schema.DataType::Int16 =>
build(
ColumnValue::Int16(
scalar_int(field, begin, end, valid).map(narrow_int16),
),
valid_slice(valid, begin, end),
)
@schema.DataType::Int32 =>
build(
ColumnValue::Int32(scalar_int(field, begin, end, valid)),
valid_slice(valid, begin, end),
)
@schema.DataType::Int64 =>
build(
ColumnValue::Int64(scalar_long(field, begin, end, valid)),
valid_slice(valid, begin, end),
)
@schema.DataType::Float =>
build(
ColumnValue::Float(scalar_float(field, begin, end, valid)),
valid_slice(valid, begin, end),
)
@schema.DataType::Double =>
build(
ColumnValue::Double(scalar_double(field, begin, end, valid)),
valid_slice(valid, begin, end),
)
@schema.DataType::String =>
build(
ColumnValue::String(scalar_string(field, begin, end, valid)),
valid_slice(valid, begin, end),
)
@schema.DataType::VarChar =>
build(
ColumnValue::VarChar(scalar_string(field, begin, end, valid)),
valid_slice(valid, begin, end),
)
@schema.DataType::Text =>
build(
ColumnValue::Text(scalar_string(field, begin, end, valid)),
valid_slice(valid, begin, end),
)
@schema.DataType::Timestamptz =>
build(
ColumnValue::Timestamptz(scalar_long(field, begin, end, valid)),
valid_slice(valid, begin, end),
)
@schema.DataType::JSON =>
build(
ColumnValue::Json(scalar_bytes(field, begin, end, valid)),
valid_slice(valid, begin, end),
)
@schema.DataType::Geometry =>
build(
ColumnValue::Geometry(scalar_string(field, begin, end, valid)),
valid_slice(valid, begin, end),
)
@schema.DataType::Array =>
build(
ColumnValue::Array(array_rows(field, begin, end, valid)),
valid_slice(valid, begin, end),
)
@schema.DataType::FloatVector => {
let (dim, rows) = vector_float_rows(field, begin, end, valid)
build(ColumnValue::FloatVector(dim, rows), valid_slice(valid, begin, end))
}
@schema.DataType::Float16Vector => {
let (dim, rows) = vector_float16_rows(field, begin, end, valid)
build(
ColumnValue::Float16Vector(dim, rows),
valid_slice(valid, begin, end),
)
}
@schema.DataType::BFloat16Vector => {
let (dim, rows) = vector_bfloat16_rows(field, begin, end, valid)
build(
ColumnValue::BFloat16Vector(dim, rows),
valid_slice(valid, begin, end),
)
}
@schema.DataType::BinaryVector => {
let (dim, rows) = vector_binary_rows(field, begin, end, valid)
build(
ColumnValue::BinaryVector(dim, rows),
valid_slice(valid, begin, end),
)
}
@schema.DataType::Int8Vector => {
let (dim, rows) = vector_int8_rows(field, begin, end, valid)
build(ColumnValue::Int8Vector(dim, rows), valid_slice(valid, begin, end))
}
@schema.DataType::SparseFloatVector =>
build(
ColumnValue::SparseFloatVector(sparse_rows(field, begin, end, valid)),
valid_slice(valid, begin, end),
)
other =>
raise UnsupportedType(
"unsupported field data type \{data_type_name(other)}",
)
}
}