## Extension Function Catalog

This section is generated from `functions.yaml`.

### Diagnostics

| Function | Kind | Returns | R helper | Description |
| --- | --- | --- | --- | --- |
| `duckhts_simd_backend` | scalar | VARCHAR | `rduckhts_simd_backend` | Return the current DuckHTS SIMD dispatch label. For explicit scalar or concrete backend requests this is the requested policy; for auto it is the single selected backend when all logical kernels resolve to the same backend, or mixed when per-kernel auto-dispatch resolves to multiple backends. Use duckhts_simd_kernel_info() for per-kernel details. |
| `duckhts_simd_requested_backend` | scalar | VARCHAR | `rduckhts_simd_requested_backend` | Return the current explicit SIMD backend request, usually auto unless `SELECT backend FROM duckhts_simd_set_backend('auto'\|'scalar'\|backend)` was called. The selected per-kernel backend may differ under auto-dispatch across x86, ARM, wasm, and scalar-only builds. |
| `duckhts_simd_backend_compiled` | scalar | BOOLEAN | `rduckhts_simd_backend_compiled` | Return whether a concrete DuckHTS SIMD backend was compiled into this build. This is independent of whether the current CPU/runtime supports executing that backend; for example avx512 can be compiled but not CPU-supported on the running host. |
| `duckhts_simd_backend_cpu_supported` | scalar | BOOLEAN | `rduckhts_simd_backend_cpu_supported` | Return whether the current CPU/runtime supports a concrete DuckHTS SIMD backend, independent of whether DuckHTS compiled an implementation for it. Availability is the intersection of compiled and CPU-supported. |
| `duckhts_simd_backend_available` | scalar | BOOLEAN | `rduckhts_simd_backend_available` | Return whether a concrete SIMD backend is usable in the current process. Availability means the backend is compiled into DuckHTS and supported by the current CPU/runtime. auto is a selection request rather than a concrete backend and is not reported as available here. |
| `duckhts_simd_info` | table | table | `rduckhts_simd_info` | Return one row per known concrete DuckHTS SIMD backend with extension-owned selectable, compiled, CPU-supported, available, selected, requested, and dispatch-mode diagnostics. Availability is the intersection of compiled and CPU/runtime-supported. selectable reports whether the backend has a selectable implementation path; explicit selection still requires available = TRUE. selected is TRUE when the current dispatch table uses that backend for at least one logical kernel. auto is a selection request and is not a concrete backend row. |
| `duckhts_simd_kernel_info` | table | table | `rduckhts_simd_kernel_info` | Return one row per logical DuckHTS SIMD kernel showing the concrete backend selected by the current immutable dispatch table, the selected capability, the requested backend policy, whether scalar was used as a per-kernel fallback, and the dispatch mode. This is the authoritative diagnostic for mixed auto-dispatch when different kernels resolve to different backends. |
| `duckhts_simd_set_backend` | table | table(backend VARCHAR) | `rduckhts_simd_set_backend` | Explicitly select the DuckHTS SIMD dispatch policy for this process using a one-row table-function call and return the current dispatch label in a backend column. Use auto for per-kernel runtime dispatch or scalar for a portable baseline; unavailable platform-specific requests such as avx512 on non-AVX-512 CPUs raise an error instead of silently falling back. |
| `duckhts_duckdb_type_supported` | scalar_macro | BOOLEAN |  | Return whether the currently open DuckDB runtime advertises a logical type with the given name through duckdb_types(). This is a catalog-level runtime probe for feature gating SQL/macros across DuckDB versions. |
| `duckhts_duckdb_supports_variant` | scalar_macro | BOOLEAN |  | Return whether the currently open DuckDB runtime advertises the VARIANT logical type. Use this to gate optional SQL that depends on DuckDB VARIANT support. |
| `duckhts_duckdb_supports_geometry` | scalar_macro | BOOLEAN |  | Return whether the currently open DuckDB runtime advertises the GEOMETRY logical type. Use this to gate optional SQL that depends on DuckDB GEOMETRY support. |

### Readers

