Move function.h under ast/ as app_function.h and grammar-match the function call nodes - #1542
Merged
Merged
Conversation
The header holds the call node of an application-defined function together with the definition machinery that generates it (`func<UDF>`, `"name"_scalar`), the same shape as `ast/builtin_function.h`. Name the definition object and the call node after it — `app_function<UDF>` and `app_function_call<UDF, Args...>`, mirroring `builtin_function` and `builtin_function_call` — since `function` and `function_call` say nothing in `internal`. It also specializes the operand and grammar traits in place, so register it in node_definitions.h, which it was missing from. Co-Authored-By: Claude Opus 5
…ument the rule The consumers of `app_function_call` — ast_iterator, column_result_t, node_tuple, statement_serializer and udf_existence_checker — pattern-matched and decomposed the concrete node. Give the node a grammar trait, `is_app_function_call`, and let its consumers match on it and read through `udf_type_t` and `args_tuple_t`. The built-in side gets the same treatment: `is_builtin_function_v` was a primary-false template with a pattern partial specialization per call node; it is now `is_builtin_function_call_v`, one closed definition over `is_base_template_of<builtin_function_call, T>` that also covers the derived aggregate call node, and `is_operator_argument_v` is enabled on it. The rename says what the trait classifies: the call node, not the definition object. The vocabulary document now states the rule both nodes follow: a node's own trait is one closed definition over a type predicate, a joined axis is a SFINAE enabler on the node's grammar trait, and consumers grammar-match and read through the projections rather than pattern-matching and decomposing the node. Co-Authored-By: Claude Opus 5
fnc12
approved these changes
Sep 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two commits, both about the application-defined function machinery and its place in the vocabulary layer.
1.
dev/function.h→dev/ast/app_function.h. The header holds the call node of an application-defined function together with the definition machinery that generates it (func<UDF>,"name"_scalar) — the same shape asast/builtin_function.h, so it belongs next to it. The definition object and the call node are named after it,app_function<UDF>andapp_function_call<UDF, Args...>, mirroringbuiltin_function/builtin_function_call;functionandfunction_callsaid nothing ininternal. "Application-defined" is SQLite's own term (sqlite3_create_function). The header specializes the operand and grammar traits in place, so it is now registered innode_definitions.h, which it had been missing from.2.
is_app_function_call+is_builtin_function_call, and the rule behind them. The consumers of the app-function call node —ast_iterator,column_result_t,node_tuple,statement_serializer,udf_existence_checker— pattern-matched and decomposed the concrete node. They now grammar-match on a newis_app_function_calltrait and read throughudf_type_t/args_tuple_t, and no longer include the node header at all. The built-in side gets the same treatment:is_builtin_function_v(a primary-false template with a pattern partial specialization per call node) becomesis_builtin_function_call_v, one closed definition overis_base_template_of<builtin_function_call, T>that also covers the derived aggregate node;is_operator_argument_vis enabled on the grammar trait for both. The rename says what the trait classifies: the call node, not the definition object.docs/internals/vocabulary-layer.mdgains two sections stating the rule — a node's own trait is one closed definition over a type predicate, a joined axis is a SFINAE enabler on the node's grammar trait, and consumers grammar-match and read through the projections rather than pattern-matching the node — andAGENTS.mdcarries the short form.No public API changes:
func<>,"x"_scalar, theorm_*concepts andstorage.create_*_function()are untouched.Test plan
tests/static_tests/function_static_tests.cpp:is_app_function_call_vpositive for scalar and aggregate call nodes, negative for the UDF type and the definition object;is_operator_argument_von both nodes.tests/static_tests/builtin_function_static_tests.cpp: renamed assertions.🤖 Generated with Claude Code