sqry_core/query/mod.rs
1//! Query language for AST-aware code search
2//!
3//! This module provides a powerful query language for searching code based on
4//! semantic properties like symbol type, name patterns, language, and more.
5//!
6//! # Query Parsing
7//!
8//! All queries are parsed through the boolean AST parser:
9//!
10//! - **Boolean queries**: Parsed directly via [`QueryParser`](crate::query::QueryParser)
11//! - **Execution**: Use [`QueryExecutor::execute_on_graph`](crate::query::QueryExecutor::execute_on_graph) for string queries
12//!
13//! ## Recommended Entry Points
14//!
15//! | Use Case | Function | Notes |
16//! |----------|----------|-------|
17//! | Query execution | [`QueryExecutor::execute_on_graph`](crate::query::QueryExecutor::execute_on_graph) | Most common - handles everything |
18//! | AST access | [`QueryParser::parse_query`](crate::query::QueryParser::parse_query) | Boolean queries only |
19//!
20//! # Query Language
21//!
22//! The boolean query language supports:
23//!
24//! - **Boolean operators**: AND, OR, NOT
25//! - **Comparison operators**: `:` (equal), `~=` (regex), `>`, `<`, `>=`, `<=`
26//! - **Field types**: kind, name, path, lang, text, and plugin-specific fields
27//! - **Values**: strings, regex patterns, numbers, booleans
28//! - **Grouping**: parentheses for precedence
29//!
30//! # Core Types
31//!
32//! - [`Query`](crate::query::types::Query) - Complete query with root expression
33//! - [`Expr`](crate::query::Expr) - Expression nodes (Or, And, Not, Condition)
34//! - [`Condition`](crate::query::Condition) - Field-operator-value conditions
35//! - [`Operator`](crate::query::Operator) - Comparison operators
36//! - [`Value`](crate::query::Value) - Values in conditions
37//!
38//! # Error Handling
39//!
40//! All errors use [`QueryError`](crate::query::QueryError) which wraps:
41//! - [`LexError`](crate::query::LexError) - Tokenization errors
42//! - [`ParseError`](crate::query::ParseError) - Parsing errors
43//! - [`ValidationError`](crate::query::ValidationError) - Semantic validation errors
44//! - [`ExecutionError`](crate::query::ExecutionError) - Runtime execution errors
45//!
46//! # Performance
47//!
48//! The query lexer uses a thread-local buffer pool to reduce allocations:
49//!
50//! - **Allocation efficiency**: 80% fewer heap allocations vs creating fresh lexers
51//! - **Memory efficiency**: Reuses token buffers across multiple tokenize calls
52//! - **Thread-safe**: Each thread has its own isolated pool
53//! - **Configurable**: Can be tuned or disabled via environment variables
54//!
55//! ## Lexer Pool Configuration
56//!
57//! The lexer pool can be configured via environment variables:
58//!
59//! ```bash
60//! # Pool size (default: 4 lexers per thread)
61//! export SQRY_LEXER_POOL_MAX=8
62//!
63//! # Buffer capacity limit (default: 256 tokens)
64//! export SQRY_LEXER_POOL_MAX_CAP=512
65//!
66//! # Shrink ratio (default: 8x)
67//! export SQRY_LEXER_POOL_SHRINK_RATIO=4
68//!
69//! # Disable pooling (for latency-critical workloads)
70//! export SQRY_LEXER_POOL_MAX=0
71//! ```
72//!
73//! **Performance characteristics**:
74//! - Simple queries (<10 tokens): ~380ns (pooled) vs ~223ns (fresh) – pooling adds overhead
75//! - Long queries (>100 tokens): ~18.2µs (pooled) vs ~19.1µs (fresh) – pooling saves ~4%
76//! - High-throughput workloads: Pool reduces GC pressure and memory fragmentation
77//!
78//! **Recommendation**: Keep pooling enabled (default) for most workloads. The overhead
79//! (~150ns per query) is negligible compared to typical query execution time (>10ms).
80//! Disable only for latency-critical single-query scenarios.
81//!
82//! # Examples
83//!
84//! ```ignore
85//! use sqry_core::query::QueryParser;
86//!
87//! // Find all async functions
88//! let query = QueryParser::parse_query("kind:function AND async:true").unwrap();
89//!
90//! // Find test functions (using regex)
91//! let query = QueryParser::parse_query("kind:function AND name~=/^test_/").unwrap();
92//!
93//! // Find functions OR methods in Rust files
94//! let query = QueryParser::parse_query("(kind:function OR kind:method) AND lang:rust").unwrap();
95//!
96//! // Find non-test functions
97//! let query = QueryParser::parse_query("kind:function AND NOT name~=/test/").unwrap();
98//! ```
99
100// Core query modules
101mod executor;
102pub(crate) mod name_matching;
103mod repo_filter;
104
105// Boolean query language modules
106pub mod builder;
107pub mod cache;
108pub mod error;
109pub mod lexer;
110pub mod optimizer;
111pub mod parsed_query;
112pub mod parser_new;
113pub mod pipeline;
114pub mod plan;
115pub mod regex_cache;
116pub mod registry;
117pub mod results;
118pub mod security;
119pub mod types;
120pub mod validator;
121
122// Existing exports
123pub use executor::QueryExecutor;
124
125// CD Predicate exports (duplicate detection, cycle detection, unused analysis)
126// Graph-based analysis (CodeGraph API)
127pub use executor::UnusedScope;
128pub use executor::{CircularConfig, CircularType};
129pub use executor::{DuplicateConfig, DuplicateGroup, DuplicateType};
130
131pub use executor::build_duplicate_groups_graph;
132pub use executor::{compute_reachable_set_graph, find_unused_nodes, is_node_unused};
133pub use executor::{find_all_cycles_graph, is_node_in_cycle};
134
135pub use repo_filter::RepoFilter;
136
137// New exports
138pub use error::{
139 ExecutionError, LexError, ParseError, QueryError, RichQueryError, ValidationError,
140};
141pub use lexer::{Lexer, Token, TokenType};
142pub use optimizer::Optimizer;
143pub use parsed_query::ParsedQuery;
144pub use parser_new::Parser as QueryParser;
145pub use plan::{CacheStatus, ExecutionStep, QueryPlan};
146pub use registry::{FieldRegistry, core_fields};
147pub use types::{
148 Condition, Expr, Field, FieldDescriptor, FieldType, JoinEdgeKind, JoinExpr, Operator,
149 PipelineQuery, PipelineStage, Query as QueryAST, RegexFlags, RegexValue, Span, Value,
150};
151pub use validator::{ContradictionWarning, Validator};
152
153// Pipeline/aggregation results
154pub use pipeline::{AggregationResult, CountResult, GroupByResult, StatsResult, TopResult};
155
156// Pipeline execution
157pub use executor::execute_pipeline_stage;
158
159// Builder API exports (P2-10)
160pub use builder::{BuildError, ConditionBuilder, QueryBuilder, RegexBuilder};
161
162// CodeGraph-native query results (v6)
163pub use results::{JoinMatch, JoinResults, QueryMatch, QueryOutput, QueryResults};