| Function | Kind | Returns | R helper | Description |
| --- | --- | --- | --- | --- |
| `read_bcf` | table | table | `rduckhts_bcf` | Read VCF and BCF variant data with typed INFO, FORMAT, typed CSQ/ANN/BCSQ subfields, optional tidy sample output, optional bcftools-style CSQ type overrides, explicit scan_mode control ('auto' or full-file 'sequential'), optional htslib decompression worker threads via decompression_threads (default 0 for single-threaded reads), and decode_error_policy ('null', 'warn', or 'error') for corrupt BCF header-vs-payload decode mismatches. |
| `read_bcf_v2` | table | table |  | Experimental clone of read_bcf(...) for non-destructive benchmarking of current-schema scan optimizations. It preserves the read_bcf wide/tidy output schema by default, streams full-file scans by default instead of auto-iterating indexed contigs, accepts the same scan_mode and decode_error_policy ('null', 'warn', or 'error') contract as read_bcf, sets htslib VCF text max_unpack from DuckDB projection pushdown so unprojected INFO/FORMAT text can be skipped earlier, keeps INFO/FORMAT/GT decode buffers and parsed VEP/CSQ records in local scan state across output chunks, repeats VEP-derived values correctly across tidy sample rows, supports v2-only htslib sample pushdown via comma-separated samples/exclude_samples strings or samples_file/exclude_samples_file lists, can bind only requested INFO/FORMAT/VEP fields through include_info/include_format/include_vep and comma-separated info_fields/format_fields/vep_fields controls, rejects format_fields when no samples are selected, treats tidy_format := true with include_format := false as one row per variant because no SAMPLE_ID/FORMAT columns are bound, and counts VCF text rows without parsing when no columns are projected. |
| `read_bcf_appender` | table | table |  | Experimental side-effecting benchmark helper that reads BCF/VCF with htslib and appends a narrow scalar tidy table through DuckDB's chunk appender API. The target table is created in the default schema with columns CHROM, POS, REF, ALT, SAMPLE_ID, and FORMAT_GT; set include_file_offset := TRUE to also add FILE_OFFSET. For comma-separated region queries, region_threads > 1 claims regions in parallel and adds duckhts_region_idx so callers can restore requested-region order with ORDER BY duckhts_region_idx, POS. The single-stream (region_threads = 1) path runs inside an internal transaction and surfaces malformed-record errors as DuckDB errors; decode_error_policy controls corrupt BCF FORMAT/GT header-vs-payload mismatches with 'null', 'warn', or 'error'. The parallel path shares one DuckDB connection across worker appenders and is best-effort benchmarking only, with no transactional rollback. target_table must be an unqualified SQL identifier. This is intended to compare appender-based materialization against read_bcf(...) query pipelines, not as a full replacement for the typed read_bcf surface. |
| `read_bam` | table | table | `rduckhts_bam` | Read SAM, BAM, and CRAM alignments with optional typed SAMtags and auxiliary tag maps. Use sequence_encoding := 'nt16' to return SEQ as UTINYINT[], quality_representation := 'phred' to return QUAL as UTINYINT[], and cigar_representation := 'binary' to return packed BAM CIGAR operations as UINTEGER[] instead of SAM text. scan_mode := 'sequential' forces a full-file streaming scan instead of index-backed count/parallel paths and is incompatible with region. decompression_threads controls per-file htslib worker threads and defaults to 2; use 0 to disable worker threads. |
| `read_fasta` | table | table | `rduckhts_fasta` | Read FASTA records or indexed FASTA regions as sequence rows. Use sequence_encoding := 'nt16' to return SEQUENCE as UTINYINT[] (htslib nt16 4-bit codes) instead of VARCHAR. For bgzipped FASTA, gzi_path may point to an explicit .gzi sidecar when it is not colocated with the FASTA. scan_mode := 'sequential' forces full-file streaming/counting instead of index-backed count paths and is incompatible with region. |
| `read_bed` | table | table | `rduckhts_bed` | Read BED3-BED12 interval files with canonical typed columns and optional tabix-backed region filtering. scan_mode := 'sequential' forces full-file streaming/counting instead of index-backed count paths and is incompatible with region. |
| `fasta_nuc` | table | table | `rduckhts_fasta_nuc` | Compute bedtools nuc-style nucleotide composition for supplied BED intervals or generated fixed-width bins over a FASTA reference. For bgzipped FASTA, gzi_path may point to an explicit .gzi sidecar when it is not colocated with the FASTA. |
| `read_fastq` | table | table | `rduckhts_fastq` | Read single-end, paired-end, or interleaved FASTQ files with optional legacy quality decoding. By default, FASTQ qualities are interpreted as modern Phred+33 input. Use sequence_encoding := 'nt16' to return SEQUENCE as UTINYINT[] and quality_representation := 'phred' to return QUALITY as UTINYINT[] instead of VARCHAR. input_quality_encoding accepts 'phred33', 'auto', 'phred64', or 'solexa64'. scan_mode := 'sequential' forces raw streaming/counting instead of index-backed count paths. |
| `read_gff` | table | table | `rduckhts_gff` | Read GFF annotations with optional raw scalar and richer list/pair parsed attribute columns, strict GFF3 structural validation, and indexed region filtering. scan_mode := 'sequential' forces full-file streaming/counting instead of index-backed count paths and is incompatible with region. |
| `read_gtf` | table | table | `rduckhts_gtf` | Read GTF annotations with optional raw scalar and richer list/pair parsed attribute columns and indexed region filtering. scan_mode := 'sequential' forces full-file streaming/counting instead of index-backed count paths and is incompatible with region. |
| `read_tabix` | table | table | `rduckhts_tabix` | Read generic tabix-indexed text data with optional header handling and type inference. scan_mode := 'sequential' forces full-file streaming/counting instead of index-backed count paths and is incompatible with region. |
| `fasta_index` | table | table | `rduckhts_fasta_index` | Build a FASTA index (.fai) and return a single row with columns success (BOOLEAN) and index_path (VARCHAR). |
| `hts_union_query` | scalar_macro | VARCHAR | `rduckhts_bam_multi, rduckhts_bcf_multi, rduckhts_fastq_multi, rduckhts_fasta_multi, rduckhts_bed_multi, rduckhts_tabix_multi, rduckhts_gff_multi, rduckhts_gtf_multi` | Generate a UNION ALL BY NAME query string that reads every file matching a glob pattern through the named reader function. The result includes a 'filename' column identifying the source file for each row. Assign to a variable with SET VARIABLE and execute via query(getvariable(...)). Optional params string is appended to each reader call. In R, use the typed rduckhts_*_multi() helpers instead, which accept file vectors with optional per-file parameters and create DuckDB tables directly. |
| `hts_region_union_query` | scalar_macro | VARCHAR |  | Generate a UNION ALL BY NAME query string that reads one HTS file through separate per-region table-function scans. The result adds filename, duckhts_region_shard_id, and duckhts_region_shard columns so benchmark queries can compare region-sharded execution and explicit ordered writes. Pass regions as a DuckDB list of region strings; params is appended to each reader call and should not include region. The generated UNION ALL does not deduplicate records; adjacent or overlapping shards can duplicate BAM alignments or BCF/VCF records that span shard boundaries, so add explicit shard-local filters or downstream deduplication when exact once-only semantics are required. |

