### Install extension targets Source: https://github.com/lance-format/lance-duckdb/blob/main/CMakeLists.txt Installs the extension targets (libraries) to the specified destination directory. This command is used after the targets have been built and linked. ```cmake install( TARGETS ${EXTENSION_NAME} EXPORT "${DUCKDB_EXPORT_SET}" LIBRARY DESTINATION "${INSTALL_LIB_DIR}" ARCHIVE DESTINATION "${INSTALL_LIB_DIR}") ``` -------------------------------- ### Initial Setup and Build Commands for Lance DuckDB Extension Source: https://github.com/lance-format/lance-duckdb/blob/main/AGENTS.md Commands for initial setup, building the extension in release or debug mode, and cleaning build artifacts. Requires DuckDB extension tooling. ```bash git submodule update --init --recursive ``` ```bash make ``` ```bash GEN=ninja make release ``` ```bash GEN=ninja make debug ``` ```bash GEN=ninja make clean ``` ```bash GEN=ninja make clean_all ``` -------------------------------- ### Install and Load Lance Extension Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Installs the Lance extension from the community repository and loads it into DuckDB. For local development, load the extension artifact directly. ```sql INSTALL lance FROM community; LOAD lance; ``` ```sql LOAD 'build/release/extension/lance/lance.duckdb_extension'; ``` -------------------------------- ### Class Structure Example in C++ Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/cpp_guidelines.md Demonstrates the recommended structure for C++ classes, including the ordering of public and private members and methods. ```cpp class MyClass { public: MyClass(); int my_public_variable; public: void MyFunction(); private: void MyPrivateFunction(); private: int my_private_variable; }; ``` -------------------------------- ### Install Lance Extension from DuckDB Source: https://github.com/lance-format/lance-duckdb/blob/main/README.md Install and load the Lance extension directly from DuckDB's core extensions. This is the recommended method for users who only need to utilize the extension. ```sql INSTALL lance; LOAD lance; SELECT * FROM 'path/to/dataset.lance' LIMIT 1; ``` -------------------------------- ### Install and Load Lance Extension Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/index.md Commands to install and load the Lance extension in the DuckDB CLI. Use UPDATE EXTENSIONS to get the latest version if already installed. ```sql INSTALL lance; LOAD lance; ``` ```sql UPDATE EXTENSIONS; ``` -------------------------------- ### C++ Range-based For Loop Example Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/cpp_guidelines.md Illustrates the preferred C++11 range-based for loop syntax for iterating over collections. ```cpp for (const auto& item : items) {...} ``` -------------------------------- ### Example: Custom HTTP Headers for REST Namespace Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/rest.md Pass custom HTTP headers to the REST Namespace server using semicolon-separated key-value pairs within the HEADER option. ```sql HEADER 'x-lancedb-database=my_db;x-api-key=sk_xxx;x-custom-header=value' ``` -------------------------------- ### Create LANCE Secret for MinIO with HTTP Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/cloud.md Example of creating a LANCE secret for a MinIO instance. It includes specific configurations like endpoint, disabling virtual hosted style requests, and allowing HTTP connections for local testing. ```sql CREATE SECRET ( TYPE LANCE, PROVIDER config, SCOPE 's3://my-bucket/', ACCESS_KEY_ID 'minioadmin', SECRET_ACCESS_KEY 'minioadmin', REGION 'us-east-1', ENDPOINT 'http://127.0.0.1:9000', VIRTUAL_HOSTED_STYLE_REQUEST false, ALLOW_HTTP true ); ``` -------------------------------- ### Generate BigANN Tiny Fixture with Lance Source: https://github.com/lance-format/lance-duckdb/blob/main/test/data/bigann_tiny/GENERATION.md This script generates the bigann_tiny fixture, including base vectors, query vectors, ground truth data, and creates a Lance dataset with an IVF_PQ index. It requires numpy, pyarrow, and lance to be installed. ```bash python3 -m venv venv source venv/bin/activate python -m pip install numpy pyarrow pylance ``` ```python from __future__ import annotations import json from pathlib import Path import numpy as np import pyarrow as pa import lance OUT_DIR = Path("test/data/bigann_tiny") BASE_PATH = OUT_DIR / "base.lance" QUERIES_PATH = OUT_DIR / "queries.lance" TRUTH_ALL_PATH = OUT_DIR / "groundtruth_all_top10.lance" TRUTH_LABEL1_PATH = OUT_DIR / "groundtruth_label1_top10.lance" SEED = 1337 DIM = 16 N_ROWS = 2048 N_QUERIES = 32 K = 10 rng = np.random.default_rng(SEED) ids = np.arange(N_ROWS, dtype=np.int64) labels = (ids % 8 == 0).astype(np.int8) buckets = (ids % 16).astype(np.int32) centers = np.where(labels[:, None] == 1, 10.0, 0.0).astype(np.float32) noise = rng.normal(loc=0.0, scale=0.35, size=(N_ROWS, DIM)).astype(np.float32) base_vecs = centers + noise queries = rng.normal(loc=0.0, scale=0.35, size=(N_QUERIES, DIM)).astype(np.float32) qids = np.arange(N_QUERIES, dtype=np.int32) def fsl(arr: np.ndarray) -> pa.FixedSizeListArray: values = pa.array(arr.reshape(-1).tolist(), type=pa.float32()) return pa.FixedSizeListArray.from_arrays(values, arr.shape[1]) def write(table: pa.Table, path: Path) -> lance.LanceDataset: if path.exists(): import shutil shutil.rmtree(path) lance.write_dataset(table, str(path), mode="create") return lance.dataset(str(path)) OUT_DIR.mkdir(parents=True, exist_ok=True) base = write(pa.table({"id": ids, "label": labels, "bucket": buckets, "vec": fsl(base_vecs)}), BASE_PATH) _ = write(pa.table({"qid": qids, "vec": fsl(queries)}), QUERIES_PATH) truth_all, truth_label1 = [], [] for qid, q in enumerate(queries): diffs = base_vecs - q[None, :] dists = np.sum(diffs * diffs, axis=1) topk = np.argsort(dists, kind="stable")[:K] truth_all.extend((qid, rank, int(ids[i]), float(dists[i])) for rank, i in enumerate(topk)) mask = labels == 1 d1 = dists[mask] i1 = ids[mask] topk1 = np.argsort(d1, kind="stable")[:K] truth_label1.extend((qid, rank, int(i1[p]), float(d1[p])) for rank, p in enumerate(topk1)) schema = pa.schema([("qid", pa.int32()), ("rank", pa.int32()), ("id", pa.int64()), ("distance", pa.float32())]) _ = write(pa.Table.from_pylist([{"qid": q, "rank": r, "id": i, "distance": d} for q, r, i, d in truth_all], schema=schema), TRUTH_ALL_PATH) _ = write(pa.Table.from_pylist([{"qid": q, "rank": r, "id": i, "distance": d} for q, r, i, d in truth_label1], schema=schema), TRUTH_LABEL1_PATH) base.create_index("vec", index_type="IVF_PQ", metric="L2", replace=True, num_partitions=8, num_sub_vectors=4) meta = { "seed": SEED, "dim": DIM, "rows": N_ROWS, "queries": N_QUERIES, "k": K, "metric": "L2", "label_rule": "label=1 iff id % 8 == 0", "bucket_rule": "bucket = id % 16", "clusters": {"label0_center": 0.0, "label1_center": 10.0, "noise_stddev": 0.35}, "packages": {"numpy": np.__version__, "pyarrow": pa.__version__, "pylance": getattr(lance, "__version__", "unknown")}, } (OUT_DIR / "metadata.json").write_text(json.dumps(meta, indent=2) + "\n", encoding="utf-8") print("done:", OUT_DIR) ``` -------------------------------- ### Debug-only Assertion Example in C++ Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/cpp_guidelines.md Shows the usage of D_ASSERT for assertions that should only be active in debug builds. These assertions should not be triggerable by user input. ```cpp D_ASSERT(a > b + 3); ``` -------------------------------- ### Commit Message Conventions Source: https://github.com/lance-format/lance-duckdb/blob/main/AGENTS.md Example of Conventional Commits format for commit messages, including type, optional scope, and description. Breaking changes are indicated with '!'. ```markdown type[(scope)]: short description ``` -------------------------------- ### Run Full Benchmark Source: https://github.com/lance-format/lance-duckdb/blob/main/benches/laion_1m/README.md Execute the entire benchmark process, including data preparation and all query types. ```bash python3 benches/laion_1m/scripts/run_search_bench.py all ``` -------------------------------- ### Create Lance Dataset via ATTACH and CREATE TABLE Source: https://github.com/lance-format/lance-duckdb/blob/main/README.md Attach a directory as a Lance namespace and then create new datasets using `CREATE TABLE` (schema-only) or `CREATE TABLE AS SELECT` (CTAS). ```sql ATTACH 'path/to/dir' AS lance_ns (TYPE LANCE); -- Schema-only (creates an empty dataset) CREATE TABLE lance_ns.main.my_empty (id BIGINT, s VARCHAR); -- CTAS (writes query results) CREATE TABLE lance_ns.main.my_dataset AS SELECT 1::BIGINT AS id, 'a'::VARCHAR AS s UNION ALL SELECT 2::BIGINT AS id, 'b'::VARCHAR AS s; SELECT count(*) FROM lance_ns.main.my_dataset; ``` -------------------------------- ### Format Code with uv and make Source: https://github.com/lance-format/lance-duckdb/blob/main/AGENTS.md Command to format the codebase using uv and make. This is a PR requirement; ensure all formatting changes are committed. ```bash uv run make format ``` -------------------------------- ### Run Cold Benchmark Source: https://github.com/lance-format/lance-duckdb/blob/main/benches/laion_1m/README.md Execute the benchmark in a cold state, where each workload runs in a fresh DuckDB process. Useful for measuring startup and first-query costs. ```bash python3 benches/laion_1m/scripts/run_search_bench.py cold ``` -------------------------------- ### Attach Lance dataset as a namespace and create a table Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/index.md Attach a local Lance dataset as a namespace and then create a new table within that namespace using SQL. The dataset will be written to `/.lance`. ```sql ATTACH './lance_duck' AS lance_ns (TYPE LANCE); CREATE TABLE lance_ns.main.duck_animals AS SELECT * FROM ( VALUES ('duck', 'quack', [0.9, 0.7, 0.1]::FLOAT[]), ('horse', 'neigh', [0.3, 0.1, 0.5]::FLOAT[]), ('dragon', 'roar', [0.5, 0.2, 0.7]::FLOAT[]) ) AS t(animal, noise, vector); ``` -------------------------------- ### Attach and Drop Table Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Demonstrates attaching a Lance dataset as a namespace and then dropping a table within that namespace. Use `IF EXISTS` to prevent errors if the table does not exist. ```sql ATTACH 'path/to/dir' AS ns (TYPE LANCE); DROP TABLE ns.main.my_table; DROP TABLE IF EXISTS ns.main.my_table; DETACH ns; ``` -------------------------------- ### Run Benchmark Skipping Preparation Source: https://github.com/lance-format/lance-duckdb/blob/main/benches/laion_1m/README.md Execute the benchmark, skipping the preparation steps if all necessary artifacts already exist. Useful for rerunning benchmarks without re-downloading or rebuilding data. ```bash python3 benches/laion_1m/scripts/run_search_bench.py all --skip-prepare ``` -------------------------------- ### Build Lance Extension from Source Source: https://github.com/lance-format/lance-duckdb/blob/main/README.md Steps for building the Lance extension from source for development purposes. This involves updating submodules, building the release, and loading the unsigned extension. ```bash git submodule update --init --recursive ``` ```bash GEN=ninja make release ``` ```bash duckdb -unsigned -c "LOAD 'build/release/extension/lance/lance.duckdb_extension'; SELECT 1;" ``` -------------------------------- ### Download Source Parquet Data Source: https://github.com/lance-format/lance-duckdb/blob/main/benches/laion_1m/README.md Manually download the source Parquet shards for the benchmark. This is the initial networked step. ```bash bash benches/laion_1m/scripts/download_source_parquet.sh ``` -------------------------------- ### Build Lance Dataset Source: https://github.com/lance-format/lance-duckdb/blob/main/benches/laion_1m/README.md Create a Lance dataset from the LZ4 Parquet baseline. Requires a stable DuckDB Lance extension with hybrid search parameters. ```sql duckdb -c ".read benches/laion_1m/sql/30_build_lance_v22.sql" ``` -------------------------------- ### Attach and Query Directory Namespace Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Use `ATTACH` to treat a directory as a Lance namespace. Datasets within the directory are accessible as tables. Use `DETACH` to remove the namespace. ```sql ATTACH 'path/to/dir' AS ns (TYPE LANCE); -- A dataset stored at path/to/dir/my_table.lance becomes ns.main.my_table SELECT count(*) FROM ns.main.my_table; SHOW TABLES FROM ns.main; DETACH ns; ``` -------------------------------- ### Create Empty Dataset with COPY Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Create an empty Lance dataset (schema only) by using `COPY ... TO ...` with a query that returns zero rows and setting `write_empty_file true`. ```sql COPY ( SELECT 1::BIGINT AS id, 'x'::VARCHAR AS s LIMIT 0 ) TO 'path/to/empty.lance' (FORMAT lance, mode 'overwrite', write_empty_file true); ``` -------------------------------- ### Run Warm Benchmark Source: https://github.com/lance-format/lance-duckdb/blob/main/benches/laion_1m/README.md Execute the benchmark in a warm state, where backends run in a single DuckDB session after a warmup pass. Measures performance after initial load. ```bash python3 benches/laion_1m/scripts/run_search_bench.py warm ``` -------------------------------- ### List Tables in Attached Namespace Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/rest.md After attaching to a Lance REST Namespace, use SHOW TABLES to view all available tables within that namespace. ```sql SHOW TABLES; ``` -------------------------------- ### Create Empty Table in Namespace Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Use `CREATE OR REPLACE TABLE` within an attached namespace to create an empty dataset with a defined schema. ```sql ATTACH 'path/to/dir' AS ns (TYPE LANCE); -- Schema-only (creates an empty dataset) CREATE OR REPLACE TABLE ns.main.my_empty (id BIGINT, s VARCHAR); -- CTAS (writes query results) CREATE OR REPLACE TABLE ns.main.my_dataset AS SELECT 1::BIGINT AS id, 'a'::VARCHAR AS s UNION ALL SELECT 2::BIGINT AS id, 'b'::VARCHAR AS s; SELECT count(*) FROM ns.main.my_dataset; DETACH ns; ``` -------------------------------- ### Write Lance Dataset using COPY TO Source: https://github.com/lance-format/lance-duckdb/blob/main/README.md Materialize query results as a Lance dataset using the `COPY ... TO ...` command. Supports 'overwrite', 'append', and creating empty datasets with schema only. ```sql -- Create/overwrite a Lance dataset from a query COPY ( SELECT 1::BIGINT AS id, 'a'::VARCHAR AS s UNION ALL SELECT 2::BIGINT AS id, 'b'::VARCHAR AS s ) TO 'path/to/out.lance' (FORMAT lance, mode 'overwrite'); -- Read it back via the replacement scan SELECT count(*) FROM 'path/to/out.lance'; -- Append more rows to an existing dataset COPY ( SELECT 3::BIGINT AS id, 'c'::VARCHAR AS s ) TO 'path/to/out.lance' (FORMAT lance, mode 'append'); -- Optionally create an empty dataset (schema only) COPY ( SELECT 1::BIGINT AS id, 'x'::VARCHAR AS s LIMIT 0 ) TO 'path/to/empty.lance' (FORMAT lance, mode 'overwrite', write_empty_file true); ``` -------------------------------- ### Run Benchmark with Custom Repeats Source: https://github.com/lance-format/lance-duckdb/blob/main/benches/laion_1m/README.md Execute the benchmark with a specified number of repeats for each workload. Adjusts the number of times each query is run and averaged. ```bash python3 benches/laion_1m/scripts/run_search_bench.py all --repeats 10 ``` -------------------------------- ### Materialize LZ4 Parquet Baseline Source: https://github.com/lance-format/lance-duckdb/blob/main/benches/laion_1m/README.md Create a local LZ4-compressed Parquet baseline from the downloaded shards using DuckDB. ```sql duckdb -c ".read benches/laion_1m/sql/10_materialize_lz4_parquet.sql" ``` -------------------------------- ### Testing Commands for Lance DuckDB Extension Source: https://github.com/lance-format/lance-duckdb/blob/main/AGENTS.md Commands to run all tests, including debug and release builds, and to launch DuckDB with the extension for manual testing. ```bash GEN=ninja make test ``` ```bash GEN=ninja make test_debug ``` ```bash GEN=ninja make test_release ``` ```bash ./build/release/duckdb -c "SELECT * FROM 'test/data/test_data.lance' LIMIT 1;" ``` -------------------------------- ### Load Lance Extension in DuckDB Source: https://github.com/lance-format/lance-duckdb/blob/main/AGENTS.md Use this command to load the Lance extension from a standalone DuckDB binary. Ensure you use the '-unsigned' flag for local builds. ```bash duckdb -unsigned -c "LOAD 'build/release/extension/lance/lance.duckdb_extension'; SELECT * FROM 'test/data/test_data.lance' LIMIT 1;" ``` -------------------------------- ### Connect DuckDB to Lance REST Namespace Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/rest.md Load the lance extension and attach to the REST Namespace using your server details and API key. Then, switch to the attached namespace. ```sql -- Load the Lance extension LOAD 'lance.duckdb_extension'; -- Attach to the REST Namespace ATTACH 'ns1' AS lance_ns ( TYPE LANCE, ENDPOINT 'http://localhost:10024', HEADER 'x-lancedb-database=lance_ns;x-api-key=sk_localtest' ); -- Switch to the attached database USE lance_ns; ``` -------------------------------- ### Configure Alibaba Cloud OSS Secret Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/cloud.md Use this SQL command to create a secret for accessing Alibaba Cloud Object Storage Service (OSS). Provide the necessary `OSS_ENDPOINT`, `OSS_ACCESS_KEY_ID`, and `OSS_SECRET_ACCESS_KEY` for authentication. ```sql CREATE SECRET ( TYPE LANCE, PROVIDER config, SCOPE 'oss://my-bucket/', OSS_ENDPOINT 'https://oss-cn-hangzhou.aliyuncs.com', OSS_ACCESS_KEY_ID '...', OSS_SECRET_ACCESS_KEY '...' ); ``` -------------------------------- ### Build DuckDB Indexed Database Source: https://github.com/lance-format/lance-duckdb/blob/main/benches/laion_1m/README.md Construct a DuckDB indexed database from the LZ4 Parquet baseline, including FTS and VSS indexes. ```sql duckdb benches/laion_1m/data/laion_1m_indexed.duckdb -c ".read benches/laion_1m/sql/20_build_duckdb_indexed.sql" ``` -------------------------------- ### Add Table and Column Comments Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Demonstrates how to add descriptive comments to a Lance table and its columns for better documentation. ```sql ATTACH 'path/to/dir' AS ns (TYPE LANCE); COMMENT ON TABLE ns.main.my_table IS 'table comment'; COMMENT ON COLUMN ns.main.my_table.age_plus_one IS 'col comment'; DETACH ns; ``` -------------------------------- ### Write Lance Dataset to S3 using COPY TO Source: https://github.com/lance-format/lance-duckdb/blob/main/README.md Write a Lance dataset to an S3 path using the `COPY ... TO ...` command. Requires a pre-configured TYPE LANCE secret for the target scope. ```sql CREATE SECRET ( TYPE LANCE, PROVIDER credential_chain, SCOPE 's3://bucket/' ); COPY (SELECT 1 AS id) TO 's3://bucket/path/to/out.lance' (FORMAT lance, mode 'overwrite'); ``` -------------------------------- ### Create LANCE Secret with Custom Storage Options Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/cloud.md Use this when you need to pass custom storage options not directly supported by the secret type. The `STORAGE_OPTIONS` map allows for arbitrary key-value pairs to be forwarded to Lance. ```sql CREATE SECRET ( TYPE LANCE, PROVIDER config, SCOPE 's3://my-bucket/', STORAGE_OPTIONS map(['my_custom_key'], ['my_custom_value']) ); ``` -------------------------------- ### Create Full-Text Index Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Creates a full-text index on a specified text column of a Lance dataset, enabling efficient text search operations. ```sql CREATE INDEX text_idx ON 'path/to/dataset.lance' (text) USING INVERTED; ``` -------------------------------- ### Show Indexes on Dataset Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Retrieves and displays information about all indexes defined on a specific Lance dataset. ```sql SHOW INDEXES ON 'path/to/dataset.lance'; ``` -------------------------------- ### Optimize Lance Dataset Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Optimizes a Lance dataset by compacting fragments. Use this to improve read performance and reduce storage overhead. Parameters control fragment size, deletion materialization, and threading. ```sql OPTIMIZE 'path/to/dataset.lance' WITH ( target_rows_per_fragment = 1048576, max_rows_per_group = 1024, max_bytes_per_file = 0, materialize_deletions = true, materialize_deletions_threshold = 0.1, num_threads = 0, batch_size = 0, defer_index_remap = false ); ``` -------------------------------- ### Create a Table in Lance Namespace Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/rest.md Define the schema for a new table, including column names and data types, to create it within the connected Lance REST Namespace. ```sql CREATE TABLE users ( id INTEGER, name VARCHAR, email VARCHAR ); ``` -------------------------------- ### Set PROTOC environment variable for Rust builds Source: https://github.com/lance-format/lance-duckdb/blob/main/CMakeLists.txt Configures the PROTOC environment variable for Rust builds if it's not already set. This is crucial for prost-build when building DuckDB core extensions. ```cmake if(NOT "$ENV{PROTOC}" STREQUAL "") list(APPEND RUST_CARGO_ENV "PROTOC=$ENV{PROTOC}") elseif(DEFINED VCPKG_TARGET_TRIPLET) if(DEFINED VCPKG_INSTALLED_DIR) set(RUST_PROTOC_ROOT "${VCPKG_INSTALLED_DIR}") elseif(DEFINED _VCPKG_INSTALLED_DIR) set(RUST_PROTOC_ROOT "${_VCPKG_INSTALLED_DIR}") else() set(RUST_PROTOC_ROOT "${CMAKE_BINARY_DIR}/vcpkg_installed") endif() if(WIN32) set(RUST_PROTOC_NAME "protoc.exe") else() set(RUST_PROTOC_NAME "protoc") endif() set(RUST_PROTOC_PATH "${RUST_PROTOC_ROOT}/${VCPKG_TARGET_TRIPLET}/tools/protobuf/${RUST_PROTOC_NAME}") if(EXISTS "${RUST_PROTOC_PATH}") list(APPEND RUST_CARGO_ENV "PROTOC=${RUST_PROTOC_PATH}") endif() endif() ``` -------------------------------- ### Rust-only Checks for Lance DuckDB Extension Source: https://github.com/lance-format/lance-duckdb/blob/main/AGENTS.md Commands to perform Rust-specific checks like compilation and linting without a full DuckDB/CMake build. Ensure Cargo.toml is in the root. ```bash cargo check --manifest-path Cargo.toml ``` ```bash cargo clippy --manifest-path Cargo.toml --all-targets ``` -------------------------------- ### Build Rust artifacts for multi-configuration generators Source: https://github.com/lance-format/lance-duckdb/blob/main/CMakeLists.txt Defines a custom command to build both debug and release Rust artifacts using Cargo. This is used for multi-configuration generators like Visual Studio. ```cmake if(CMAKE_CONFIGURATION_TYPES) add_custom_command( OUTPUT "${RUST_DEBUG_LIB}" "${RUST_RELEASE_LIB}" COMMAND ${CMAKE_COMMAND} -E env ${RUST_CARGO_ENV} cargo build --manifest-path=${CMAKE_CURRENT_LIST_DIR}/Cargo.toml --target=${RUST_PLATFORM_TARGET} COMMAND ${CMAKE_COMMAND} -E env ${RUST_CARGO_ENV} cargo build --manifest-path=${CMAKE_CURRENT_LIST_DIR}/Cargo.toml --release --target=${RUST_PLATFORM_TARGET} WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} DEPENDS ${RUST_FFI_DEPENDS} VERBATIM) add_custom_target(lance_duckdb_ffi_build DEPENDS "${RUST_DEBUG_LIB}" "${RUST_RELEASE_LIB}") else() if(NOT DEFINED CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "") set(CMAKE_BUILD_TYPE Release) endif() if(CMAKE_BUILD_TYPE STREQUAL "Debug") add_custom_command( OUTPUT "${RUST_DEBUG_LIB}" COMMAND ${CMAKE_COMMAND} -E env ${RUST_CARGO_ENV} cargo build --manifest-path=${CMAKE_CURRENT_LIST_DIR}/Cargo.toml --target=${RUST_PLATFORM_TARGET} WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} DEPENDS ${RUST_FFI_DEPENDS} VERBATIM) add_custom_target(lance_duckdb_ffi_build DEPENDS "${RUST_DEBUG_LIB}") else() add_custom_command( OUTPUT "${RUST_RELEASE_LIB}" COMMAND ${CMAKE_COMMAND} -E env ${RUST_CARGO_ENV} cargo build --manifest-path=${CMAKE_CURRENT_LIST_DIR}/Cargo.toml --release --target=${RUST_PLATFORM_TARGET} WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} DEPENDS ${RUST_FFI_DEPENDS} VERBATIM) add_custom_target(lance_duckdb_ffi_build DEPENDS "${RUST_RELEASE_LIB}") endif() endif() ``` -------------------------------- ### Write Dataset with COPY (Overwrite) Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Use the `COPY ... TO ...` statement to write query results to a new Lance dataset. The `mode 'overwrite'` option replaces any existing dataset at the target path. ```sql COPY ( SELECT 1::BIGINT AS id, 'a'::VARCHAR AS s UNION ALL SELECT 2::BIGINT AS id, 'b'::VARCHAR AS s ) TO 'path/to/out.lance' (FORMAT lance, mode 'overwrite'); ``` -------------------------------- ### Write Data to Lance Dataset Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/index.md Use DuckDB's COPY command to materialize query results into a Lance dataset file. The mode 'overwrite' will replace existing files. ```sql COPY ( SELECT * FROM ( VALUES ('duck', 'quack', [0.9, 0.7, 0.1]::FLOAT[]), ('horse', 'neigh', [0.3, 0.1, 0.5]::FLOAT[]), ('dragon', 'roar', [0.5, 0.2, 0.7]::FLOAT[]) ) AS t(animal, noise, vector) ) TO './lance_duck.lance' (FORMAT lance, mode 'overwrite'); ``` -------------------------------- ### Configure Hugging Face Hub Secret Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/cloud.md This snippet shows how to create a secret for accessing Hugging Face Hub datasets via OpenDAL. Include your `HF_TOKEN` and optionally specify `HF_REVISION` for a particular version. ```sql CREATE SECRET ( TYPE LANCE, PROVIDER config, SCOPE 'hf://datasets/acme/my-repo/', HF_TOKEN '...', HF_REVISION 'main' ); ``` -------------------------------- ### Append to Dataset with COPY Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Use `COPY ... TO ...` with `mode 'append'` to add rows to an existing Lance dataset without overwriting it. ```sql COPY (SELECT 3::BIGINT AS id, 'c'::VARCHAR AS s) TO 'path/to/out.lance' (FORMAT lance, mode 'append'); ``` -------------------------------- ### Configure Auto Cleanup for Lance Dataset Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Configures automatic cleanup of old versions for a Lance dataset. This command sets the interval, age threshold, and number of versions to retain. Use UNSET to disable. ```sql ALTER TABLE 'path/to/dataset.lance' SET AUTO_CLEANUP WITH (interval = 1, older_than = '1h', retain_versions = 3); ``` ```sql ALTER TABLE 'path/to/dataset.lance' UNSET AUTO_CLEANUP; ``` -------------------------------- ### ATTACH Syntax for Lance REST Namespace Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/rest.md Use this syntax to connect DuckDB to a Lance REST Namespace. Specify the namespace ID, an alias, the server endpoint, and optional authentication headers. ```sql ATTACH '' AS ( TYPE LANCE, ENDPOINT '', HEADER '=;=' ); ``` -------------------------------- ### Query a table within a Lance namespace Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/index.md Query a table that has been created within a Lance namespace. This demonstrates how to access and count rows from a table managed by a namespace. ```sql SELECT count(*) FROM lance_ns.main.duck_animals; ``` -------------------------------- ### Link Rust artifacts to extension targets Source: https://github.com/lance-format/lance-duckdb/blob/main/CMakeLists.txt Links the compiled Rust debug and release libraries to the main extension targets. It also adds a dependency on the Rust FFI build target. ```cmake target_link_libraries( ${EXTENSION_NAME} debug "${RUST_DEBUG_LIB}" optimized "${RUST_RELEASE_LIB}" ${PLATFORM_LIBS}) add_dependencies(${EXTENSION_NAME} lance_duckdb_ffi_build) target_link_libraries( ${LOADABLE_EXTENSION_NAME} debug "${RUST_DEBUG_LIB}" optimized "${RUST_RELEASE_LIB}" ${PLATFORM_LIBS}) add_dependencies(${LOADABLE_EXTENSION_NAME} lance_duckdb_ffi_build) ``` -------------------------------- ### Configure Azure Blob Storage Secret Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/cloud.md This snippet demonstrates creating a secret for Azure Blob Storage using an account key. Set `USE_OPENDAL` to `true` to utilize the OpenDAL implementation for Azure Blob Storage. ```sql CREATE SECRET ( TYPE LANCE, PROVIDER config, SCOPE 'az://my-container/', ACCOUNT_NAME 'my-account', ACCOUNT_KEY '...', USE_OPENDAL true ); ``` -------------------------------- ### Create Vector ANN Index Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Creates a Vector Approximate Nearest Neighbor (ANN) index on a specified column of a Lance dataset. Requires a fixed-size vector column. ```sql CREATE INDEX vec_idx ON 'path/to/dataset.lance' (vec) USING IVF_FLAT WITH (num_partitions=1, metric_type='l2'); ``` -------------------------------- ### Use Fully Qualified Names for Tables Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/rest.md Access tables in the Lance REST Namespace using their fully qualified names (e.g., `namespace.schema.table`) without needing to switch the current database context. ```sql -- Create table with fully qualified name CREATE TABLE lance_ns.main.my_table (col1 INTEGER, col2 VARCHAR); -- Query with fully qualified name SELECT * FROM lance_ns.main.my_table; ``` -------------------------------- ### Scan Lance Dataset Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Queries a Lance dataset by selecting all columns directly from its URI. A LIMIT clause is used to restrict the number of returned rows. ```sql SELECT * FROM 'path/to/dataset.lance' LIMIT 10; ``` -------------------------------- ### Create Scalar Index Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Creates a scalar index (e.g., B-Tree) on a specified column of a Lance dataset, suitable for equality and range queries. ```sql CREATE INDEX label_idx ON 'path/to/dataset.lance' (label) USING BTREE; ``` -------------------------------- ### Create LANCE Secret with Config Provider Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/cloud.md Use this to create a secret for the LANCE type with explicit key/value configuration. Specify the scope, access key ID, secret access key, and region. ```sql CREATE SECRET ( TYPE LANCE, PROVIDER config, SCOPE 's3://my-bucket/', ACCESS_KEY_ID '...', SECRET_ACCESS_KEY '...', REGION 'us-east-1' ); ``` -------------------------------- ### Query Lance Dataset in DuckDB Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/index.md Query data directly from a Lance dataset file using SQL in DuckDB. Supports local paths and S3 URIs after creating a secret. ```sql SELECT * FROM './lance_duck.lance' LIMIT 5; ``` ```sql CREATE SECRET ( TYPE LANCE, PROVIDER credential_chain, SCOPE 's3://bucket/' ); SELECT * FROM 's3://bucket/path/to/lance_duck.lance' LIMIT 5; ``` -------------------------------- ### Attach and Query REST Namespace Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Attach a remote Lance namespace using its ID and endpoint. This allows querying datasets hosted on a remote service. ```sql ATTACH 'namespace_id' AS ns (TYPE LANCE, ENDPOINT 'http://127.0.0.1:2333'); SHOW TABLES FROM ns.main; SELECT count(*) FROM ns.main.some_table; DETACH ns; ``` -------------------------------- ### Verify DuckDB Indexed Data Source: https://github.com/lance-format/lance-duckdb/blob/main/benches/laion_1m/README.md Run verification queries on the DuckDB indexed dataset to ensure data integrity and index correctness. ```sql duckdb benches/laion_1m/data/laion_1m_indexed.duckdb -c ".read benches/laion_1m/sql/50_verify_duckdb_indexed.sql" ``` -------------------------------- ### Verify Lance Data Source: https://github.com/lance-format/lance-duckdb/blob/main/benches/laion_1m/README.md Run verification queries on the Lance dataset to ensure data integrity and correct indexing. ```sql duckdb -c ".read benches/laion_1m/sql/51_verify_lance.sql" ``` -------------------------------- ### Show Maintenance Status on Lance Dataset Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Displays the current maintenance configuration for a Lance dataset, including whether auto cleanup is enabled and its specific parameters like interval, older_than, and retain_versions. ```sql SHOW MAINTENANCE ON 'path/to/dataset.lance'; ``` -------------------------------- ### Drop Column Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Shows how to remove a column from a Lance table. ```sql ALTER TABLE ns.main.my_table DROP COLUMN score2; ``` -------------------------------- ### Create LANCE Secret with Credential Chain Provider Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/cloud.md This method creates a scoped secret for the LANCE type but relies on the upstream SDK's credential chain (environment variables, shared config/credentials, instance metadata) for authentication. It's useful for avoiding hardcoded credentials. ```sql CREATE SECRET ( TYPE LANCE, PROVIDER credential_chain, SCOPE 's3://my-bucket/', REGION 'us-east-1' ); ``` -------------------------------- ### Optimize Index Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Optimizes a specified index on a Lance dataset. Supported modes include 'append', 'merge', and 'retrain'. ```sql ALTER INDEX vec_idx ON 'path/to/dataset.lance' OPTIMIZE WITH (mode = 'append'); ``` -------------------------------- ### Insert Data into Lance Table Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/rest.md Populate a table in the Lance REST Namespace with data using the INSERT INTO statement. Multiple rows can be inserted at once. ```sql INSERT INTO users VALUES (1, 'Alice', 'alice@example.com'), (2, 'Bob', 'bob@example.com'), (3, 'Charlie', 'charlie@example.com'); ``` -------------------------------- ### Configure Google Cloud Storage Secret Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/cloud.md Use this snippet to create a secret for accessing Google Cloud Storage using a bearer token. Ensure the `GOOGLE_STORAGE_TOKEN` is valid and `USE_OPENDAL` is set to `false` for direct GCS client usage. ```sql CREATE SECRET ( TYPE LANCE, PROVIDER config, SCOPE 'gs://my-bucket/', GOOGLE_STORAGE_TOKEN '...', USE_OPENDAL false ); ``` -------------------------------- ### Vector Search on Lance Dataset Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/index.md Perform vector similarity search on a Lance dataset using the lance_vector_search function. Results are sorted by distance, with smaller distances indicating closer neighbors. ```sql SELECT animal, noise, vector, _distance FROM lance_vector_search( './lance_duck.lance', 'vector', [0.8, 0.7, 0.2]::FLOAT[], k = 1, prefilter = true ) ORDER BY _distance ASC; ``` -------------------------------- ### Query Data from Lance Table Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/rest.md Retrieve data from a table in the Lance REST Namespace using standard SQL SELECT statements. Supports filtering and aggregation. ```sql -- Select all rows SELECT * FROM users; ``` ```sql -- Select with filter SELECT * FROM users WHERE id > 1; ``` ```sql -- Aggregation SELECT COUNT(*) as total_users FROM users; ``` -------------------------------- ### Full-Text Search on Lance Dataset Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/index.md Execute keyword-based BM25 search on a Lance dataset using the lance_fts function. Results are sorted by score in descending order for relevance. ```sql SELECT animal, noise, vector, _score FROM lance_fts( './lance_duck.lance', 'animal', 'the brave knight faced the dragon', k = 1, prefilter = true ) ORDER BY _score DESC; ``` -------------------------------- ### Query Lance Dataset (Local and S3) Source: https://github.com/lance-format/lance-duckdb/blob/main/README.md Query data from a Lance dataset stored locally or on S3. For S3 access, a TYPE LANCE secret must be configured. ```sql -- local file SELECT * FROM 'path/to/dataset.lance' LIMIT 10; ``` ```sql -- s3 SELECT * FROM 's3://bucket/path/to/dataset.lance' LIMIT 10; ``` -------------------------------- ### Rename Column Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Illustrates renaming an existing column in a Lance table. ```sql ALTER TABLE ns.main.my_table RENAME COLUMN score TO score2; ``` -------------------------------- ### Vacuum Lance Dataset Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Removes old, unreferenced versions of a Lance dataset. Configure the retention period and whether to delete unverified versions. This helps manage disk space by removing stale data. ```sql VACUUM LANCE 'path/to/dataset.lance' WITH ( older_than_seconds = 1209600, delete_unverified = false, error_if_tagged_old_versions = true, retain_n_versions = 3 ); ``` -------------------------------- ### Add Column with Default Value Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Shows how to alter a Lance table to add a new column, specifying its data type and a default value derived from an existing column. ```sql ATTACH 'path/to/dir' AS ns (TYPE LANCE); ALTER TABLE ns.main.my_table ADD COLUMN age_plus_one BIGINT DEFAULT (age + 1); DETACH ns; ``` -------------------------------- ### Vector Search with lance_vector_search Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Performs a vector search on a specified column within a Lance dataset. It returns the nearest neighbors based on the query vector and includes a `_distance` column. Use `use_index=true` to leverage ANN indexes. ```sql -- Search a vector column, returning distances in `_distance` (smaller is closer) SELECT id, label, _distance FROM lance_vector_search( 'path/to/dataset.lance', 'vec', [0.1, 0.2, 0.3, 0.4]::FLOAT[4], k = 5, use_index = true, nprobs = 4, refine_factor = 2, prefilter = true ) ORDER BY _distance ASC; ``` -------------------------------- ### Vector Search in Lance Dataset Source: https://github.com/lance-format/lance-duckdb/blob/main/README.md Perform vector search on a Lance dataset. This function returns distances, and results can be filtered and ordered by distance. ```sql -- Search a vector column, returning distances in `_distance` (smaller is closer) SELECT id, label, _distance FROM lance_vector_search('path/to/dataset.lance', 'vec', [0.1, 0.2, 0.3, 0.4]::FLOAT[4], k = 5, prefilter = true) ORDER BY _distance ASC; ``` -------------------------------- ### Hybrid Search on Lance Dataset Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/index.md Combine vector and full-text search scores using lance_hybrid_search. Results include hybrid score, distance, and FTS score, sorted by hybrid score in descending order. ```sql SELECT animal, noise, vector, _hybrid_score, _distance, _score FROM lance_hybrid_search( './lance_duck.lance', 'vector', [0.8, 0.7, 0.2]::FLOAT[], 'animal', 'the duck surprised the dragon', k = 2, prefilter = false, alpha = 0.5, oversample_factor = 4 ) ORDER BY _hybrid_score DESC; ``` -------------------------------- ### MERGE INTO Lance Table (Update/Insert) Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Use MERGE INTO to conditionally update existing rows or insert new rows into a Lance table based on matching criteria with a source. ```sql ATTACH 'path/to/dir' AS ns (TYPE LANCE); MERGE INTO ns.main.my_table AS t USING ( SELECT 2::BIGINT AS id, 'bb'::VARCHAR AS s UNION ALL SELECT 3::BIGINT AS id, 'c'::VARCHAR AS s ) AS src ON t.id = src.id WHEN MATCHED THEN UPDATE SET s = src.s WHEN NOT MATCHED THEN INSERT (id, s) VALUES (src.id, src.s); MERGE INTO ns.main.my_table AS t USING (SELECT 3::BIGINT AS id) AS src ON t.id = src.id WHEN MATCHED THEN DELETE RETURNING merge_action, id, s; DETACH ns; ``` -------------------------------- ### lance_hybrid_search Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Performs a hybrid search by combining vector and text scores. It returns results ordered by `_hybrid_score`, which is a weighted combination of vector and text similarity, where a larger score indicates better relevance. ```APIDOC ## lance_hybrid_search ### Description Combines vector and text scores to return `_hybrid_score` (larger is better), `_distance`, and `_score` from a Lance dataset. ### Signature lance_hybrid_search(uri, vector_column, query_vector, text_column, query, ...) ### Parameters #### Positional Arguments - **uri** (VARCHAR) - Required - Dataset root path or object store URI (e.g. `s3://...`). - **vector_column** (VARCHAR) - Required - Vector column name. - **query_vector** (FLOAT[dim] or DOUBLE[dim], preferred) - Required - Query vector (must be non-empty; values are cast to float32). `FLOAT[]` / `DOUBLE[]` are also accepted. - **text_column** (VARCHAR) - Required - Text column name. - **query** (VARCHAR) - Required - Query string. #### Named Parameters - **k** (BIGINT, default `10`) - Number of results to return. Must be > 0. - **nprobs** (BIGINT, optional) - Number of IVF partitions to probe when using a vector index. Must be > 0. Only affects IVF-based vector indices. - **refine_factor** (BIGINT, optional) - Refine factor for the vector branch. Must be > 0. - **prefilter** (BOOLEAN, default `false`) - If `true`, filters are applied before top-k selection. - **use_index** (BOOLEAN, default `true`) - If `true`, allow ANN index usage for the vector branch when available. If `false`, the vector branch runs exact KNN. - **alpha** (FLOAT, default `0.5`) - Vector/text mixing weight. Larger values weigh vector similarity more heavily. - **oversample_factor** (INTEGER, default `4`) - Oversample factor for candidate generation. If provided, must be > 0. ### Output - Dataset columns plus `_hybrid_score` (larger is better), `_distance`, and `_score`. ### Filter Semantics - If `prefilter=false`, filter pushdown is best-effort. If pushdown fails, the query is retried without pushed filters and DuckDB applies filters for correctness. - If `prefilter=true`, prefilterable filters must be pushed down, otherwise the query fails with an error. ### Example ```sql -- Combine vector and text scores, returning `_hybrid_score` (larger is better) SELECT id, _hybrid_score, _distance, _score FROM lance_hybrid_search( 'path/to/dataset.lance', 'vec', [0.1, 0.2, 0.3, 0.4]::FLOAT[4], 'text', 'puppy', k = 10, prefilter = false, alpha = 0.5, oversample_factor = 4 ) ORDER BY _hybrid_score DESC; ``` ``` -------------------------------- ### Optimize Lance Index Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Optimizes a specific index within a Lance dataset. Supports 'append', 'merge', and 'retrain' modes for index maintenance. The 'merge' mode allows specifying the number of indices to merge. ```sql ALTER INDEX vec_idx ON 'path/to/dataset.lance' OPTIMIZE WITH ( mode = 'merge', num_indices_to_merge = 4 ); ``` -------------------------------- ### Configure S3 Secret for Lance Source: https://github.com/lance-format/lance-duckdb/blob/main/README.md Configure a TYPE LANCE secret to enable access to S3 object store URIs for Lance datasets. This involves specifying the provider and scope. ```sql CREATE SECRET ( TYPE LANCE, PROVIDER credential_chain, SCOPE 's3://bucket/' ); SELECT * FROM 's3://bucket/path/to/dataset.lance' LIMIT 10; ``` -------------------------------- ### INSERT Data into Lance Table Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Use INSERT to add new rows to a Lance table. Supports inserting literal values or results from a SELECT query. ```sql ATTACH 'path/to/dir' AS ns (TYPE LANCE); INSERT INTO ns.main.my_table VALUES (3::BIGINT, 'c'::VARCHAR); INSERT INTO ns.main.my_table SELECT 4::BIGINT AS id, 'd'::VARCHAR AS s; DETACH ns; ``` -------------------------------- ### TRUNCATE Lance Table Source: https://github.com/lance-format/lance-duckdb/blob/main/docs/sql.md Use TRUNCATE TABLE to efficiently remove all rows from a Lance table. ```sql ATTACH 'path/to/dir' AS ns (TYPE LANCE); TRUNCATE TABLE ns.main.my_table; DETACH ns; ``` -------------------------------- ### Hybrid Search (Vector + FTS) in Lance Dataset Source: https://github.com/lance-format/lance-duckdb/blob/main/README.md Perform hybrid search combining vector and full-text search. This function returns a combined `_hybrid_score` along with `_distance` and `_score`. ```sql -- Combine vector and text scores, returning `_hybrid_score` in addition to `_distance` / `_score` SELECT id, _hybrid_score, _distance, _score FROM lance_hybrid_search('path/to/dataset.lance', 'vec', [0.1, 0.2, 0.3, 0.4]::FLOAT[4], 'text', 'puppy', k = 10, prefilter = false, alpha = 0.5, oversample_factor = 4) ORDER BY _hybrid_score DESC; ```