mirror of
https://github.com/lancedb/lancedb.git
synced 2026-09-04 04:28:44 +00:00
refactor: simplify Function binding identity (#4046)
Function applications and bindings currently encode `group_id` and binding `revision` even though `binding_id` already owns the complete immutable binding lifecycle and `outputs` already defines the atomic multi-output set. Make `binding_id` the sole binding identity, remove the redundant fields from the Rust and Python client contracts, and describe multi-output declarations directly. This intentionally replaces the removed wire fields without a compatibility path.
This commit is contained in:
@@ -25,7 +25,6 @@ import re
|
||||
import sys
|
||||
import textwrap
|
||||
import types
|
||||
import uuid
|
||||
from collections.abc import Mapping
|
||||
from datetime import date, datetime
|
||||
from typing import (
|
||||
@@ -276,7 +275,7 @@ class FunctionVersion(_RemoteValue):
|
||||
|
||||
Every input must be a direct [lancedb.col][lancedb.expr.col]
|
||||
reference. The returned application is immutable and retains a
|
||||
named-struct output as one sibling group, so every row's sibling values
|
||||
named-struct output as one binding, so every row's sibling values
|
||||
come from one logical Function evaluation. Map result fields to table
|
||||
columns with
|
||||
[FunctionApplication.rename][lancedb.functions.FunctionApplication.rename],
|
||||
@@ -326,7 +325,6 @@ class FunctionVersion(_RemoteValue):
|
||||
function=FunctionVersionRef(name=self.name, version=self.version),
|
||||
inputs=tuple(bindings),
|
||||
output=self.signature.output,
|
||||
group_id=f"fg_{uuid.uuid4().hex}",
|
||||
)
|
||||
|
||||
|
||||
@@ -370,7 +368,7 @@ class ApplicationInput(_OpenRemoteValue):
|
||||
class FunctionApplication(_OpenRemoteValue):
|
||||
"""Immutable pre-declaration application of an exact Function version.
|
||||
|
||||
A named-struct output remains one grouped application through table
|
||||
A named-struct output remains one application through table
|
||||
declaration and execution.
|
||||
[FunctionApplication.rename][lancedb.functions.FunctionApplication.rename]
|
||||
records the result-field to table-column mapping without splitting sibling
|
||||
@@ -380,7 +378,6 @@ class FunctionApplication(_OpenRemoteValue):
|
||||
function: FunctionVersionRef
|
||||
inputs: tuple[ApplicationInput, ...]
|
||||
output: FunctionOutput
|
||||
group_id: str
|
||||
columns: Mapping[str, str] = Field(default_factory=dict)
|
||||
|
||||
def _known_dict(self) -> dict[str, Any]:
|
||||
@@ -452,12 +449,10 @@ class OutputMapping(_RemoteValue):
|
||||
|
||||
|
||||
class FunctionBinding(_RemoteValue):
|
||||
"""Immutable grouped binding persisted by the Enterprise table service."""
|
||||
"""Immutable Function binding persisted by the Enterprise table service."""
|
||||
|
||||
binding_id: str
|
||||
revision: _UInt64
|
||||
function: FunctionVersionRef
|
||||
group_id: str
|
||||
inputs: tuple[InputBinding, ...]
|
||||
outputs: tuple[OutputMapping, ...]
|
||||
input_schema: Optional[Mapping[str, Any]] = None
|
||||
|
||||
@@ -1972,7 +1972,7 @@ class Table(ABC):
|
||||
A mapping with one ``FunctionApplication`` value keeps its scalar
|
||||
or named-struct result in the named table column. A bare
|
||||
named-struct application expands its ordered result fields as one
|
||||
atomic sibling group; aliases come from ``rename(columns=...)``.
|
||||
atomic binding; aliases come from ``rename(columns=...)``.
|
||||
Function columns are supported only on LanceDB Cloud and
|
||||
Enterprise.
|
||||
computed: Dict[str, str], optional
|
||||
@@ -6038,7 +6038,7 @@ class AsyncTable:
|
||||
A mapping with one ``FunctionApplication`` value keeps its scalar
|
||||
or named-struct result in the named table column. A bare
|
||||
named-struct application expands its ordered result fields as one
|
||||
atomic sibling group; aliases come from ``rename(columns=...)``.
|
||||
atomic binding; aliases come from ``rename(columns=...)``.
|
||||
Function columns are supported only on LanceDB Cloud and
|
||||
Enterprise.
|
||||
computed: Dict[str, str], optional
|
||||
@@ -6075,7 +6075,7 @@ class AsyncTable:
|
||||
isinstance(value, FunctionApplication) for value in transforms.values()
|
||||
):
|
||||
raise ValueError(
|
||||
"one add_columns call declares exactly one Function sibling group"
|
||||
"one add_columns call declares exactly one Function binding"
|
||||
)
|
||||
function_output_name, function_application = next(iter(transforms.items()))
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ def test_function_version_identity_is_immutable_and_exact():
|
||||
assert FunctionVersion(**changed) != version
|
||||
|
||||
|
||||
def test_function_version_binds_named_columns_as_one_immutable_group():
|
||||
def test_function_version_binds_named_columns_as_one_immutable_application():
|
||||
version = FunctionVersion.from_json(
|
||||
json.dumps(job_result("remote_function_job.json"))
|
||||
)
|
||||
@@ -131,13 +131,10 @@ def test_function_version_binds_named_columns_as_one_immutable_group():
|
||||
assert application.function.name == version.name
|
||||
assert application.function.version == version.version
|
||||
assert application.output is version.signature.output
|
||||
assert application.group_id.startswith("fg_")
|
||||
assert [
|
||||
(value.parameter, value.kind, value.value["path"])
|
||||
for value in application.inputs
|
||||
] == [("text", "column", "documents.body")]
|
||||
with pytest.raises((TypeError, ValueError)):
|
||||
application.group_id = "fg_changed"
|
||||
|
||||
|
||||
def test_function_version_binding_validates_names_and_direct_columns():
|
||||
@@ -156,7 +153,7 @@ def test_function_version_binding_validates_names_and_direct_columns():
|
||||
def test_function_version_keeps_named_struct_outputs_in_one_application():
|
||||
value = job_result("remote_function_job.json")
|
||||
value["name"] = "text_features"
|
||||
value["version"] = "fv_grouped"
|
||||
value["version"] = "fv_multi_output"
|
||||
value["signature"] = {
|
||||
"inputs": [
|
||||
{"name": "title", "arrow_type": "utf8", "nullable": True},
|
||||
@@ -221,7 +218,6 @@ def test_function_application_uses_rename_columns_only():
|
||||
assert application.columns["normalized_text"] == "search_text"
|
||||
assert renamed.columns["normalized_text"] == "body_normalized"
|
||||
assert renamed.function == application.function
|
||||
assert renamed.group_id == application.group_id
|
||||
assert not hasattr(application, "rename_outputs")
|
||||
with pytest.raises(TypeError, match="immutable"):
|
||||
renamed.columns["normalized_text"] = "changed"
|
||||
@@ -242,7 +238,6 @@ def test_function_application_uses_rename_columns_only():
|
||||
|
||||
def test_binding_and_refresh_result_keep_stable_remote_fields():
|
||||
binding = FunctionBinding.from_json(fixture("remote_function_binding.json"))
|
||||
assert binding.revision == 3
|
||||
assert binding.function.version == "fv_01K3TEXT"
|
||||
assert [output.output_ordinal for output in binding.outputs] == [0, 1]
|
||||
assert binding.input_schema is not None
|
||||
@@ -322,7 +317,7 @@ def known_application() -> FunctionApplication:
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_add_columns_routes_struct_as_one_and_grouped_expansion_atomically():
|
||||
async def test_add_columns_routes_struct_as_one_and_multi_output_binding_atomically():
|
||||
inner = _FunctionDeclarationInner()
|
||||
table = AsyncTable(inner)
|
||||
application = known_application()
|
||||
@@ -343,12 +338,12 @@ async def test_add_columns_routes_struct_as_one_and_grouped_expansion_atomically
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_add_columns_rejects_mixed_groups_and_unknown_newer_application():
|
||||
async def test_add_columns_rejects_multiple_bindings_and_unknown_newer_application():
|
||||
inner = _FunctionDeclarationInner()
|
||||
table = AsyncTable(inner)
|
||||
application = known_application()
|
||||
|
||||
with pytest.raises(ValueError, match="exactly one Function sibling group"):
|
||||
with pytest.raises(ValueError, match="exactly one Function binding"):
|
||||
await table.add_columns({"a": application, "b": application})
|
||||
|
||||
future = json.loads(fixture("remote_function_application.json"))
|
||||
@@ -376,7 +371,6 @@ def test_rename_requires_named_struct_and_keeps_partial_mapping_immutable():
|
||||
"arrow_type": "list<float32>",
|
||||
"nullable": False,
|
||||
},
|
||||
"group_id": "fg_scalar",
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
@@ -446,7 +446,6 @@ pub struct FunctionApplication {
|
||||
function: FunctionVersionRef,
|
||||
inputs: Vec<ApplicationInput>,
|
||||
output: FunctionOutput,
|
||||
group_id: String,
|
||||
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
|
||||
columns: BTreeMap<String, String>,
|
||||
#[serde(default, flatten, skip_serializing)]
|
||||
@@ -468,10 +467,6 @@ impl FunctionApplication {
|
||||
&self.output
|
||||
}
|
||||
|
||||
pub fn group_id(&self) -> &str {
|
||||
&self.group_id
|
||||
}
|
||||
|
||||
pub fn columns(&self) -> &BTreeMap<String, String> {
|
||||
&self.columns
|
||||
}
|
||||
@@ -513,7 +508,7 @@ pub struct InputBinding {
|
||||
pub nullable: bool,
|
||||
}
|
||||
|
||||
/// Ordered result-field to table-field mapping for a grouped binding.
|
||||
/// Ordered result-field to table-field mapping for a Function binding.
|
||||
///
|
||||
/// Assignment state is not part of the Slice 1 client contract. During the
|
||||
/// NULL transition there is no public Lance cell-flag identifier to persist.
|
||||
@@ -527,20 +522,18 @@ pub struct OutputMapping {
|
||||
pub nullable: bool,
|
||||
}
|
||||
|
||||
/// Immutable grouped binding persisted by the Enterprise table service.
|
||||
/// Immutable Function binding persisted by the Enterprise table service.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct FunctionBinding {
|
||||
binding_id: String,
|
||||
revision: u64,
|
||||
function: FunctionVersionRef,
|
||||
group_id: String,
|
||||
inputs: Vec<InputBinding>,
|
||||
outputs: Vec<OutputMapping>,
|
||||
/// Exact Arrow schema presented to the Function, encoded with the Lance
|
||||
/// Namespace Arrow JSON representation.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
input_schema: Option<Value>,
|
||||
/// Exact physical Arrow schema of the grouped table outputs.
|
||||
/// Exact physical Arrow schema of the binding's table outputs.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
output_schema: Option<Value>,
|
||||
}
|
||||
@@ -550,18 +543,10 @@ impl FunctionBinding {
|
||||
&self.binding_id
|
||||
}
|
||||
|
||||
pub fn revision(&self) -> u64 {
|
||||
self.revision
|
||||
}
|
||||
|
||||
pub fn function(&self) -> &FunctionVersionRef {
|
||||
&self.function
|
||||
}
|
||||
|
||||
pub fn group_id(&self) -> &str {
|
||||
&self.group_id
|
||||
}
|
||||
|
||||
pub fn inputs(&self) -> &[InputBinding] {
|
||||
&self.inputs
|
||||
}
|
||||
|
||||
@@ -1774,11 +1774,14 @@ mod tests {
|
||||
.postfilter();
|
||||
let result = query.execute().await;
|
||||
let mut stream = result.expect("should have result");
|
||||
// should only have one batch
|
||||
let mut num_rows = 0;
|
||||
while let Some(batch) = stream.next().await {
|
||||
// post filter should have removed some rows
|
||||
assert!(batch.expect("should be Ok").num_rows() < 10);
|
||||
let batch = batch.expect("should be Ok");
|
||||
let ids: &Int32Array = batch["id"].as_primitive();
|
||||
assert!(ids.iter().all(|id| id.unwrap() % 2 == 0));
|
||||
num_rows += batch.num_rows();
|
||||
}
|
||||
assert!(num_rows <= 10);
|
||||
|
||||
let query = table
|
||||
.query()
|
||||
|
||||
@@ -6787,8 +6787,7 @@ mod tests {
|
||||
r#"{
|
||||
"function":{"name":"embed","version":"fv_01K3EXACT"},
|
||||
"inputs":[{"parameter":"text","kind":"column","value":{"path":"description"}}],
|
||||
"output":{"kind":"scalar","arrow_type":"list<float32>","nullable":false},
|
||||
"group_id":"fg_scalar"
|
||||
"output":{"kind":"scalar","arrow_type":"list<float32>","nullable":false}
|
||||
}"#,
|
||||
)
|
||||
.unwrap();
|
||||
@@ -6834,8 +6833,7 @@ mod tests {
|
||||
r#"{
|
||||
"function":{"name":"embed","version":"fv_01K3EXACT"},
|
||||
"inputs":[{"parameter":"text","kind":"column","value":{"path":"description"}}],
|
||||
"output":{"kind":"scalar","arrow_type":"fixed_size_list<float32, 3>","nullable":false},
|
||||
"group_id":"fg_fixed"
|
||||
"output":{"kind":"scalar","arrow_type":"fixed_size_list<float32, 3>","nullable":false}
|
||||
}"#,
|
||||
)
|
||||
.unwrap();
|
||||
@@ -6850,7 +6848,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_add_named_struct_function_expands_one_atomic_sibling_group() {
|
||||
async fn test_add_named_struct_function_expands_one_atomic_binding() {
|
||||
let table = Table::new_with_handler("my_table", |request| match request.url().path() {
|
||||
"/v1/table/my_table/describe/" => http::Response::builder()
|
||||
.status(200)
|
||||
@@ -6865,7 +6863,7 @@ mod tests {
|
||||
let actual: serde_json::Value =
|
||||
serde_json::from_slice(request.body().unwrap().as_bytes().unwrap()).unwrap();
|
||||
let expected: serde_json::Value = serde_json::from_str(include_str!(
|
||||
"../../tests/fixtures/first_class_functions/v1/remote_grouped_declaration_request.json"
|
||||
"../../tests/fixtures/first_class_functions/v1/remote_multi_output_declaration_request.json"
|
||||
))
|
||||
.unwrap();
|
||||
assert_eq!(actual, expected);
|
||||
@@ -6887,7 +6885,6 @@ mod tests {
|
||||
{"name":"normalized_text","arrow_type":"utf8","nullable":false},
|
||||
{"name":"token_count","arrow_type":"int64","nullable":false}
|
||||
]},
|
||||
"group_id":"fg_01K3TEXT",
|
||||
"columns":{"normalized_text":"search_text"}
|
||||
}"#,
|
||||
)
|
||||
|
||||
@@ -751,7 +751,7 @@ pub trait BaseTable: std::fmt::Display + std::fmt::Debug + Send + Sync {
|
||||
message: "computed columns are not supported on this table type".into(),
|
||||
})
|
||||
}
|
||||
/// Declare one immutable registered-Function output group.
|
||||
/// Declare one immutable registered-Function binding.
|
||||
async fn add_function_columns(
|
||||
&self,
|
||||
_application: &crate::function::FunctionApplication,
|
||||
|
||||
@@ -88,7 +88,7 @@ impl AddColumnsBuilder {
|
||||
}
|
||||
|
||||
/// Declare every field of a named-struct Function result as one atomic
|
||||
/// sibling group. Result-field aliases come from
|
||||
/// binding. Result-field aliases come from
|
||||
/// [`FunctionApplication::columns`](crate::function::FunctionApplication::columns).
|
||||
///
|
||||
/// ```
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
//! self-describing -- both are derived from the expression, so a caller writes
|
||||
//! neither -- while a kind resolved through a registry cannot be typed without
|
||||
//! consulting it. Registered Functions use an exact remote version plus a
|
||||
//! schema-level grouped binding; unknown newer kinds remain readable and fail
|
||||
//! schema-level Function binding; unknown newer kinds remain readable and fail
|
||||
//! closed before mutation.
|
||||
//!
|
||||
//! [`computed_columns`] and [`computed_column_from_field`] read declarations
|
||||
@@ -46,16 +46,16 @@ pub const EXPRESSION_META_KEY: &str = "computed_column.expression";
|
||||
/// Field metadata key holding the column's inputs, as a JSON array of names.
|
||||
pub const INPUTS_META_KEY: &str = "computed_column.inputs";
|
||||
|
||||
/// Field metadata key holding the grouped Function binding identity.
|
||||
/// Field metadata key holding the Function binding identity.
|
||||
pub const FUNCTION_BINDING_ID_META_KEY: &str = "computed_column.function.binding_id";
|
||||
|
||||
/// Field metadata key holding this sibling's ordered Function output ordinal.
|
||||
pub const FUNCTION_OUTPUT_ORDINAL_META_KEY: &str = "computed_column.function.output_ordinal";
|
||||
|
||||
/// Schema metadata key holding all immutable grouped Function bindings.
|
||||
/// Schema metadata key holding all immutable Function bindings.
|
||||
pub const FUNCTION_BINDINGS_META_KEY: &str = "lancedb::function_bindings";
|
||||
|
||||
/// Version of the schema-level grouped Function binding envelope.
|
||||
/// Version of the schema-level Function binding envelope.
|
||||
pub const FUNCTION_BINDINGS_VERSION: u32 = 1;
|
||||
|
||||
/// Value of [`KIND_META_KEY`] for a column defined by a SQL expression.
|
||||
@@ -81,7 +81,7 @@ pub enum ComputedColumnKind {
|
||||
/// The expression.
|
||||
expression: String,
|
||||
},
|
||||
/// One physical output in an immutable grouped registered-Function
|
||||
/// One physical output in an immutable registered-Function
|
||||
/// binding. The full binding lives in schema metadata.
|
||||
Function {
|
||||
/// Shared immutable binding identity.
|
||||
@@ -159,7 +159,7 @@ struct FunctionBindingEnvelope {
|
||||
bindings: Vec<Value>,
|
||||
}
|
||||
|
||||
/// Encode immutable grouped bindings for schema-level persistence.
|
||||
/// Encode immutable Function bindings for schema-level persistence.
|
||||
pub fn function_bindings_metadata(bindings: &[FunctionBinding]) -> Result<String> {
|
||||
let bindings = bindings
|
||||
.iter()
|
||||
@@ -177,7 +177,7 @@ pub fn function_bindings_metadata(bindings: &[FunctionBinding]) -> Result<String
|
||||
})
|
||||
}
|
||||
|
||||
/// Decode known grouped Function bindings without rewriting their raw schema
|
||||
/// Decode known Function bindings without rewriting their raw schema
|
||||
/// metadata. Unknown envelope versions fail closed.
|
||||
pub fn function_bindings(schema: &ArrowSchema) -> Result<Vec<FunctionBinding>> {
|
||||
let Some(envelope) = function_binding_envelope(schema)? else {
|
||||
@@ -238,21 +238,15 @@ pub(crate) fn ensure_supported_function_metadata(schema: &ArrowSchema) -> Result
|
||||
message: format!("duplicate Function binding '{}'", binding.binding_id()),
|
||||
});
|
||||
}
|
||||
if binding.revision() == 0 || binding.outputs().is_empty() {
|
||||
if binding.outputs().is_empty() {
|
||||
return Err(Error::InvalidInput {
|
||||
message: format!(
|
||||
"Function binding '{}' has no immutable revision or outputs",
|
||||
binding.binding_id()
|
||||
),
|
||||
message: format!("Function binding '{}' has no outputs", binding.binding_id()),
|
||||
});
|
||||
}
|
||||
if binding.function().name.is_empty()
|
||||
|| binding.function().version.is_empty()
|
||||
|| binding.group_id().is_empty()
|
||||
{
|
||||
if binding.function().name.is_empty() || binding.function().version.is_empty() {
|
||||
return Err(Error::InvalidInput {
|
||||
message: format!(
|
||||
"Function binding '{}' has no exact version or group identity",
|
||||
"Function binding '{}' has no exact version",
|
||||
binding.binding_id()
|
||||
),
|
||||
});
|
||||
@@ -493,9 +487,7 @@ fn ensure_known_binding_shape(value: &Value) -> Result<()> {
|
||||
value,
|
||||
&[
|
||||
"binding_id",
|
||||
"revision",
|
||||
"function",
|
||||
"group_id",
|
||||
"inputs",
|
||||
"outputs",
|
||||
"input_schema",
|
||||
@@ -786,12 +778,9 @@ pub(crate) fn plan_function_application(
|
||||
message: "Function application contains fields from a newer contract".into(),
|
||||
});
|
||||
}
|
||||
if application.function().name.is_empty()
|
||||
|| application.function().version.is_empty()
|
||||
|| application.group_id().is_empty()
|
||||
{
|
||||
if application.function().name.is_empty() || application.function().version.is_empty() {
|
||||
return Err(invalid_function(
|
||||
"Function application requires an exact version and group identity",
|
||||
"Function application requires an exact version",
|
||||
));
|
||||
}
|
||||
|
||||
@@ -2261,7 +2250,6 @@ mod tests {
|
||||
{{"name":"normalized_text","arrow_type":"utf8","nullable":false}},
|
||||
{{"name":"token_count","arrow_type":"int64","nullable":false}}
|
||||
]}},
|
||||
"group_id":"fg_exact",
|
||||
"columns":{columns}
|
||||
}}"#
|
||||
))
|
||||
@@ -2442,8 +2430,7 @@ mod tests {
|
||||
r#"{
|
||||
"function":{"name":"f","version":"fv"},
|
||||
"inputs":[{"parameter":"title","kind":"future_source","value":{"path":"title"}}],
|
||||
"output":{"kind":"scalar","arrow_type":"int64","nullable":false},
|
||||
"group_id":"fg"
|
||||
"output":{"kind":"scalar","arrow_type":"int64","nullable":false}
|
||||
}"#,
|
||||
)
|
||||
.unwrap();
|
||||
@@ -2456,7 +2443,6 @@ mod tests {
|
||||
"function":{"name":"f","version":"fv"},
|
||||
"inputs":[],
|
||||
"output":{"kind":"scalar","arrow_type":"int64","nullable":false},
|
||||
"group_id":"fg",
|
||||
"future_declaration":{"mode":"managed"}
|
||||
}"#,
|
||||
)
|
||||
@@ -2470,8 +2456,7 @@ mod tests {
|
||||
r#"{
|
||||
"function":{"name":"f","version":"fv"},
|
||||
"inputs":[],
|
||||
"output":{"kind":"scalar","arrow_type":"int64","nullable":false,"assignment":"cell_flag"},
|
||||
"group_id":"fg"
|
||||
"output":{"kind":"scalar","arrow_type":"int64","nullable":false,"assignment":"cell_flag"}
|
||||
}"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -84,7 +84,6 @@ fn application_and_binding_match_shared_remote_goldens() {
|
||||
|
||||
let binding = FunctionBinding::from_json(&fixture("remote_function_binding.json"))
|
||||
.expect("binding fixture");
|
||||
assert_eq!(binding.revision(), 3);
|
||||
assert_eq!(binding.function().version, "fv_01K3TEXT");
|
||||
assert_eq!(binding.outputs()[0].output_ordinal, 0);
|
||||
assert_eq!(binding.outputs()[1].output_ordinal, 1);
|
||||
|
||||
Vendored
+2
-3
@@ -24,8 +24,7 @@
|
||||
"kind": "scalar",
|
||||
"arrow_type": "fixed_size_list<float32, 3>",
|
||||
"nullable": false
|
||||
},
|
||||
"group_id": "fg_fixed"
|
||||
}
|
||||
},
|
||||
"binding_metadata_version": 1,
|
||||
"input_bindings": [
|
||||
@@ -76,4 +75,4 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
{"columns":{"normalized_text":"search_text","token_count":"search_token_count"},"function":{"name":"text_features","version":"fv_01K3TEXT"},"group_id":"fg_01K3TEXT","inputs":[{"kind":"column","parameter":"title","value":{"path":"title"}},{"kind":"column","parameter":"body","value":{"path":"body"}}],"output":{"fields":[{"arrow_type":"utf8","name":"normalized_text","nullable":false},{"arrow_type":"int64","name":"token_count","nullable":false}],"kind":"named_struct"}}
|
||||
{"columns":{"normalized_text":"search_text","token_count":"search_token_count"},"function":{"name":"text_features","version":"fv_01K3TEXT"},"inputs":[{"kind":"column","parameter":"title","value":{"path":"title"}},{"kind":"column","parameter":"body","value":{"path":"body"}}],"output":{"fields":[{"arrow_type":"utf8","name":"normalized_text","nullable":false},{"arrow_type":"int64","name":"token_count","nullable":false}],"kind":"named_struct"}}
|
||||
|
||||
-1
@@ -11,7 +11,6 @@
|
||||
{"name": "token_count", "arrow_type": "int64", "nullable": false}
|
||||
]
|
||||
},
|
||||
"group_id": "fg_01K3TEXT",
|
||||
"columns": {
|
||||
"normalized_text": "search_text",
|
||||
"token_count": "search_token_count"
|
||||
|
||||
Vendored
+1
-2
@@ -3,6 +3,5 @@
|
||||
"inputs": [
|
||||
{"parameter": "threshold", "kind": "literal", "value": 1e-7}
|
||||
],
|
||||
"output": {"kind": "scalar", "arrow_type": "bool", "nullable": false},
|
||||
"group_id": "fg_01K3FLOAT"
|
||||
"output": {"kind": "scalar", "arrow_type": "bool", "nullable": false}
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
{"binding_id":"fb_01K3TEXT","function":{"name":"text_features","version":"fv_01K3TEXT"},"group_id":"fg_01K3TEXT","input_schema":{"fields":[{"name":"title","nullable":true,"type":{"type":"utf8"}},{"name":"body","nullable":true,"type":{"type":"utf8"}}]},"inputs":[{"arrow_type":"utf8","field_id":11,"field_path":"title","nullable":true,"parameter":"title"},{"arrow_type":"utf8","field_id":12,"field_path":"body","nullable":true,"parameter":"body"}],"output_schema":{"fields":[{"name":"search_text","nullable":true,"type":{"type":"utf8"}},{"name":"search_token_count","nullable":true,"type":{"type":"int64"}}]},"outputs":[{"arrow_type":"utf8","nullable":false,"output_field_id":21,"output_name":"search_text","output_ordinal":0,"result_field":"normalized_text"},{"arrow_type":"int64","nullable":false,"output_field_id":22,"output_name":"search_token_count","output_ordinal":1,"result_field":"token_count"}],"revision":3}
|
||||
{"binding_id":"fb_01K3TEXT","function":{"name":"text_features","version":"fv_01K3TEXT"},"input_schema":{"fields":[{"name":"title","nullable":true,"type":{"type":"utf8"}},{"name":"body","nullable":true,"type":{"type":"utf8"}}]},"inputs":[{"arrow_type":"utf8","field_id":11,"field_path":"title","nullable":true,"parameter":"title"},{"arrow_type":"utf8","field_id":12,"field_path":"body","nullable":true,"parameter":"body"}],"output_schema":{"fields":[{"name":"search_text","nullable":true,"type":{"type":"utf8"}},{"name":"search_token_count","nullable":true,"type":{"type":"int64"}}]},"outputs":[{"arrow_type":"utf8","nullable":false,"output_field_id":21,"output_name":"search_text","output_ordinal":0,"result_field":"normalized_text"},{"arrow_type":"int64","nullable":false,"output_field_id":22,"output_name":"search_token_count","output_ordinal":1,"result_field":"token_count"}]}
|
||||
|
||||
+1
-3
@@ -1,8 +1,6 @@
|
||||
{
|
||||
"binding_id": "fb_01K3TEXT",
|
||||
"revision": 3,
|
||||
"function": {"name": "text_features", "version": "fv_01K3TEXT"},
|
||||
"group_id": "fg_01K3TEXT",
|
||||
"inputs": [
|
||||
{"parameter": "title", "field_id": 11, "field_path": "title", "arrow_type": "utf8", "nullable": true},
|
||||
{"parameter": "body", "field_id": 12, "field_path": "body", "arrow_type": "utf8", "nullable": true}
|
||||
@@ -23,5 +21,5 @@
|
||||
{"name": "search_token_count", "nullable": true, "type": {"type": "int64"}}
|
||||
]
|
||||
},
|
||||
"future_binding": {"metadata_revision": 1}
|
||||
"future_binding": {"mode": "managed"}
|
||||
}
|
||||
|
||||
-1
@@ -17,7 +17,6 @@
|
||||
{"name": "token_count", "arrow_type": "int64", "nullable": false}
|
||||
]
|
||||
},
|
||||
"group_id": "fg_01K3TEXT",
|
||||
"columns": {"normalized_text": "search_text"}
|
||||
},
|
||||
"binding_metadata_version": 1,
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
"job_type": "refresh_function_columns",
|
||||
"job_state": "DONE",
|
||||
"creation_ms": 1787270400001,
|
||||
"spec": {"table": "documents", "binding_revision": 3},
|
||||
"spec": {"table": "documents", "binding_id": "fb_01K3TEXT"},
|
||||
"result": {
|
||||
"rows_assigned": 999998800,
|
||||
"rows_failed": 0,
|
||||
|
||||
Vendored
+1
-2
@@ -8,8 +8,7 @@
|
||||
"inputs": [
|
||||
{"parameter": "text", "kind": "column", "value": {"path": "description"}}
|
||||
],
|
||||
"output": {"kind": "scalar", "arrow_type": "list<float32>", "nullable": false},
|
||||
"group_id": "fg_scalar"
|
||||
"output": {"kind": "scalar", "arrow_type": "list<float32>", "nullable": false}
|
||||
},
|
||||
"binding_metadata_version": 1,
|
||||
"input_bindings": [
|
||||
|
||||
Reference in New Issue
Block a user