### Converters

| Function | Kind | Returns | R helper | Description |
| --- | --- | --- | --- | --- |
| `duckhts_bcf_convert_parquet_sql` | scalar_macro | VARCHAR | `rduckhts_bcf_convert_parquet` | Build a DuckDB COPY statement that converts read_bcf(...) output to Parquet with DuckHTS key-value metadata, preserved or corrected VCF header text, user metadata from metadata := map(...), selected columns, filters, and partition columns. Optional metadata_json_file is caller-managed and requires DuckDB's json extension to be available when the builder is called; use metadata maps for CRAN/offline-safe workflows. Clients execute the returned SQL string; the R wrapper is a thin DBI helper that does this execution. |
| `duckhts_bam_convert_parquet_sql` | scalar_macro | VARCHAR | `rduckhts_bam_convert_parquet` | Build a DuckDB COPY statement that converts read_bam(...) output to Parquet with DuckHTS key-value metadata, preserved or corrected SAM header text, user metadata from metadata := map(...), selected columns, filters, and partition columns. Optional metadata_json_file is caller-managed and requires DuckDB's json extension to be available when the builder is called; use metadata maps for CRAN/offline-safe workflows. Clients execute the returned SQL string; the R wrapper is a thin DBI helper that does this execution. |
| `duckhts_gff_convert_parquet_sql` | scalar_macro | VARCHAR | `rduckhts_gff_convert_parquet` | Build a DuckDB COPY statement that converts read_gff(...) output to Parquet with DuckHTS key-value metadata, preserved or corrected GFF/tabix header text, user metadata from metadata := map(...), selected columns, filters, and partition columns. Optional metadata_json_file is caller-managed and requires DuckDB's json extension to be available when the builder is called; use metadata maps for CRAN/offline-safe workflows. Clients execute the returned SQL string; the R wrapper is a thin DBI helper that does this execution. |
| `duckhts_tabix_convert_parquet_sql` | scalar_macro | VARCHAR | `rduckhts_tabix_convert_parquet` | Build a DuckDB COPY statement that converts read_tabix(...) output to Parquet with DuckHTS key-value metadata, preserved or corrected tabix header text, user metadata from metadata := map(...), selected columns, filters, and partition columns. Optional metadata_json_file is caller-managed and requires DuckDB's json extension to be available when the builder is called; use metadata maps for CRAN/offline-safe workflows. Clients execute the returned SQL string; the R wrapper is a thin DBI helper that does this execution. |

### Coverage

