1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
//! # SQL Query Analyzer
//!
//! Static analysis and LLM-powered optimization for SQL queries.
//!
//! `sql-query-analyzer` is a comprehensive SQL analysis tool that combines
//! fast, deterministic static analysis with optional AI-powered insights. It
//! parses SQL queries, validates them against your database schema, and
//! identifies performance issues, style violations, and security
//! vulnerabilities.
//!
//! # Architecture
//!
//! The analyzer operates in two phases:
//!
//! 1. **Static Analysis** (always runs) - A rule engine executes 18 built-in
//! rules in parallel using [`rayon`]. Rules are categorized as Performance,
//! Style, or Security, each with configurable severity levels.
//!
//! 2. **LLM Analysis** (optional) - When API credentials are provided, queries
//! are sent to OpenAI, Anthropic, or a local Ollama instance for deeper
//! semantic analysis and optimization suggestions.
//!
//! # Quick Start
//!
//! ```bash
//! # Basic static analysis
//! sql-query-analyzer analyze -s schema.sql -q queries.sql
//!
//! # CI/CD integration with SARIF output
//! sql-query-analyzer analyze -s schema.sql -q queries.sql -f sarif > results.sarif
//!
//! # Stream queries from stdin
//! echo "SELECT * FROM users" | sql-query-analyzer analyze -s schema.sql -q -
//!
//! # Enable LLM analysis
//! export LLM_API_KEY="sk-..."
//! sql-query-analyzer analyze -s schema.sql -q queries.sql --provider openai
//! ```
//!
//! # Configuration
//!
//! Configuration is loaded from (in order of precedence):
//!
//! 1. Command-line arguments
//! 2. Environment variables (`LLM_API_KEY`, `LLM_PROVIDER`, etc.)
//! 3. `.sql-analyzer.toml` in current directory
//! 4. `~/.config/sql-analyzer/config.toml`
//!
//! ## Example Configuration
//!
//! ```toml
//! [rules]
//! # Disable specific rules by ID
//! disabled = ["STYLE001", "PERF011"]
//!
//! # Override default severity levels
//! [rules.severity]
//! PERF001 = "error" # Promote to error
//! SCHEMA001 = "info" # Demote to info
//!
//! [llm]
//! provider = "ollama"
//! model = "codellama"
//! ollama_url = "http://localhost:11434"
//!
//! [retry]
//! max_retries = 3
//! initial_delay_ms = 1000
//! ```
//!
//! # Rules
//!
//! ## Performance Rules (PERF001-PERF011)
//!
//! | ID | Name | Description |
//! |----|------|-------------|
//! | PERF001 | Select star without limit | `SELECT *` without `LIMIT` can return unbounded rows |
//! | PERF002 | Leading wildcard | `LIKE '%value'` prevents index usage |
//! | PERF003 | OR instead of IN | Multiple `OR` conditions can be simplified to `IN` |
//! | PERF004 | Large offset | `OFFSET > 1000` causes performance degradation |
//! | PERF005 | Missing join condition | Cartesian product detected |
//! | PERF006 | Distinct with order by | Potentially redundant operations |
//! | PERF007 | Scalar subquery | N+1 query pattern detected |
//! | PERF008 | Function on column | Function calls prevent index usage |
//! | PERF009 | NOT IN with subquery | Can cause unexpected NULL behavior |
//! | PERF010 | UNION without ALL | Unnecessary deduplication overhead |
//! | PERF011 | Select without where | Full table scan on large tables |
//!
//! ## Style Rules (STYLE001-STYLE002)
//!
//! | ID | Name | Description |
//! |----|------|-------------|
//! | STYLE001 | Select star | Explicit column list preferred |
//! | STYLE002 | Missing table alias | Multi-table queries should use aliases |
//!
//! ## Security Rules (SEC001-SEC002)
//!
//! | ID | Name | Description |
//! |----|------|-------------|
//! | SEC001 | Missing WHERE in UPDATE | Potentially dangerous bulk update |
//! | SEC002 | Missing WHERE in DELETE | Potentially dangerous bulk delete |
//!
//! ## Schema-Aware Rules (SCHEMA001-SCHEMA003)
//!
//! | ID | Name | Description |
//! |----|------|-------------|
//! | SCHEMA001 | Missing index on filter | WHERE/JOIN column lacks index |
//! | SCHEMA002 | Column not in schema | Referenced column doesn't exist |
//! | SCHEMA003 | Index suggestion | ORDER BY column could benefit from index |
//!
//! # Exit Codes
//!
//! The process exit code reflects the highest severity violation found:
//!
//! - `0` - Success, no issues or only informational messages
//! - `1` - Warnings found
//! - `2` - Errors found
//!
//! # Output Formats
//!
//! - `text` - Human-readable colored output (default)
//! - `json` - Structured JSON for programmatic processing
//! - `yaml` - YAML format for configuration management
//! - `sarif` - SARIF 2.1.0 for CI/CD integration (GitHub, GitLab, etc.)
//!
//! # Modules
//!
//! - [`rules`] - Static analysis rule engine and built-in rules
//! - [`query`] - SQL parsing and query metadata extraction
//! - [`schema`] - Database schema parsing and representation
//! - [`llm`] - LLM provider integrations (OpenAI, Anthropic, Ollama)
//! - [`config`] - Configuration loading and validation
//! - [`output`] - Result formatting for various output formats
//! - [`cache`] - Query parsing cache for performance
//! - [`error`] - Error types and constructors
//! - [`app`] - Application logic for CLI commands
use process;
use Parser;
use main;
use crate::;
async
async