--- warning: DO NOT CHANGE THIS MANUALLY, THIS IS GENERATED BY https://github.com/duckdb/community-extensions repository, check README there title: sitting_duck excerpt: | DuckDB Community Extensions Parse and analyze source code ASTs from 28 programming languages with tree-sitter grammars, pattern matching, and structural search extension: name: sitting_duck description: Parse and analyze source code ASTs from 28 programming languages with tree-sitter grammars, pattern matching, and structural search version: 1.18.1 language: C++ build: cmake license: Apache-2.0 maintainers: - teaguesterling repo: github: teaguesterling/sitting_duck # v1.18 REQUIRES DUCKDB 2.0, so `ref` and `variegata` are no longer the same # commit. sitting_duck's duckdb submodule pin moved to the v2.0.0 tag and the # v1.5 build leg was removed from its own CI. # # ref, ref_next -> v1.18.1, for the 2.0 line # variegata -> held at v1.17.0, so DuckDB v1.5.6 keeps the artifact it # has today # # `variegata` is unchanged on purpose: the v1.5.6 leg then skips and its # existing artifact stays in place. Stated plainly, so nobody is surprised: # under this entry's `version: 1.18.1`, v1.5.6 continues to serve # sitting_duck v1.17.0. Only the 2.0 line moves. # # WHY v1.5.6 IS STILL OFFERED: ast_select is about 28x slower per call on the # 2.0 line. Measured with one variable changed, 0.448 s against 12.537 s. The # cost is planning, not execution, and PREPARE does not amortize it. It is an # upstream planner regression, duckdb/duckdb#26036. It no longer reproduces on # duckdb main, but that fix is not in any release. ref: 30704be97ef09c416ea97bfd2071e2894fabec2a variegata: cee95ef6eeb33aa6c25527769d3ebf97898aa994 # # v1.18.0 CHANGED OUTPUT, so re-measure if you pin values. ast_type_map() # gained a `native_strategy` column at index 8, which moves `flags` from 8 to # 9. Four native-extraction paths that returned populated but WRONG values now # return correct ones: python type annotations, swift call arguments, and lua # local visibility and modifier scope. v1.18.1 adds an opt-in `peek :=` # parameter to ast_select and corrects the ast_unparse documentation. # Notes: https://github.com/teaguesterling/sitting_duck/blob/main/docs/releases/v1.18.1.md # # EVIDENCE: run 41990901070 on the extension repo, at the commit `ref` names, is # completed/success with no job outside success and skipped, over 17 platform # legs. https://github.com/teaguesterling/sitting_duck/actions/runs/41990901070 # # The suite RUNS against DuckDB v2.0.0 -- the version this registry builds -- # on all four platforms where the harness runs it, with identical counts: # # linux_amd64 ran tests: 168 passed, 5 skipped in 1310s # osx_arm64 ran tests: 168 passed, 5 skipped in 3264s # windows_amd64 ran tests: 168 passed, 5 skipped in 3820s # windows_amd64_mingw ran tests: 168 passed, 5 skipped in 3899s # # A fifth leg pins the same v2.0.0 tag with ci-tools `main` and reports # ran tests: 168 passed, 5 skipped in 1325s on linux_amd64. # # The rest is COMPILE evidence, stated so a green "Test" step is not over-read. # On `linux_arm64` the harness itself declines: "Tests are not supported for # linux_arm64." The three wasm targets have no test step. A separate leg # builds the moving `v2.0-cyanoptera` branch with `skip_tests: true`, whose # Test step prints "Tests skipped by workflow input." ref_next: 30704be97ef09c416ea97bfd2071e2894fabec2a docs: hello_world: | -- Parse Python code and find function definitions SELECT name, start_line, peek FROM parse_ast(' def hello(): return "hello world" def greet(name): print(f"Hello, {name}!") return name ', 'python') WHERE is_function_definition(semantic_type); -- Pattern matching: find eval() calls and capture arguments SELECT captures['X'].peek as dangerous_input, file_path, start_line FROM ast_match('code', 'eval(__X__)', 'python'); -- Pattern matching with variadic wildcards SELECT captures['F'].name as func_name, captures['Y'].peek as return_value FROM ast_match('code', 'def __F__(__): %____% return __Y__', 'python'); -- Security audit: find dangerous function calls SELECT * FROM ast_security_audit('code') WHERE risk_level = 'high'; -- Function complexity metrics SELECT name, cyclomatic, max_depth, lines FROM ast_function_metrics('code') WHERE cyclomatic > 10; -- Cross-language analysis with semantic types SELECT language, COUNT(*) as functions FROM read_ast(['src/**/*.py', 'src/**/*.js', 'src/**/*.go']) WHERE is_function_definition(semantic_type) GROUP BY language; extended_description: | Sitting Duck is a DuckDB extension for parsing source code into Abstract Syntax Trees (ASTs) using tree-sitter grammars. It provides a powerful SQL interface to analyze, search, and understand code structure across 25+ programming languages. **Documentation:** https://sitting-duck.readthedocs.io/ ## Core Features **Pattern Matching:** Find code structures using pattern-by-example matching with wildcards: ```sql -- Recursive wildcards for deep matching SELECT * FROM ast_match('code', 'class __C__: %__<**>__% def __M__(self): %____%', 'python'); -- Optional and negation wildcards SELECT * FROM ast_match('code', 'def __F__(____): %____%', 'python'); ``` See: https://sitting-duck.readthedocs.io/en/latest/guide/pattern-matching/ **CSS Selector Queries (v1.6.0, enhanced in v1.7.0+):** Query AST nodes using CSS selector syntax — bootstrapped with sitting duck's own CSS grammar: ```sql SELECT name FROM ast_select('src/*.py', '.func:has(.call#execute):not(:has(try_statement))'); -- v1.7.0: :match (current-node) vs :contains (subtree) structural patterns SELECT name FROM ast_select('src/*.py', '.func:contains("db.execute()")'); SELECT name FROM ast_select('src/*.py', 'call:match("db.execute()")'); -- v1.7.2: parse once, query many — orders of magnitude faster for interactive use CREATE TABLE my_ast AS SELECT * FROM read_ast('src/**/*.py'); SELECT * FROM ast_select_from('my_ast', '.class:named'); SELECT * FROM ast_select_from('my_ast', '.func:has(return_statement)'); ``` Supports type selectors, `#name`, `.semantic` (~80 aliases), combinators, `:has()`, `:not()`, `:match()` / `:contains()` structural patterns, scope/call-graph pseudo-classes, and pseudo-element navigation. Bare type matching: `if` matches `if` + `if_statement` + `if_clause`. v1.10.0 adds runtime-loadable tree-sitter grammars (`register_language()`, off by default behind `sitting_duck_enable_runtime_grammars`), `ast_to_blocks` (render code structure as duck_blocks documents), and `ast_patch`/`ast_replace` (AST-anchored source patching and selector-driven rewriting in SQL). v1.9.0 hardens the selector engine: no more silent-empty results (selectors the engine can't honor now raise a clear error instead of returning 0 rows), `#name` on call nodes binds uniformly across all 27 grammars, and NULL columns no longer over- or under-match. **Parse-time filtering (v1.8.0):** `max_depth :=` and `prune :=` shrink the AST at parse time, with automatic tree healing: ```sql SELECT * FROM read_ast('file.py', max_depth := 2); SELECT * FROM read_ast('src/**/*.py', prune := ['syntax', 'comments', 'punctuation']); ``` Prune policies: `syntax`, `comments`, `literals`, `imports`, `types`, `punctuation`, `unnamed`, `leaves`, `internal`. **Call-graph macros (v1.8.0):** - `ast_get_calls(source)` - calls with caller attribution and type classification - `ast_call_graph(source)` - aggregated caller→callee graph with call counts - `ast_find_references(source, name)` - scope-chain-aware symbol reference resolution **Table Functions:** - `read_ast(file_pattern, language := NULL)` - Parse source files into AST rows (parallel) - `parse_ast(content, language)` - Parse source code strings (table function) - `parse_ast_list(content, language)` - Parse source code strings (scalar, returns LIST; v1.7.0) - `ast_match(source, pattern, lang)` - Pattern matching for code search - `ast_select(source, css_selector)` - CSS selector queries - `ast_select_from(table_name, selector)` - CSS selectors on pre-parsed tables (v1.7.2) - `ast_type_map(language)` - Node type discovery across languages **v1.7.0 extraction suffix:** Any extraction parameter (`context`, `source`, `structure`, `peek`) can take a `+schema` suffix that keeps the full column set in the output schema as NULLs without computing them: ```sql -- Keep peek column in schema but skip its computation SELECT name, peek FROM read_ast('file.py', peek := 'none+schema'); ``` Enables SQL macros to declare stable schemas regardless of which columns they populate. **Relational Predicates (v1.5.0):** - `ast_has(source, parent_type, child_type)` - Check containment relationships - `ast_inside(source, child_type, parent_type, parent_name)` - Find nodes inside specific parents - `ast_precedes(source, before_type, after_type)` - Ordering predicates - `ast_follows(source, after_type, before_type)` - Ordering predicates - `ast_not_has(source, parent_type, child_type)` - Negated containment **Analysis Macros (file-path based):** - `ast_definitions(source)` - All named definitions with categories - `ast_function_metrics(source)` - Cyclomatic complexity, nesting depth, line counts - `ast_security_audit(source)` - Detect dangerous function call patterns - `ast_dead_code(source)` - Find potentially unused functions/classes - `ast_nesting_analysis(source)` - Identify deeply nested code - `ast_definition_parent(table)` - Resolve nearest definition ancestor per node **Tree Navigation:** - `ast_descendants(table, node_id)` - Get subtree (O(1) using descendant_count) - `ast_ancestors(table, node_id)` - Path from node to root - `ast_children(table, node_id)` - Immediate children - `ast_function_scope(table, node_id)` - Function body excluding nested functions **Semantic Predicates:** Cross-language filtering with normalized types: - `is_function_definition(st)`, `is_class_definition(st)`, `is_variable_definition(st)` - `is_function_call(st)`, `is_literal(st)`, `is_conditional(st)`, `is_loop(st)` ## Supported Languages (27) | Category | Languages | |----------|-----------| | **Web** | JavaScript, TypeScript, HTML, CSS | | **Systems** | C, C++, Go, Rust, Zig | | **Scripting** | Python, Ruby, PHP, Lua, R, Bash | | **Enterprise** | Java, C#, Kotlin, Swift | | **Mobile** | Dart | | **Data** | SQL, JSON, TOML, GraphQL, HCL | | **Documentation** | Markdown | ## AST Schema Each parsed node includes: - `type`, `name` - Node type and extracted identifier - `semantic_type` - Normalized type for cross-language queries - `file_path`, `language` - Source location - `start_line`, `end_line`, `depth` - Position and nesting - `descendant_count` - For O(1) subtree queries - `peek` - Configurable source preview - `qualified_name` - Scope-based path unique within a file (`C[User] F[__init__]` format; v1.7.0) - `signature_type`, `parameters`, `modifiers`, `annotations` - Native extraction (v1.8.0: `modifiers[]` populated across Python, JS, TS, Rust, Kotlin, Swift, Dart, C#; `IS_EXPORTED` flag for file-level visibility) - `scope` - STRUCT (v1.7.4); replaces the v1.7.2 `scope_id` / `scope_stack` columns. `scope.function` lets you answer "what function is this in?" as a single column read. Full schema: https://sitting-duck.readthedocs.io/en/latest/api/output-schema/ ## Use Cases - **Security auditing** - Find dangerous patterns (eval, exec, SQL injection) - **Code quality** - Complexity metrics, dead code detection, nesting analysis - **Refactoring** - Pattern-based code search across large codebases - **Documentation** - Extract function signatures and structure - **AI workflows** - Structured code understanding for LLM tools **GitHub:** https://github.com/teaguesterling/sitting_duck extension_star_count: 36 extension_star_count_pretty: 36 extension_download_count: 1132 extension_download_count_pretty: 1.1k image: '/images/community_extensions/social_preview/preview_community_extension_sitting_duck.png' layout: community_extension_doc --- ### Compatibility Matrix This table covers all DuckDB releases that have not reached [end-of-life](https://duckdb.org/release_calendar), including LTS releases, and shows the 2 most recent patch releases of each. Older patch releases are not listed, but the extension may be available for them as well.
| Platform | 1.4.4 | 1.4.5 | 1.5.5 | 1.5.6 | 2.0.0 | | :--- | :---: | :---: | :---: | :---: | :---: | | Linux AMD64 | ✅ | ❌ | ✅ | ✅ | ✅ | | Linux ARM64 | ✅ | ❌ | ✅ | ✅ | ✅ | | macOS AMD64 | ✅ | ❌ | ✅ | ✅ | ✅ | | macOS ARM64 | ✅ | ❌ | ✅ | ✅ | ✅ | | Windows AMD64 | ✅ | ❌ | ✅ | ✅ | ✅ | | Windows ARM64 | ❌ | ❌ | ❌ | ❌ | ❌ | | WebAssembly | ✅ | ❌ | ✅ | ✅ | ✅ | ### Installing and Loading ```sql INSTALL {{ page.extension.name }} FROM community; LOAD {{ page.extension.name }}; ``` {% if page.docs.hello_world %} ### Example ```sql {{ page.docs.hello_world }}``` {% endif %} {% if page.docs.extended_description %} ### About {{ page.extension.name }} {{ page.docs.extended_description }} {% endif %} ### Added Functions
| function_name | function_type | description | comment | examples | |----------------------------------------|---------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | ast_ancestors | table_macro | The ancestor chain from a node up to the root | NULL | | | ast_call_arguments | table_macro | Argument nodes of a call, from its argument_list child | NULL | | | ast_call_graph | table_macro | Caller to callee edges derived from the call sites | NULL | | | ast_callees | table_macro | What does each function call? | NULL | [SELECT * FROM ast_callees('src/**/*.py');, SELECT caller, callee FROM ast_callees('src/*.py') WHERE caller = 'main';] | | ast_callers | table_macro | Who calls a given function? | NULL | [SELECT * FROM ast_callers('src/**/*.py');, SELECT caller, callee FROM ast_callers('src/*.py') WHERE callee = 'execute';] | | ast_capture | macro | Pull one named capture out of a match captures map | NULL | | | ast_children | table_macro | Direct children of a node in a parsed AST table | NULL | | | ast_class_members | table_macro | Members declared directly inside one class | NULL | | | ast_containing_line | table_macro | Nodes whose source span covers a given line number | NULL | | | ast_dead_code | table_macro | Definitions with no reference elsewhere in the source, with the reason | NULL | | | ast_definition_parent | table_macro | The nearest enclosing definition for every node in an AST table | NULL | | | ast_definitions | table_macro | Every definition (function, class, variable, module) in the source | NULL | | | ast_descendants | table_macro | Every node beneath an ancestor, via its descendant_count range | NULL | | | ast_dispatch_predicate | macro | NULL | NULL | | | ast_exports | table_macro | Module-level definitions visible outside the file | NULL | [SELECT * FROM ast_exports('src/**/*.py');, SELECT name, type FROM ast_exports('src/*.go') WHERE name = upper(left(name, 1)) \|\| right(name, -1);] | | ast_find_references | table_macro | Find all uses of a symbol via scope-chain resolution | NULL | [SELECT * FROM ast_find_references('src/**/*.py', 'process');, SELECT * FROM ast_find_references('src/main.py', 'x') WHERE ref_kind = 'call';, SELECT * FROM ast_find_references('src/*.py', 'Service', language := 'python');] | | ast_follows | table_macro | Nodes of one type that appear after a node of another type | NULL | | | ast_function_metrics | table_macro | Per-function size and complexity: lines, return_count, conditionals, loops, cyclomatic | NULL | | | ast_function_scope | table_macro | Every node inside one function definition | NULL | | | ast_functions_containing | table_macro | Functions that contain at least one node of a given type | NULL | | | ast_get_calls | table_macro | Call sites in the source, with the enclosing function | NULL | | | ast_get_source | macro | Raw source text for a line range of a file | NULL | | | ast_get_source_line | macro | A single line of source text from a file | NULL | | | ast_get_source_numbered | macro | Source text for a line range, each line prefixed with its number | NULL | | | ast_has | table_macro | Nodes of one type that contain a node of another type | NULL | | | ast_imports | table_macro | Import statements with source module and imported names | NULL | [SELECT * FROM ast_imports('src/**/*.py');, SELECT source_module, imported_name FROM ast_imports('src/*.js');] | | ast_in_range | table_macro | Nodes whose source span falls inside a line range | NULL | | | ast_inside | table_macro | Nodes of one type that sit inside a node of another type | NULL | | | ast_match | table_macro | Find nodes matching a structural pattern, with wildcard captures | NULL | [SELECT * FROM ast_match('src/**/*.py', 'my_func(__X__)');, SELECT * FROM ast_match('src/main.py', 'my_func(__X__)', match_syntax := true);, SELECT * FROM ast_match('src/**/*.py', '__F__(__X__)', match_by := 'semantic_type');] | | ast_nesting_analysis | table_macro | Per-function nesting depth: max_depth, avg_depth, deep_nodes, total_nodes | NULL | | | ast_node_edit | macro | build a well-formed edit STRUCT from an AST row's location columns. `node` is any STRUCT/row with file_path, start_line, start_column, end_line, end_column — pass the table alias of a read_ast(...) scan directly. Expand to columns with unnest(...): | NULL | [SELECT unnest(ast_node_edit(r, 'replace', 'renamed_fn')), SELECT unnest(ast_node_edit(r, 'replace', 'new_text'))] | | ast_not_has | table_macro | Nodes of one type that do NOT contain a node of another type | NULL | | | ast_patch | table_macro | apply edit rows to their files, returning patched text | NULL | [SELECT * FROM ast_patch('edits', 'src/main.py');] | | ast_pattern | table_macro | Parse a pattern string into its node sequence | NULL | | | ast_pattern_list | macro | Parse a pattern string into a list of pattern tokens | NULL | | | ast_peek_contains_any | scalar | Case-sensitive search checking if peek string contains any pattern in the list (alias of string_contains_any). | NULL | [ast_peek_contains_any(peek, ['import', 'require'])] | | ast_precedes | table_macro | Nodes of one type that appear before a node of another type | NULL | | | ast_qualified_name_as_string | macro | NULL | NULL | | | ast_replace | table_macro | one-shot selector-driven replacement — match nodes with a CSS selector (the ast_select engine), replace each match's exact byte range with new_text, return the patched text per file | NULL | | | ast_resolve | table_macro | Resolve references to their definitions via scope chain | NULL | [SELECT * FROM ast_resolve('src/main.py');, SELECT r.ref_name, r.def_line, r.scope_hops FROM ast_resolve('src/*.py') r;] | | ast_resolve_entity | table_macro | Find a named entity by name and optional kind, within one file | NULL | [SELECT * FROM ast_resolve_entity('src/app.py', 'run', kind := 'function');] | | ast_security_audit | table_macro | Risk-pattern findings per function: risk_category, risk_level, finding, matched_pattern | NULL | | | ast_select | table_macro | convenience wrapper that parses source files and then runs the selector engine. For one-off queries this is the simplest API. For repeated queries, use ast_select_from with a pre-parsed table | NULL | | | ast_select_from | table_macro | the selector engine, operates on a pre-parsed AST table. The `source` parameter is a table name (string) resolved via query_table(). This separates parsing (expensive) from querying (cheap), enabling callers to parse once and query many times with different selectors | NULL | [SELECT * FROM ast_select_from('my_ast', '.class:named');, SELECT * FROM ast_select_from('my_ast', '.func:has(return_statement)');] | | ast_select_list | table_macro | nested form, one row per rule with matches packed as LIST | NULL | | | ast_select_rules | table_macro | Run several CSS selector rules at once, one row per match | NULL | | | ast_selector_for | table_macro | node -> selector ("Copy selector", as in browser devtools) | NULL | [SELECT * FROM ast_selector_for('my_ast', 'src/app.py', 42);] | | ast_semantic_aliases | table | Return every semantic class usable in an ast_select selector (e.g. .fn, .call, .def), what it resolves to, and how broadly it matches. | NULL | [SELECT selector, resolves_to FROM ast_semantic_aliases() ORDER BY selector] | | ast_siblings | table_macro | Nodes sharing a parent with the target node | NULL | | | ast_source_bytes | scalar | Read a file's pristine bytes as a BLOB, one row at a time. NULL when the path does not exist (including the '' pseudo-path of parse_ast()). This is the per-row substrate byte-exact unparse needs, which read_blob() cannot provide because table functions take only constant arguments. | NULL | [SELECT ast_source_bytes('src/main.py'), SELECT fp, ast_source_bytes(fp) AS cblob FROM (SELECT DISTINCT file_path AS fp FROM nodes)] | | ast_source_of | table_macro | Source text for matched nodes, keyed by file pattern | NULL | [SELECT * FROM ast_source_of('src/**/*.py', 'process_payment');, SELECT * FROM ast_source_of('src/**/*.py', 'MyClass', kind := 'class');, SELECT * FROM ast_source_of('src/**/*.py', 'handler', language := 'python', kind := 'function');] | | ast_supported_languages | table | Return list of supported programming and markup languages and their registered grammar metadata. | NULL | [SELECT * FROM ast_supported_languages()] | | ast_to_blocks | table_macro | convenience wrapper that parses source files (with the peek := 'full' that complete bodies require) and delegates to the converter engine. Same CTE-delegation pattern as ast_select -> ast_select_from | NULL | | | ast_to_blocks_from | table_macro | the converter engine, operates on a pre-parsed AST table (name resolved via query_table). Parse once with read_ast(..., peek := 'full'), convert many times with different styles | NULL | | | ast_to_blocks_list | table_macro | one row per file with the blocks pre-aggregated into a LIST(duck_block) ready for consumers that take a whole document, e.g. duck_block_utils rendering: | NULL | | | ast_type_map | table | Return mapping of AST node types to semantic types and extraction strategies. | NULL | [SELECT * FROM ast_type_map(), SELECT * FROM ast_type_map('python')] | | ast_unparse | table_macro | Reconstruct source text from a file path, using a formatting preset | NULL | | | ast_unparse_code | table_macro | Reconstruct source text from a code string, using a formatting preset | NULL | | | ast_unparse_custom | table_macro | Reconstruct source text using caller-supplied formatting rules | NULL | | | ast_unparse_exact | table_macro | Reproduce a file byte-for-byte from its AST, or refuse — no normalising | NULL | | | ast_unparse_exact_code | table_macro | Reproduce a code string byte-for-byte through a parse round-trip | NULL | | | ast_unparse_exact_from | table_macro | Reproduce files byte-for-byte from an existing AST table | NULL | | | ast_unparse_exact_splice | table_macro | the shared core. You normally want `ast_unparse_exact(path)`; this is exposed because it is the one place the splice lives, and because it is useful on its own | NULL | | | ast_unparse_from | table_macro | Reconstruct source text from an AST table, using a formatting preset | NULL | | | ast_unparse_rules | table | Return active unparse layout and spacing rules. | NULL | [SELECT * FROM ast_unparse_rules(), SELECT * FROM ast_unparse_rules('python'), SELECT * FROM ast_unparse_rules('python', 'black'), SELECT * FROM ast_unparse_rules('go', 'gofmt')] | | binds_name | scalar | Returns true if node binds a name in lexical scope (definition or declaration). | NULL | [binds_name(flags)] | | clean_pattern | macro | NULL | NULL | | | detect_language | scalar | Detect tree-sitter language name from file extension, or return NULL if unknown. | NULL | [detect_language('src/main.rs')] | | get_kind | scalar | Get the primary kind name (FUNCTION, CLASS, VARIABLE, etc.) for a semantic type. | NULL | [get_kind(semantic_type)] | | get_searchable_types | scalar | Get list of all searchable semantic type codes. | NULL | [get_searchable_types()] | | get_super_kind | scalar | Get the super-kind category name (DEFINITION, EXECUTION, STRUCTURE, LITERAL, etc.) for a semantic type. | NULL | [get_super_kind(semantic_type)] | | has_body | scalar | Returns true if node has an embodied implementation body. | NULL | [has_body(flags)] | | is_annotation | macro | NULL | NULL | | | is_arithmetic | macro | NULL | NULL | | | is_assignment | macro | NULL | NULL | | | is_block | macro | NULL | NULL | | | is_boolean_literal | macro | NULL | NULL | | | is_call | scalar | Check if a semantic type represents a function/method call expression. | NULL | [is_call(semantic_type)] | | is_class_definition | macro | NULL | NULL | | | is_comment | macro | NULL | NULL | | | is_comparison | macro | NULL | NULL | | | is_conditional | macro | NULL | NULL | | | is_constituent | scalar | Returns true if node is an internal constituent part of a compound construct. | NULL | [is_constituent(flags)] | | is_construct | scalar | Returns true if node is a meaningful semantic construct (inverse of is_syntax_only). | NULL | [is_construct(flags)] | | is_control_flow | scalar | Check if a semantic type represents a control flow construct (if, loop, switch, return, etc.). | NULL | [is_control_flow(semantic_type)] | | is_declaration_only | scalar | Returns true if node is a declaration without an accompanying implementation body. | NULL | [is_declaration_only(flags)] | | is_definition | scalar | Check if a semantic type represents a definition (function, class, variable, etc.). | NULL | [is_definition(semantic_type)] | | is_directive | macro | NULL | NULL | | | is_embodied | scalar | Returns true if node is an embodied definition (has implementation body). | NULL | [is_embodied(flags)] | | is_export | macro | NULL | NULL | | | is_exported | scalar | Returns true if node is exported from its containing module/package. | NULL | [is_exported(flags)] | | is_foreign | macro | NULL | NULL | | | is_function_call | macro | NULL | NULL | | | is_function_definition | macro | NULL | NULL | | | is_identifier | scalar | Check if a semantic type represents an identifier (variable name, function name, etc.). | NULL | [is_identifier(semantic_type)] | | is_import | macro | NULL | NULL | | | is_jump | macro | NULL | NULL | | | is_kind | scalar | Check if a semantic type code belongs to the specified kind. | NULL | [is_kind(semantic_type, 'FUNCTION')] | | is_list | macro | NULL | NULL | | | is_literal | macro | NULL | NULL | | | is_logical | macro | NULL | NULL | | | is_loop | macro | NULL | NULL | | | is_member_access | macro | NULL | NULL | | | is_module_definition | macro | NULL | NULL | | | is_name_declaration | scalar | Returns true if node represents a name declaration. | NULL | [is_name_declaration(flags)] | | is_name_definition | scalar | Returns true if node represents a name definition. | NULL | [is_name_definition(flags)] | | is_name_reference | scalar | Returns true if node represents a name reference. | NULL | [is_name_reference(flags)] | | is_number_literal | macro | NULL | NULL | | | is_parser_specific | scalar | Check if a semantic type is parser-specific/unclassified in the universal taxonomy. | NULL | [is_parser_specific(semantic_type)] | | is_pattern_wildcard | macro | NULL | NULL | | | is_punctuation | scalar | Check if a semantic type represents punctuation or syntax delimiter. | NULL | [is_punctuation(semantic_type)] | | is_scope | scalar | Returns true if node establishes a lexical scope boundary (function, class, block, module). | NULL | [is_scope(flags)] | | is_semantic_type | scalar | Check if a semantic type bitmask matches a taxonomy pattern string. | NULL | [is_semantic_type(semantic_type, 'DEFINITION_%')] | | is_string_literal | macro | NULL | NULL | | | is_syntax_only | scalar | Returns true if node is a pure syntax token (keyword, punctuation) with no semantic payload. | NULL | [is_syntax_only(flags)] | | is_type_composite | macro | NULL | NULL | | | is_type_definition | macro | NULL | NULL | | | is_type_generic | macro | NULL | NULL | | | is_type_primitive | macro | NULL | NULL | | | is_type_reference | macro | NULL | NULL | | | is_variable_definition | macro | NULL | NULL | | | kind_code | scalar | Get the numeric code for a taxonomy kind name. | NULL | [kind_code('FUNCTION')] | | name_role | scalar | Get the numeric NameRole code (0=NONE, 1=DECLARATION, 2=DEFINITION, 3=REFERENCE) from flags. | NULL | [name_role(flags)] | | parse_ast | table | Parse source code string into an AST table representation. | NULL | [SELECT * FROM parse_ast('def add(a, b): return a + b', 'python')] | | parse_ast_flat | table | Parse source code string into a flat AST table representation (alias of parse_ast). | NULL | [SELECT * FROM parse_ast_flat('def add(a, b): return a + b', 'python')] | | parse_ast_hierarchical | table | Parse source code string into a hierarchical AST table representation. | NULL | [SELECT * FROM parse_ast_hierarchical('def add(a, b): return a + b', 'python')] | | parse_ast_list | scalar | Parse source code string into a list of AST node structs (scalar function for column-valued inputs). | NULL | [parse_ast_list('x = 1', 'python')] | | parse_ast_list_table | table_macro | Table-macro wrapper for parse_ast_list | NULL | | | parse_html_wildcard | macro | NULL | NULL | | | pattern_has_recursive | macro | NULL | NULL | | | pattern_has_variadic | macro | NULL | NULL | | | read_ast | table | Parse source code from file(s) into an AST table representation. | NULL | [SELECT * FROM read_ast('src/main.cpp'), SELECT * FROM read_ast('src/main.cpp', 'cpp')] | | read_ast | table | NULL | NULL | | | read_ast_flat | table | Parse source code from file(s) into flat AST table representation (alias of read_ast). | NULL | [SELECT * FROM read_ast_flat('src/main.cpp'), SELECT * FROM read_ast_flat('src/main.cpp', 'cpp')] | | read_ast_flat | table | NULL | NULL | | | read_ast_hierarchical | table | Parse source code from file(s) into legacy hierarchical AST table representation. | NULL | [SELECT * FROM read_ast_hierarchical('src/main.cpp'), SELECT * FROM read_ast_hierarchical('src/main.cpp', 'cpp')] | | read_ast_hierarchical | table | NULL | NULL | | | read_ast_hierarchical_new | table | Parse source code from file(s) into hierarchical AST table representation. | NULL | [SELECT * FROM read_ast_hierarchical_new('src/main.cpp'), SELECT * FROM read_ast_hierarchical_new('src/main.cpp', 'cpp')] | | read_ast_hierarchical_new | table | NULL | NULL | | | register_language | table | Dynamically register a tree-sitter language grammar from a shared library. | NULL | [SELECT * FROM register_language('mylang', '/path/to/libtree-sitter-mylang.so')] | | semantic_type_base | macro | NULL | NULL | | | semantic_type_code | scalar | Convert a semantic type name string to its numeric bitmask code. | NULL | [semantic_type_code('DEFINITION_FUNCTION')] | | semantic_type_to_string | scalar | Convert a numeric semantic type bitmask to its human-readable name string. | NULL | [semantic_type_to_string(1::UTINYINT)] | | sitting_duck_enable_dynamic_predicates | pragma | NULL | NULL | | | string_contains_any | scalar | Case-sensitive search checking if string contains any pattern in the list. | NULL | [string_contains_any('hello world', ['world', 'foo'])] | | string_contains_any_i | scalar | Case-insensitive search checking if string contains any pattern in the list. | NULL | [string_contains_any_i('Hello World', ['world', 'foo'])] | | wildcard_capture_name | macro | NULL | NULL | | ### Overloaded Functions
This extension does not add any function overloads. ### Added Types
| type_name | type_size | logical_type | type_category | internal | |---------------|----------:|--------------|---------------|----------| | SEMANTIC_TYPE | 1 | UTINYINT | NUMERIC | true | ### Added Settings
| name | description | input_type | scope | aliases | typed_value | |--------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------|------------|--------|---------|-------------| | sitting_duck_enable_runtime_grammars | Allow register_language() to load native tree-sitter grammar libraries, which executes arbitrary native code in-process. Disabled by default. | BOOLEAN | GLOBAL | [] | false | | temp_directory | Set the directory to which temporary files are written. | VARCHAR | GLOBAL | [] | post.db.tmp |