| Function | Kind | Returns | R helper | Description |
| --- | --- | --- | --- | --- |
| `read_pileup` | table | table | `rduckhts_pileup` | Construct a region-scoped BAM pileup with one row per covered position, emitting chrom, 1-based position, depth, observed bases, and Phred+33 qualities after SAM flag and MAPQ filtering. This is a compact htslib pileup view, not samtools mpileup text parity. |
| `bam_bin_counts` | table | table | `rduckhts_bam_bin_counts` | Count BAM or CRAM read starts into fixed-width bins. Returns one row per bin across the selected contig span, including zero-count bins, with total, forward, and reverse counts; `rmdup := 'streaming'` applies the WisecondorX-style larp/larp2 consecutive-position deduplication, `rmdup := 'flag'` drops SAM duplicate-flagged reads, and `stats := 'gc'`, `'mq'`, or `'gc,mq'` adds per-bin pre/post-filter GC and MAPQ sufficient statistics, including reference GC when `reference` is provided. |
| `duckhts_bam_bed_coverage` | table | table | `rduckhts_bam_bed_coverage` | Compute samtools coverage-like regional summaries for BAM or CRAM input over a BED target set, returning one row per BED interval with DuckHTS-specific pre/post-filter read counts, covered bases, percentage covered, mean depth, mean baseQ, mean mapQ, and strand-specific post-filter summaries in read mode. Indexed BAM/CRAM input is required in the current implementation. decompression_threads controls htslib worker threads for BAM/CRAM decoding; use 0 to disable them. |
| `duckhts_mosdepth` | table | table | `rduckhts_mosdepth` | Write native mosdepth-compatible coverage outputs for indexed BAM or CRAM input. Produces mosdepth-style summary, global distribution, per-base BED.gz + CSI, optional window/BED region outputs, optional quantized BED.gz + CSI, and optional threshold counts for `by`; `fast_mode` defaults to FALSE to match upstream mosdepth, default mode performs CIGAR-aware coverage with mate-overlap correction, `fragment_mode` switches coverage to full-fragment insert spans for proper pairs, `use_median` switches `by` outputs from mean to median, `read_groups` filters by comma-separated RG IDs, `min_frag_len` and `max_frag_len` filter on absolute template length, `fasta` is required for CRAM when htslib needs a reference, `precision_digits` controls decimal places in the text outputs, and `processing_threads` enables parallel contig processing (0 = sequential, >0 = number of worker threads). |

### Intervals

| Function | Kind | Returns | R helper | Description |
| --- | --- | --- | --- | --- |
| `duckhts_cgranges_create` | scalar | BOOLEAN |  | Create an empty session-scoped cgranges registry entry that can be populated with intervals and finalized for overlap queries. |
| `duckhts_cgranges_add` | scalar | BOOLEAN |  | Append an interval to a session-scoped cgranges registry entry before finalization. Labels may be BIGINT-like, DOUBLE, VARCHAR, or BOOLEAN. |
| `duckhts_cgranges_index` | scalar | BOOLEAN |  | Finalize a populated cgranges registry entry and build its immutable overlap index for subsequent queries. |
| `duckhts_cgranges_destroy` | scalar | BOOLEAN |  | Destroy a session-scoped cgranges registry entry and release its indexed interval storage when it is not in active use. |
| `duckhts_cgranges_from_query` | scalar | BOOLEAN |  | Execute a SQL query on an extension-owned DuckDB connection, append its interval rows into a session-scoped cgranges registry entry, and leave the populated index ready for explicit finalization with duckhts_cgranges_index(...). |
| `duckhts_cgranges_from_table` | scalar | BOOLEAN |  | Reserved convenience constructor for bulk cgranges population from a table name. The current implementation is intentionally deferred and directs callers to duckhts_cgranges_from_query(...). |
| `duckhts_cgranges_has_overlap` | scalar | BOOLEAN |  | Vectorized scalar predicate for streaming provider rows through a finalized session-scoped cgranges index. Returns TRUE when the query interval overlaps at least one indexed interval, or when mode = 'contain' and it fully contains at least one indexed interval; NULL inputs return NULL. |
| `duckhts_cgranges_count_overlaps` | scalar | BIGINT |  | Vectorized scalar overlap counter for streaming provider rows through a finalized session-scoped cgranges index. Returns the number of indexed intervals that overlap the query interval, or with mode = 'contain' the number fully contained by it; NULL inputs return NULL. |
| `duckhts_cgranges_overlaps_list` | scalar | STRUCT(interval_ordinal BIGINT, label VARCHAR, label_type VARCHAR, interval_chrom VARCHAR, interval_start INTEGER, interval_end INTEGER)[] |  | Vectorized scalar overlap expander for streaming provider rows through a finalized session-scoped cgranges index. Returns a LIST of hit STRUCTs that can be expanded with UNNEST, preserving provider columns while emitting one row per matching indexed interval. Because scalar return types are fixed, labels are returned as text with label_type describing the original cgranges label kind; NULL inputs return NULL. |
| `duckhts_cgranges_overlaps` | table | table |  | Query a finalized session-scoped cgranges registry entry and return one row per overlapping or containing indexed interval, preserving the original label type and interval coordinates. |
| `duckhts_cgranges_overlaps_bulk` | table | table |  | Run a SQL query that yields overlap probes, stream those rows through a finalized session-scoped cgranges registry entry, and return one row per matching indexed interval. The probe query runs on the extension-owned helper connection, so it must reference regular tables/views rather than connection-local temp tables. When query_row_id_col is omitted, query_row_id defaults to the 1-based probe row ordinal. |
| `regionkey` | scalar | UBIGINT |  | Encode a genomic interval as an official RegionKey-compatible 64-bit unsigned integer. Start and end use 0-based half-open interval semantics, matching BED-style coordinates; strand accepts -1, 0, or 1. |
| `regionkey_hex` | scalar | VARCHAR |  | Render a RegionKey as its lowercase 16-character hexadecimal string representation. |
| `parse_regionkey_hex` | scalar | UBIGINT |  | Parse a 16-character hexadecimal RegionKey string back into its UBIGINT code. Invalid or non-hex strings return NULL. |
| `encode_regionkey` | scalar | UBIGINT |  | Encode the raw upstream RegionKey fields directly: chromosome code, 0-based start, 0-based end, and strand code (0 = unknown, 1 = +, 2 = -). |
| `extract_regionkey_chrom` | scalar | UTINYINT |  | Extract the raw upstream RegionKey chromosome code. |
| `extract_regionkey_startpos` | scalar | UINTEGER |  | Extract the raw upstream RegionKey 0-based start position. |
| `extract_regionkey_endpos` | scalar | UINTEGER |  | Extract the raw upstream RegionKey 0-based end position. |
| `extract_regionkey_strand` | scalar | UTINYINT |  | Extract the raw upstream RegionKey strand code (0 = unknown, 1 = +, 2 = -). |
| `decode_regionkey` | scalar | STRUCT |  | Decode a RegionKey into its raw upstream numeric fields: chrom_code, start, end, and strand_code. |
| `reverse_regionkey` | scalar | STRUCT |  | Decode a RegionKey into a STRUCT with chrom, chrom_code, start, end, strand, and strand_code. |
| `extend_regionkey` | scalar | UBIGINT |  | Extend a RegionKey interval by a fixed number of bases on both sides, clamping to the official 28-bit RegionKey position range. |
| `are_overlapping_regions` | scalar | BOOLEAN |  | Return TRUE when two explicit 0-based half-open intervals overlap on the same canonical chromosome. |
| `are_overlapping_region_regionkey` | scalar | BOOLEAN |  | Return TRUE when a 0-based half-open interval overlaps the supplied RegionKey interval. |
| `are_overlapping_regionkeys` | scalar | BOOLEAN |  | Return TRUE when two RegionKeys overlap. |

### Metadata

| Function | Kind | Returns | R helper | Description |
| --- | --- | --- | --- | --- |
| `detect_quality_encoding` | table | table | `rduckhts_detect_quality_encoding` | Inspect a FASTQ file's observed quality ASCII range and report compatible legacy encodings with a heuristic guessed encoding. |
| `duckhts_samtools_idxstats` | table | table | `rduckhts_samtools_idxstats` | Write samtools idxstats-compatible TAB-delimited output for BAM, CRAM, or SAM input. Indexed BAM uses `hts_idx_get_stat(...)` for the fast path; CRAM, SAM, and unindexed BAM fall back to a full scan while preserving samtools-style contig rows plus the final `*` row. |
| `read_hts_header` | table | table | `rduckhts_hts_header` | Inspect HTS headers in parsed, raw, or combined form across supported formats. Raw VCF/BCF mode includes the final `#CHROM` sample header line so the returned text is suitable for Parquet metadata and future VCF/BCF regeneration. |
| `read_hts_index` | table | table | `rduckhts_hts_index` | Inspect high-level HTS index metadata such as sequence names and mapped counts. |
| `read_hts_index_spans` | table | table | `rduckhts_hts_index_spans` | Expand index metadata into span and chunk rows suitable for low-level index inspection. |
| `read_hts_index_raw` | table_macro | table | `rduckhts_hts_index_raw` | Return the raw on-disk HTS index blob together with basic identifying metadata. |

### Compression

| Function | Kind | Returns | R helper | Description |
| --- | --- | --- | --- | --- |
| `bgzip` | table | table | `rduckhts_bgzip` | Compress a plain file to BGZF and return the created output path and byte counts. |
| `bgunzip` | table | table | `rduckhts_bgunzip` | Decompress a BGZF-compressed file and return the created output path and byte counts. |

### Indexing

| Function | Kind | Returns | R helper | Description |
| --- | --- | --- | --- | --- |
| `bam_index` | table | table | `rduckhts_bam_index` | Build a BAM or CRAM index and report the written index path and format. |
| `bcf_index` | table | table | `rduckhts_bcf_index` | Build a TBI or CSI index for a VCF or BCF file and report the written index path and format. |
| `tabix_index` | table | table | `rduckhts_tabix_index` | Build a tabix index for a BGZF-compressed text file using a preset or explicit coordinate columns. |

### Variants

| Function | Kind | Returns | R helper | Description |
| --- | --- | --- | --- | --- |
| `variantkey` | scalar | UBIGINT |  | Encode a normalized biallelic variant as an official VariantKey-compatible 64-bit unsigned integer. This DuckHTS wrapper accepts 1-based VCF/DuckHTS POS to match bcftools `%VKX` / `+add-variantkey`, internally converts to the upstream 0-based field, and preserves the official hashed nonreversible mode for large, ambiguous, and symbolic REF/ALT strings. Only CHROM, POS, REF, and ALT are encoded; END, SVLEN, mate breakend coordinates, and other SV metadata are not. |
| `variantkey_hex` | scalar | VARCHAR |  | Render a VariantKey as its lowercase 16-character hexadecimal string representation. |
| `parse_variantkey_hex` | scalar | UBIGINT |  | Parse a 16-character hexadecimal VariantKey string back into its UBIGINT code. Invalid or non-hex strings return NULL. |
| `encode_variantkey` | scalar | UBIGINT |  | Encode the raw upstream VariantKey fields directly: chromosome code, 0-based position, and 31-bit REF+ALT code. |
| `extract_variantkey_chrom` | scalar | UTINYINT |  | Extract the raw upstream VariantKey chromosome code. |
| `extract_variantkey_pos` | scalar | UINTEGER |  | Extract the raw upstream VariantKey 0-based position field. |
| `extract_variantkey_refalt` | scalar | UINTEGER |  | Extract the raw upstream 31-bit VariantKey REF+ALT code. |
| `decode_variantkey` | scalar | STRUCT |  | Decode a VariantKey into its raw upstream numeric fields: chrom_code, pos0, and refalt_code. |
| `reverse_variantkey` | scalar | STRUCT |  | Decode a VariantKey into a STRUCT with chrom, chrom_code, 1-based pos, upstream 0-based pos0, ref, alt, refalt_code, and reversible. For hashed nonreversible keys, reversible is FALSE and ref/alt are returned as NULL because DuckHTS v1 does not ship the optional NRVK lookup sidecar. |
| `variantkey_range` | scalar | STRUCT |  | Return the inclusive minimum and maximum VariantKey bounds for a chromosome plus 1-based VCF position range, suitable for numeric range filtering on precomputed VariantKeys. |
| `bcftools_liftover` | scalar | STRUCT | `rduckhts_liftover` | Row-oriented liftover kernel intended to mirror bcftools +liftover semantics as closely as possible while returning one STRUCT per input row with fields: src_chrom, src_pos, src_ref, src_alt, dest_chrom, dest_pos, dest_end, dest_ref, dest_alt, mapped, reverse_complemented, swap, reject_reason, and note. Set no_left_align := true to skip post-liftover left-alignment of lifted indels (mirrors --no-left-align in bcftools +liftover). |
| `duckdb_liftover` | table_macro | table | `rduckhts_liftover` | DuckDB-specific wrapper over bcftools_liftover that takes either a table name or a derived-table expression plus column-name strings for chrom/pos/ref/alt and returns the lifted table. The no_left_align parameter mirrors --no-left-align in bcftools +liftover. |
| `bcftools_norm_row` | scalar | STRUCT |  | Normalize one variant row with bcftools/vt-style left-alignment semantics against a FASTA reference. The alt argument may be either a comma-delimited VARCHAR or a VARCHAR[] list. The returned STRUCT contains pos_normed, end_pos_normed, ref_normed, alt_normed (always VARCHAR[]), normed (TRUE/FALSE/NULL), and norm_status. Symbolic <DEL> rows can use end_pos, and symbolic <DUP> rows can use svlen. gVCF <NON_REF>/<*> reference-block alleles pass through with GVCFReferenceBlock, and mixed real-plus-gVCF-symbolic alleles normalize the real alleles while preserving symbolic alleles and caller-supplied reference-block END in site-preserving output. |
| `duckhts_bcftools_norm` | table_macro | table | `rduckhts_bcftools_norm` | DuckDB table macro wrapper over bcftools_norm_row that normalizes variants from a table or derived-table expression while preserving the original columns. The input ALT column may be either VARCHAR or VARCHAR[]. The result appends pos_normed, end_pos_normed, ref_normed, alt_normed, normed, and norm_status; with split_multiallelic := TRUE, multiallelic sites are split before normalization and alt_normed becomes VARCHAR plus alt_index. This is a vt/vcfnorm-style row/table transform, not a full-record VCF/BCF rewrite: genotype, PL/GP/DS, and PS fields are preserved as caller columns unless a separate full-record writer/remapper layer is used. |
| `bcftools_score` | table | table | `rduckhts_score` | Compute polygenic scores from one genotype BCF/VCF and one or more summary-statistics files with bcftools +score-compatible GT/DS/HDS/AP/GP/AS dosage semantics, sample subsetting, and region/target/FILTER-string controls. The second argument accepts a scalar path or a DuckDB LIST/array of paths; TSV/SSF summaries produce one PRS column per file in a single genotype scan, while GWAS-VCF summaries still produce one PRS column per FORMAT sample. Use summaries_list_file with a NULL second argument to read paths from a file or directory; list-file entries are interpreted as written, matching upstream `bcftools +score --summaries` behavior, while directory inputs scan supported regular summary files in lexicographic order and ignore index sidecars. Use log_path to write per-PRS loaded/matched/allele-mismatch/duplicate-marker audit counts. |
| `bcftools_munge_row` | scalar | STRUCT |  | Normalize one summary-statistics row into GWAS-VCF-style fields (chrom/pos/ref/alt/effect metrics), resolving REF/ALT orientation against a FASTA reference and applying swap-aware sign/frequency/count transforms. The output flag `alleles_swapped` means REF/ALT orientation was swapped to match the FASTA reference. |
| `duckdb_munge` | table_macro | table | `rduckhts_munge` | DuckDB macro wrapper over bcftools_munge_row that maps source columns (via preset or explicit map) and returns normalized GWAS-VCF-style rows with lean outputs and explicit `alleles_swapped` semantics. Output columns: chrom, pos, id, ref, alt, alleles_swapped, filter, ns, ez, nc, es, se, lp, af, ac, ne (16 columns). For METAL meta-analysis output with SI/I2/CQ/ED columns, use duckdb_munge_metal. |
| `duckdb_munge_metal` | table_macro | table | `rduckhts_munge` | Extended munge macro with METAL meta-analysis output columns. Same as duckdb_munge but additionally emits: si (imputation info, from INFO input), i2 (Cochran's I² heterogeneity, from HET_I2), cq (Cochran's Q -log10 p, from HET_LP or -log10(HET_P)), and ed (effect direction string, from DIRE; +/- flipped on allele swap). The R wrapper rduckhts_munge() auto-dispatches to this macro when metal keys (INFO, HET_I2, HET_P, HET_LP, DIRE) are present in the resolved column map. |

### Sequence UDFs

| Function | Kind | Returns | R helper | Description |
| --- | --- | --- | --- | --- |
| `seq_revcomp` | scalar | VARCHAR |  | Compute the reverse complement of a DNA sequence using A, C, G, T, and N bases. Overloaded: accepts either a VARCHAR text sequence (returns VARCHAR) or a UTINYINT[] of htslib nt16 codes as produced by read_bam(sequence_encoding := 'nt16') (returns UTINYINT[]); the nt16 overload is bit-identical to the text path after decoding, so BAM pipelines can reverse-complement without leaving the nt16 encoding. |
| `seq_canonical` | scalar | VARCHAR |  | Return the lexicographically smaller of a sequence and its reverse complement. Overloaded: accepts either a VARCHAR text sequence (returns VARCHAR) or a UTINYINT[] of htslib nt16 codes as produced by read_bam(sequence_encoding := 'nt16') (returns UTINYINT[]); the nt16 overload compares by decoded base order and is bit-identical to the text path after decoding. |
| `seq_hash_2bit` | scalar | UBIGINT |  | Encode a short DNA sequence as a 2-bit unsigned integer hash. Overloaded to also accept a UTINYINT[] of htslib nt16 codes (from read_bam(sequence_encoding := 'nt16')); non-ACGT codes yield NULL, bit-identical to the text path. |
| `seq_encode_4bit` | scalar | UTINYINT[] |  | Encode an IUPAC DNA sequence as a list of 4-bit base codes, preserving ambiguity symbols including N. |
| `seq_decode_4bit` | scalar | VARCHAR |  | Decode a list of 4-bit IUPAC DNA base codes back into a sequence string. |
| `seq_gc_content` | scalar | DOUBLE |  | Compute GC fraction for a DNA sequence as a value between 0 and 1. Overloaded: accepts either a VARCHAR text sequence or a UTINYINT[] of htslib nt16 codes as produced by read_bam(sequence_encoding := 'nt16'); the nt16 overload classifies codes directly and is bit-identical to the text path, so BAM pipelines can compute GC without decoding sequences back to text. |
| `seq_kmers` | table | table |  | Expand a sequence into positional k-mers with optional canonicalization. |

### SAM Flag UDFs

| Function | Kind | Returns | R helper | Description |
| --- | --- | --- | --- | --- |
| `sam_flag_bits` | scalar | STRUCT |  | Decode a SAM flag into a struct of boolean bit fields using explicit SAM-oriented names such as `is_paired`, `is_proper_pair`, `is_next_segment_unmapped`, and `is_supplementary`. |
| `sam_flag_has` | scalar | BOOLEAN |  | Test whether any bits from the provided SAM flag mask are set in a flag value. |
| `is_forward_aligned` | scalar | BOOLEAN |  | Test whether a mapped segment is aligned to the forward strand. Returns `NULL` for unmapped segments because SAM flag `0x10` does not define genomic strand when `0x4` is set. |
| `is_paired` | scalar | BOOLEAN |  | Test whether the SAM flag indicates that the template has multiple segments in sequencing (`0x1`). |
| `is_proper_pair` | scalar | BOOLEAN |  | Test whether the SAM flag indicates that each segment is properly aligned according to the aligner (`0x2`). |
| `is_unmapped` | scalar | BOOLEAN |  | Test whether the read itself is unmapped according to the SAM flag. |
| `is_next_segment_unmapped` | scalar | BOOLEAN |  | Test whether the next segment in the template is flagged as unmapped (`0x8`). |
| `is_reverse_complemented` | scalar | BOOLEAN |  | Test whether `SEQ` is stored reverse complemented (`0x10`); for mapped reads this corresponds to reverse-strand alignment. |
| `is_next_segment_reverse_complemented` | scalar | BOOLEAN |  | Test whether `SEQ` of the next segment in the template is stored reverse complemented (`0x20`). |
| `is_first_segment` | scalar | BOOLEAN |  | Test whether the read is marked as the first segment in the template. |
| `is_last_segment` | scalar | BOOLEAN |  | Test whether the read is marked as the last segment in the template. |
| `is_secondary` | scalar | BOOLEAN |  | Test whether the alignment is marked as secondary. |
| `is_qc_fail` | scalar | BOOLEAN |  | Test whether the read failed vendor or pipeline quality checks. |
| `is_duplicate` | scalar | BOOLEAN |  | Test whether the alignment is flagged as a duplicate. |
| `is_supplementary` | scalar | BOOLEAN |  | Test whether the alignment is marked as supplementary. |

### CIGAR Utils

| Function | Kind | Returns | R helper | Description |
| --- | --- | --- | --- | --- |
| `cigar_has_soft_clip` | scalar | BOOLEAN |  | Test whether a CIGAR string contains any soft-clipped segment (`S`). Overloaded to also accept a UINTEGER[] binary CIGAR (as produced by read_bam(cigar_representation := 'binary')); the binary overload is bit-identical to the text path. |
| `cigar_has_hard_clip` | scalar | BOOLEAN |  | Test whether a CIGAR string contains any hard-clipped segment (`H`). Overloaded to also accept a UINTEGER[] binary CIGAR (as produced by read_bam(cigar_representation := 'binary')); the binary overload is bit-identical to the text path. |
| `cigar_left_soft_clip` | scalar | BIGINT |  | Return the left-end soft-clipped length from a CIGAR string, or zero if the alignment does not start with `S`. Overloaded to also accept a UINTEGER[] binary CIGAR (as produced by read_bam(cigar_representation := 'binary')); the binary overload is bit-identical to the text path. |
| `cigar_right_soft_clip` | scalar | BIGINT |  | Return the right-end soft-clipped length from a CIGAR string, or zero if the alignment does not end with `S`. Overloaded to also accept a UINTEGER[] binary CIGAR (as produced by read_bam(cigar_representation := 'binary')); the binary overload is bit-identical to the text path. |
| `cigar_query_length` | scalar | BIGINT |  | Return the query-consuming length from a CIGAR string, counting `M`, `I`, `S`, `=`, and `X`. Overloaded to also accept a UINTEGER[] binary CIGAR (as produced by read_bam(cigar_representation := 'binary')); the binary overload is bit-identical to the text path. |
| `cigar_aligned_query_length` | scalar | BIGINT |  | Return the aligned query length from a CIGAR string, counting `M`, `=`, and `X` but excluding clips and insertions. Overloaded to also accept a UINTEGER[] binary CIGAR (as produced by read_bam(cigar_representation := 'binary')); the binary overload is bit-identical to the text path. |
| `cigar_reference_length` | scalar | BIGINT |  | Return the reference-consuming length from a CIGAR string, counting `M`, `D`, `N`, `=`, and `X`. Overloaded to also accept a UINTEGER[] binary CIGAR (as produced by read_bam(cigar_representation := 'binary')); the binary overload is bit-identical to the text path. |
| `cigar_has_op` | scalar | BOOLEAN |  | Test whether a CIGAR string contains at least one instance of the requested operator. Overloaded to also accept a UINTEGER[] binary CIGAR (as produced by read_bam(cigar_representation := 'binary')); the binary overload is bit-identical to the text path. |

