<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Athreya aka Maneshwar</title>
    <description>The latest articles on DEV Community by Athreya aka Maneshwar (@lovestaco).</description>
    <link>https://dev.to/lovestaco</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1002302%2F5233b7df-6ee3-46b2-b8d7-1fafe103e8a3.jpg</url>
      <title>DEV Community: Athreya aka Maneshwar</title>
      <link>https://dev.to/lovestaco</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lovestaco"/>
    <language>en</language>
    <item>
      <title>How SQLite Executes Queries Through Its API Lifecycle</title>
      <dc:creator>Athreya aka Maneshwar</dc:creator>
      <pubDate>Fri, 03 Apr 2026 19:50:31 +0000</pubDate>
      <link>https://dev.to/lovestaco/how-sqlite-executes-queries-through-its-api-lifecycle-3438</link>
      <guid>https://dev.to/lovestaco/how-sqlite-executes-queries-through-its-api-lifecycle-3438</guid>
      <description>&lt;p&gt;&lt;em&gt;Hello, I'm Maneshwar. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;Star Us&lt;/a&gt; to help devs discover the project. Do give it a try and share your feedback for improving the product.&lt;/em&gt;&lt;/p&gt; 

&lt;p&gt;Now that the internal structures and their interconnections are clear, the final piece is understanding how an application actually drives all of this through the SQLite API.&lt;/p&gt;

&lt;p&gt;It starts with a simple call: &lt;code&gt;sqlite3_open&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When this function is invoked successfully, SQLite allocates a &lt;code&gt;sqlite3&lt;/code&gt; object in the application’s memory space. &lt;/p&gt;

&lt;p&gt;At this point, the connection is initialized, but it is still idle, no SQL has been compiled yet, and the &lt;code&gt;pVdbe&lt;/code&gt; list (which holds compiled statements) is empty.&lt;/p&gt;

&lt;h2&gt;
  
  
  From SQL Text to Bytecode
&lt;/h2&gt;

&lt;p&gt;The moment an application prepares a query using &lt;code&gt;sqlite3_prepare&lt;/code&gt;, SQLite translates the SQL text into a compiled representation.&lt;/p&gt;

&lt;p&gt;Internally, this creates a &lt;strong&gt;Vdbe object&lt;/strong&gt;, which is essentially a bytecode program ready to be executed. &lt;/p&gt;

&lt;p&gt;This object is then added to the &lt;code&gt;pVdbe&lt;/code&gt; list inside the &lt;code&gt;sqlite3&lt;/code&gt; connection.&lt;/p&gt;

&lt;p&gt;At this stage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The query is compiled&lt;/li&gt;
&lt;li&gt;No execution has happened yet&lt;/li&gt;
&lt;li&gt;No cursors are open&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s like having a program loaded but not yet run.&lt;/p&gt;

&lt;h2&gt;
  
  
  Binding and Execution
&lt;/h2&gt;

&lt;p&gt;Before execution, the application can inject values into the query using &lt;code&gt;sqlite3_bind_*&lt;/code&gt; functions. &lt;/p&gt;

&lt;p&gt;These bindings replace placeholders in the prepared statement.&lt;/p&gt;

&lt;p&gt;Execution begins when &lt;code&gt;sqlite3_step&lt;/code&gt; is called.&lt;/p&gt;

&lt;p&gt;This is where everything comes alive:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The VDBE starts interpreting bytecode&lt;/li&gt;
&lt;li&gt;Cursors are created dynamically&lt;/li&gt;
&lt;li&gt;Each cursor connects to a B-tree (table or index)&lt;/li&gt;
&lt;li&gt;Data is read, filtered, or modified&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These cursors exist only for the duration of execution—they are not permanent structures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cursor Lifecycle
&lt;/h2&gt;

&lt;p&gt;Cursors are tightly scoped to execution.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Created when the VM starts executing&lt;/li&gt;
&lt;li&gt;Used to traverse B/B+ trees&lt;/li&gt;
&lt;li&gt;Destroyed when execution finishes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the application calls &lt;code&gt;sqlite3_reset&lt;/code&gt;, the statement is reset to its initial state, and any active cursors are closed and cleaned up.&lt;/p&gt;

&lt;p&gt;This ensures that each execution starts fresh, without leftover state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cleaning Up Resources
&lt;/h2&gt;

&lt;p&gt;Once a prepared statement is no longer needed, the application calls &lt;code&gt;sqlite3_finalize&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This step is crucial—it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Destroys the Vdbe object&lt;/li&gt;
&lt;li&gt;Frees all associated resources&lt;/li&gt;
&lt;li&gt;Removes it from the connection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Only after all prepared statements are finalized should the application close the connection using &lt;code&gt;sqlite3_close&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When the connection is closed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;sqlite3&lt;/code&gt; object is destroyed&lt;/li&gt;
&lt;li&gt;All associated handles become invalid&lt;/li&gt;
&lt;li&gt;The session is fully terminated&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Complete Flow in One View
&lt;/h2&gt;

&lt;p&gt;From start to finish, the lifecycle looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open connection → &lt;code&gt;sqlite3_open&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Prepare query → &lt;code&gt;sqlite3_prepare&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Bind parameters → &lt;code&gt;sqlite3_bind_*&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Execute → &lt;code&gt;sqlite3_step&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Reset (optional) → &lt;code&gt;sqlite3_reset&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Finalize → &lt;code&gt;sqlite3_finalize&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Close connection → &lt;code&gt;sqlite3_close&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Closing Thoughts
&lt;/h2&gt;

&lt;p&gt;What looks like a handful of API calls from the outside is actually orchestrating a deep chain of internal operations—compilation, cursor management, B-tree traversal, and disk interaction.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;sqlite3&lt;/code&gt; object sits at the center of it all, acting as the control hub that binds together:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prepared statements (Vdbe)&lt;/li&gt;
&lt;li&gt;Execution flow (VM)&lt;/li&gt;
&lt;li&gt;Storage (B-tree + Pager)&lt;/li&gt;
&lt;li&gt;And application interaction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you see this lifecycle clearly, SQLite stops feeling magical—it becomes predictable, structured, and surprisingly elegant.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzvpkxm9mga1pweneahx.png" alt="git-lrc" width="800" height="109"&gt;&lt;/a&gt; &lt;br&gt;
 *AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production. &lt;/p&gt;

&lt;p&gt;git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.* &lt;/p&gt;

&lt;p&gt;Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use. &lt;/p&gt;

&lt;p&gt;⭐ Star it on GitHub: &lt;br&gt;
 &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/HexmosTech" rel="noopener noreferrer"&gt;
        HexmosTech
      &lt;/a&gt; / &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;
        git-lrc
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Free, Unlimited AI Code Reviews That Run on Commit
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;p&gt;| &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.da.md" rel="noopener noreferrer"&gt;🇩🇰 Dansk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.es.md" rel="noopener noreferrer"&gt;🇪🇸 Español&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fa.md" rel="noopener noreferrer"&gt;🇮🇷 Farsi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fi.md" rel="noopener noreferrer"&gt;🇫🇮 Suomi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ja.md" rel="noopener noreferrer"&gt;🇯🇵 日本語&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.nn.md" rel="noopener noreferrer"&gt;🇳🇴 Norsk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.pt.md" rel="noopener noreferrer"&gt;🇵🇹 Português&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ru.md" rel="noopener noreferrer"&gt;🇷🇺 Русский&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.sq.md" rel="noopener noreferrer"&gt;🇦🇱 Shqip&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.zh.md" rel="noopener noreferrer"&gt;🇨🇳 中文&lt;/a&gt; |&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;img width="60" alt="git-lrc logo" src="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;git-lrc&lt;/h1&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Free, Unlimited AI Code Reviews That Run on Commit&lt;/h2&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
&lt;p&gt;&lt;a href="https://www.producthunt.com/products/git-lrc?embed=true&amp;amp;utm_source=badge-top-post-badge&amp;amp;utm_medium=badge&amp;amp;utm_campaign=badge-git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt" width="200" src="https://camo.githubusercontent.com/87bf2d4283c1e0aa99e254bd17fefb1c67c0c0d39300043a243a4aa633b6cecc/68747470733a2f2f6170692e70726f6475637468756e742e636f6d2f776964676574732f656d6265642d696d6167652f76312f746f702d706f73742d62616467652e7376673f706f73745f69643d31303739323632267468656d653d6c6967687426706572696f643d6461696c7926743d31373731373439313730383638"&gt;&lt;/a&gt;
 &lt;/p&gt;
&lt;br&gt;
&lt;a href="https://discord.gg/sGdnKwB3qq" rel="nofollow noopener noreferrer"&gt;
  &lt;img alt="Discord Community" src="https://camo.githubusercontent.com/b8f979318aaabc8dec512b9d4e6e2a12431fba3c8a3b8738e1a97a0722d4e4bf/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f446973636f72642d436f6d6d756e6974792d3538363546323f6c6f676f3d646973636f7264266c6162656c436f6c6f723d7768697465"&gt;
&lt;/a&gt; &lt;a href="https://goreportcard.com/report/github.com/HexmosTech/git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Go Report Card" src="https://camo.githubusercontent.com/e74c0651c3ee9165a2ed01cb0f6842c494029960df30eb9c24cf622d3d21bf46/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f4865786d6f73546563682f6769742d6c7263"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml" rel="noopener noreferrer"&gt;&lt;img alt="gitleaks.yml" title="gitleaks.yml: Secret scanning workflow" src="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml" rel="noopener noreferrer"&gt;&lt;img alt="osv-scanner.yml" title="osv-scanner.yml: Dependency vulnerability scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml" rel="noopener noreferrer"&gt;&lt;img alt="govulncheck.yml" title="govulncheck.yml: Go vulnerability check" src="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml" rel="noopener noreferrer"&gt;&lt;img alt="semgrep.yml" title="semgrep.yml: Static analysis security scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml/badge.svg"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer" href="https://github.com/HexmosTech/git-lrc/./gfx/dependabot-enabled.svg"&gt;&lt;img alt="dependabot-enabled" title="dependabot-enabled: Automated dependency updates are enabled" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FHexmosTech%2Fgit-lrc%2FHEAD%2F.%2Fgfx%2Fdependabot-enabled.svg"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;

&lt;p&gt;AI agents write code fast. They also &lt;em&gt;silently remove logic&lt;/em&gt;, change behavior, and introduce bugs -- without telling you. You often find out in production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git-lrc&lt;/code&gt; fixes this.&lt;/strong&gt; It hooks into &lt;code&gt;git commit&lt;/code&gt; and reviews every diff &lt;em&gt;before&lt;/em&gt; it lands. 60-second setup. Completely free.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;See It In Action&lt;/h2&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See git-lrc catch serious security issues such as leaked credentials, expensive cloud
operations, and sensitive material in log statements&lt;/p&gt;
&lt;/blockquote&gt;

  
    
    

    &lt;span class="m-1"&gt;git-lrc-intro-60s.mp4&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;🤖 &lt;strong&gt;AI agents silently break things.&lt;/strong&gt; Code removed. Logic changed. Edge cases gone. You won't notice until production.&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;Catch it before it ships.&lt;/strong&gt; AI-powered inline comments show you &lt;em&gt;exactly&lt;/em&gt; what changed and what looks wrong.&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Build a&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>webdev</category>
      <category>programming</category>
      <category>database</category>
      <category>architecture</category>
    </item>
    <item>
      <title>How SQLite Internals Connect Into One Unified System</title>
      <dc:creator>Athreya aka Maneshwar</dc:creator>
      <pubDate>Wed, 01 Apr 2026 17:32:36 +0000</pubDate>
      <link>https://dev.to/lovestaco/how-sqlite-internals-connect-into-one-unified-system-e37</link>
      <guid>https://dev.to/lovestaco/how-sqlite-internals-connect-into-one-unified-system-e37</guid>
      <description>&lt;p&gt;&lt;em&gt;Hello, I'm Maneshwar. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;Star Us&lt;/a&gt; to help devs discover the project. Do give it a try and share your feedback for improving the product.&lt;/em&gt;&lt;/p&gt; 

&lt;p&gt;In the previous section, we explored individual pieces of SQLite’s internal architecture—the &lt;code&gt;sqlite3&lt;/code&gt; structure, schema objects, tables, indexes, and execution engine. &lt;/p&gt;

&lt;p&gt;Now, it’s time to zoom out and see how all of these components actually interact in a real system.&lt;/p&gt;

&lt;p&gt;This is where things start to feel less like isolated structures and more like a living system.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Big Picture: Application ↔ SQLite
&lt;/h2&gt;

&lt;p&gt;At the highest level, an application interacts with SQLite through two primary handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;sqlite3*&lt;/code&gt; → Represents a database connection&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sqlite3_stmt*&lt;/code&gt; → Represents a compiled SQL statement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every API call, whether it’s preparing a query, executing it, or fetching results—flows through these two interfaces.&lt;/p&gt;

&lt;p&gt;SQLite doesn’t just passively execute queries either. &lt;/p&gt;

&lt;p&gt;It allows applications to register custom callback functions. &lt;/p&gt;

&lt;p&gt;When needed, SQLite invokes these callbacks, enabling logic to run inside the application’s space. &lt;/p&gt;

&lt;p&gt;This is how features like custom functions, collations, or hooks are implemented.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff12ugix56lpfxh2qcdkk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff12ugix56lpfxh2qcdkk.png" alt="Figure 9.4: Integration of control data structures" width="776" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Multiple Connections, Multiple Databases
&lt;/h2&gt;

&lt;p&gt;One subtle but powerful feature of SQLite is that an application is not limited to a single connection.&lt;/p&gt;

&lt;p&gt;An application can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open multiple &lt;code&gt;sqlite3*&lt;/code&gt; connections&lt;/li&gt;
&lt;li&gt;Connect each one to different databases—or even the same database&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Within a single connection, multiple databases can coexist:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Main database&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Temporary database&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Attached databases&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these is represented internally by an entry in the &lt;code&gt;Db&lt;/code&gt; array.&lt;/p&gt;

&lt;p&gt;What’s important here is that each database is not just a logical entity—it has its own underlying storage machinery.&lt;/p&gt;

&lt;h2&gt;
  
  
  B-Tree and Pager: The Storage Backbone
&lt;/h2&gt;

&lt;p&gt;Every database is accessed through a &lt;strong&gt;B-tree (or B+ tree)&lt;/strong&gt; structure. &lt;/p&gt;

&lt;p&gt;This is the core storage engine of SQLite.&lt;/p&gt;

&lt;p&gt;Each database connection uses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A dedicated &lt;strong&gt;Btree object&lt;/strong&gt; → Handles structural access to data&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;Pager object&lt;/strong&gt; → Manages disk-level concerns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Pager is where things get very real. It is responsible for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tracking database file state&lt;/li&gt;
&lt;li&gt;Managing the journal (for transactions and rollback)&lt;/li&gt;
&lt;li&gt;Handling locks&lt;/li&gt;
&lt;li&gt;Maintaining the page cache&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In shared cache mode, multiple B-tree instances can reuse the same Pager through a shared structure (&lt;code&gt;BtShared&lt;/code&gt;). &lt;/p&gt;

&lt;p&gt;This allows efficient memory usage when multiple connections access the same database file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Transactions: Controlled and Isolated
&lt;/h2&gt;

&lt;p&gt;Even though a connection may have multiple databases attached, SQLite enforces an important rule:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A single &lt;code&gt;sqlite3&lt;/code&gt; connection can have only one active transaction at a time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, that transaction can span multiple databases within the same connection.&lt;/p&gt;

&lt;p&gt;SQLite dynamically starts transactions on individual databases depending on what the SQL statement requires. &lt;/p&gt;

&lt;p&gt;This keeps operations efficient while still ensuring consistency.&lt;/p&gt;

&lt;h2&gt;
  
  
  From SQL to Execution: The Role of &lt;code&gt;sqlite3_stmt&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Every SQL statement you write is compiled into a bytecode program.&lt;/p&gt;

&lt;p&gt;That compiled form is represented by a &lt;code&gt;sqlite3_stmt*&lt;/code&gt;, backed internally by a &lt;strong&gt;VDBE (Virtual Database Engine)&lt;/strong&gt; program.&lt;/p&gt;

&lt;p&gt;When executed:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The VDBE interprets the bytecode&lt;/li&gt;
&lt;li&gt;It opens &lt;strong&gt;cursors&lt;/strong&gt; to access data&lt;/li&gt;
&lt;li&gt;It performs operations like scan, insert, update, or delete&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Cursors: Navigating the Data
&lt;/h2&gt;

&lt;p&gt;Cursors are the bridge between execution and storage.&lt;/p&gt;

&lt;p&gt;Each SQL statement maintains a set of &lt;strong&gt;VdbeCursor&lt;/strong&gt; objects. &lt;/p&gt;

&lt;p&gt;These are runtime constructs used by the VM to interact with data.&lt;/p&gt;

&lt;p&gt;Here’s how they work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;VdbeCursor&lt;/strong&gt; maps to a &lt;strong&gt;BtCursor&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;BtCursor&lt;/strong&gt; operates on a single B-tree (table or index)&lt;/li&gt;
&lt;li&gt;It allows iteration over records&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This design enables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiple cursors on the same table or index&lt;/li&gt;
&lt;li&gt;Independent traversal without interference&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So even within a single query, SQLite can efficiently scan, filter, and join data using multiple cursors simultaneously.&lt;/p&gt;

&lt;h2&gt;
  
  
  Putting the Flow Together
&lt;/h2&gt;

&lt;p&gt;Let’s trace a typical execution flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The application prepares a query → gets a &lt;code&gt;sqlite3_stmt*&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;SQLite compiles it into VDBE bytecode&lt;/li&gt;
&lt;li&gt;On execution:

&lt;ul&gt;
&lt;li&gt;VDBE opens cursors&lt;/li&gt;
&lt;li&gt;Cursors access B-tree structures&lt;/li&gt;
&lt;li&gt;B-tree interacts with Pager&lt;/li&gt;
&lt;li&gt;Pager reads/writes pages from disk&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Results flow back up to the application&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All of this is coordinated through the &lt;code&gt;sqlite3&lt;/code&gt; connection object.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzvpkxm9mga1pweneahx.png" alt="git-lrc" width="800" height="109"&gt;&lt;/a&gt; &lt;br&gt;
 *AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production. &lt;/p&gt;

&lt;p&gt;git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.* &lt;/p&gt;

&lt;p&gt;Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use. &lt;/p&gt;

&lt;p&gt;⭐ Star it on GitHub: &lt;br&gt;
 &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/HexmosTech" rel="noopener noreferrer"&gt;
        HexmosTech
      &lt;/a&gt; / &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;
        git-lrc
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Free, Unlimited AI Code Reviews That Run on Commit
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;p&gt;| &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.da.md" rel="noopener noreferrer"&gt;🇩🇰 Dansk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.es.md" rel="noopener noreferrer"&gt;🇪🇸 Español&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fa.md" rel="noopener noreferrer"&gt;🇮🇷 Farsi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fi.md" rel="noopener noreferrer"&gt;🇫🇮 Suomi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ja.md" rel="noopener noreferrer"&gt;🇯🇵 日本語&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.nn.md" rel="noopener noreferrer"&gt;🇳🇴 Norsk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.pt.md" rel="noopener noreferrer"&gt;🇵🇹 Português&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ru.md" rel="noopener noreferrer"&gt;🇷🇺 Русский&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.sq.md" rel="noopener noreferrer"&gt;🇦🇱 Shqip&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.zh.md" rel="noopener noreferrer"&gt;🇨🇳 中文&lt;/a&gt; |&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;img width="60" alt="git-lrc logo" src="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;git-lrc&lt;/h1&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Free, Unlimited AI Code Reviews That Run on Commit&lt;/h2&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
&lt;p&gt;&lt;a href="https://www.producthunt.com/products/git-lrc?embed=true&amp;amp;utm_source=badge-top-post-badge&amp;amp;utm_medium=badge&amp;amp;utm_campaign=badge-git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt" width="200" src="https://camo.githubusercontent.com/87bf2d4283c1e0aa99e254bd17fefb1c67c0c0d39300043a243a4aa633b6cecc/68747470733a2f2f6170692e70726f6475637468756e742e636f6d2f776964676574732f656d6265642d696d6167652f76312f746f702d706f73742d62616467652e7376673f706f73745f69643d31303739323632267468656d653d6c6967687426706572696f643d6461696c7926743d31373731373439313730383638"&gt;&lt;/a&gt;
 &lt;/p&gt;
&lt;br&gt;
&lt;a href="https://goreportcard.com/report/github.com/HexmosTech/git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Go Report Card" src="https://camo.githubusercontent.com/e74c0651c3ee9165a2ed01cb0f6842c494029960df30eb9c24cf622d3d21bf46/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f4865786d6f73546563682f6769742d6c7263"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml" rel="noopener noreferrer"&gt;&lt;img alt="gitleaks.yml" title="gitleaks.yml: Secret scanning workflow" src="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml" rel="noopener noreferrer"&gt;&lt;img alt="osv-scanner.yml" title="osv-scanner.yml: Dependency vulnerability scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml" rel="noopener noreferrer"&gt;&lt;img alt="govulncheck.yml" title="govulncheck.yml: Go vulnerability check" src="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml" rel="noopener noreferrer"&gt;&lt;img alt="semgrep.yml" title="semgrep.yml: Static analysis security scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml/badge.svg"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer" href="https://github.com/HexmosTech/git-lrc/./gfx/dependabot-enabled.svg"&gt;&lt;img alt="dependabot-enabled" title="dependabot-enabled: Automated dependency updates are enabled" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FHexmosTech%2Fgit-lrc%2FHEAD%2F.%2Fgfx%2Fdependabot-enabled.svg"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;

&lt;p&gt;AI agents write code fast. They also &lt;em&gt;silently remove logic&lt;/em&gt;, change behavior, and introduce bugs -- without telling you. You often find out in production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git-lrc&lt;/code&gt; fixes this.&lt;/strong&gt; It hooks into &lt;code&gt;git commit&lt;/code&gt; and reviews every diff &lt;em&gt;before&lt;/em&gt; it lands. 60-second setup. Completely free.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;See It In Action&lt;/h2&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See git-lrc catch serious security issues such as leaked credentials, expensive cloud
operations, and sensitive material in log statements&lt;/p&gt;
&lt;/blockquote&gt;

  
    
    

    &lt;span class="m-1"&gt;git-lrc-intro-60s.mp4&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;🤖 &lt;strong&gt;AI agents silently break things.&lt;/strong&gt; Code removed. Logic changed. Edge cases gone. You won't notice until production.&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;Catch it before it ships.&lt;/strong&gt; AI-powered inline comments show you &lt;em&gt;exactly&lt;/em&gt; what changed and what looks wrong.&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Build a&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>webdev</category>
      <category>programming</category>
      <category>database</category>
      <category>architecture</category>
    </item>
    <item>
      <title>SQLite Interface Handler: Understanding the sqlite3 Core Structure</title>
      <dc:creator>Athreya aka Maneshwar</dc:creator>
      <pubDate>Tue, 31 Mar 2026 18:39:45 +0000</pubDate>
      <link>https://dev.to/lovestaco/sqlite-interface-handler-understanding-the-sqlite3-core-structure-2976</link>
      <guid>https://dev.to/lovestaco/sqlite-interface-handler-understanding-the-sqlite3-core-structure-2976</guid>
      <description>&lt;p&gt;&lt;em&gt;Hello, I'm Maneshwar. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;Star Us&lt;/a&gt; to help devs discover the project. Do give it a try and share your feedback for improving the product.&lt;/em&gt;&lt;/p&gt; 

&lt;p&gt;In earlier discussions, we explored several internal control data structures in isolation, each serving a specific purpose inside SQLite. &lt;/p&gt;

&lt;p&gt;However, understanding SQLite in fragments can feel like looking at puzzle pieces without seeing the full picture.&lt;/p&gt;

&lt;p&gt;This chapter ties everything together.&lt;/p&gt;

&lt;p&gt;At the center of SQLite’s architecture lies the &lt;code&gt;sqlite3&lt;/code&gt; structure, which acts as the main interface between the application and the database engine. &lt;/p&gt;

&lt;p&gt;By studying this structure and its relationships with other components, you get a complete, end-to-end understanding of how SQLite organizes and manages its internal state.&lt;/p&gt;

&lt;h2&gt;
  
  
  The &lt;code&gt;sqlite3&lt;/code&gt; Structure
&lt;/h2&gt;

&lt;p&gt;Whenever an application calls the &lt;code&gt;sqlite3_open&lt;/code&gt; API, something important happens behind the scenes. &lt;/p&gt;

&lt;p&gt;SQLite initializes a new database connection (also called a session) and prepares access to the database file.&lt;/p&gt;

&lt;p&gt;This process results in the creation of a &lt;code&gt;sqlite3&lt;/code&gt; object, and the application receives a pointer to it.&lt;/p&gt;

&lt;p&gt;That pointer is not just a reference—it represents the entire connection. &lt;/p&gt;

&lt;p&gt;Every subsequent database operation performed by the application goes through this handle, until the connection is closed using &lt;code&gt;sqlite3_close&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It’s important to note that the application should never directly modify the internal fields of this object. &lt;/p&gt;

&lt;p&gt;It is strictly managed by SQLite itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Internal Composition of &lt;code&gt;sqlite3&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;One of the most important members of the &lt;code&gt;sqlite3&lt;/code&gt; structure is &lt;code&gt;aDb&lt;/code&gt;, which is an array of &lt;code&gt;Db&lt;/code&gt; objects.&lt;/p&gt;

&lt;p&gt;Each &lt;code&gt;Db&lt;/code&gt; object represents a database associated with the connection.&lt;/p&gt;

&lt;p&gt;Typically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;aDb[0]&lt;/code&gt; → Main database&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;aDb[1]&lt;/code&gt; → Temporary database&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Additional entries appear when databases are attached dynamically during runtime.&lt;/p&gt;

&lt;p&gt;Internally, SQLite does not refer to databases by name. Instead, it uses their index within the &lt;code&gt;aDb&lt;/code&gt; array. This mapping from name to index is resolved during query compilation.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;nDb&lt;/code&gt; variable keeps track of how many databases are currently active in the connection.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fehgkrzzrqy2y8hqotoi7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fehgkrzzrqy2y8hqotoi7.png" alt="Figure 9.1: Components of sqli te3 objects" width="612" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The &lt;code&gt;Db&lt;/code&gt; Structure
&lt;/h2&gt;

&lt;p&gt;Each entry in the &lt;code&gt;aDb&lt;/code&gt; array is a &lt;code&gt;Db&lt;/code&gt; object, and it contains essential metadata about a database.&lt;/p&gt;

&lt;p&gt;Key components include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;zName&lt;/strong&gt; → Name of the database&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pBt&lt;/strong&gt; → Pointer to the B-tree structure (core storage engine)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;inTrans&lt;/strong&gt; → Current transaction state&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pSchema&lt;/strong&gt; → Pointer to schema information&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The schema itself is a rich structure containing multiple hash tables and metadata used for query processing and validation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Schema Organization
&lt;/h2&gt;

&lt;p&gt;The schema is where SQLite keeps track of all structural elements of a database.&lt;/p&gt;

&lt;p&gt;Important members include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;schema_cookie&lt;/strong&gt; → Version of the schema&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;cache_size&lt;/strong&gt; → Page cache configuration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;tblHash&lt;/strong&gt; → All tables and views&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;idxHash&lt;/strong&gt; → All indexes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;trigHash&lt;/strong&gt; → All triggers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;fkeyHash&lt;/strong&gt; → All foreign keys&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pSeqTab&lt;/strong&gt; → Pointer to the &lt;code&gt;sqlite_sequence&lt;/code&gt; table&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When a database is opened, SQLite parses its schema and populates these hash tables. &lt;/p&gt;

&lt;p&gt;This allows fast lookup and efficient query planning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table Representation in Memory
&lt;/h2&gt;

&lt;p&gt;Each SQL table is represented internally as a &lt;code&gt;Table&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;This object contains an array called &lt;code&gt;aCol&lt;/code&gt;, which holds all column definitions. Each column is described by a &lt;code&gt;Column&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpo6nrjise8nan0aze5fn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpo6nrjise8nan0aze5fn.png" alt="Figure 9.2: Components of Table objects" width="713" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Index Representation
&lt;/h2&gt;

&lt;p&gt;Indexes are also represented as structured objects in memory.&lt;/p&gt;

&lt;p&gt;An &lt;code&gt;Index&lt;/code&gt; object contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;aiColumn&lt;/strong&gt; → Array mapping index columns to table columns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;tnum&lt;/strong&gt; → Page number where the index root resides&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This allows SQLite to efficiently locate and traverse indexed data during query execution.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ucl40bpsefl6oyj781g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ucl40bpsefl6oyj781g.png" alt="Figure 9.3: Components of Index objects" width="648" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Runtime State and Execution
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;sqlite3&lt;/code&gt; structure also keeps track of runtime execution details:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;lastRowid&lt;/strong&gt; → The most recent row ID generated by an INSERT&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;errCode / pErr&lt;/strong&gt; → Error tracking&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;flags&lt;/strong&gt; → Current runtime state&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pVdbe&lt;/strong&gt; → Collection of compiled SQL statements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each compiled SQL statement is represented as a VDBE (Virtual Database Engine) program.&lt;/p&gt;

&lt;p&gt;These are essentially bytecode instructions executed by SQLite’s internal engine.&lt;/p&gt;

&lt;p&gt;Applications interact with these compiled statements using &lt;code&gt;sqlite3_stmt&lt;/code&gt; pointers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Putting It All Together
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;sqlite3&lt;/code&gt; structure is not just a container—it is the central hub that connects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Database files (&lt;code&gt;Db&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Storage engine (&lt;code&gt;B-tree&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Schema metadata&lt;/li&gt;
&lt;li&gt;Tables and indexes&lt;/li&gt;
&lt;li&gt;Query execution engine (VDBE)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every SQL query flows through this structure. &lt;/p&gt;

&lt;p&gt;From parsing and compilation to execution and result retrieval, everything is orchestrated through &lt;code&gt;sqlite3&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzvpkxm9mga1pweneahx.png" alt="git-lrc" width="800" height="109"&gt;&lt;/a&gt; &lt;br&gt;
 *AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production. &lt;/p&gt;

&lt;p&gt;git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.* &lt;/p&gt;

&lt;p&gt;Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use. &lt;/p&gt;

&lt;p&gt;⭐ Star it on GitHub: &lt;br&gt;
 &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/HexmosTech" rel="noopener noreferrer"&gt;
        HexmosTech
      &lt;/a&gt; / &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;
        git-lrc
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Free, Unlimited AI Code Reviews That Run on Commit
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;p&gt;| &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.da.md" rel="noopener noreferrer"&gt;🇩🇰 Dansk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.es.md" rel="noopener noreferrer"&gt;🇪🇸 Español&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fa.md" rel="noopener noreferrer"&gt;🇮🇷 Farsi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fi.md" rel="noopener noreferrer"&gt;🇫🇮 Suomi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ja.md" rel="noopener noreferrer"&gt;🇯🇵 日本語&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.nn.md" rel="noopener noreferrer"&gt;🇳🇴 Norsk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.pt.md" rel="noopener noreferrer"&gt;🇵🇹 Português&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ru.md" rel="noopener noreferrer"&gt;🇷🇺 Русский&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.sq.md" rel="noopener noreferrer"&gt;🇦🇱 Shqip&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.zh.md" rel="noopener noreferrer"&gt;🇨🇳 中文&lt;/a&gt; |&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;img width="60" alt="git-lrc logo" src="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;git-lrc&lt;/h1&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Free, Unlimited AI Code Reviews That Run on Commit&lt;/h2&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
&lt;p&gt;&lt;a href="https://www.producthunt.com/products/git-lrc?embed=true&amp;amp;utm_source=badge-top-post-badge&amp;amp;utm_medium=badge&amp;amp;utm_campaign=badge-git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt" width="200" src="https://camo.githubusercontent.com/87bf2d4283c1e0aa99e254bd17fefb1c67c0c0d39300043a243a4aa633b6cecc/68747470733a2f2f6170692e70726f6475637468756e742e636f6d2f776964676574732f656d6265642d696d6167652f76312f746f702d706f73742d62616467652e7376673f706f73745f69643d31303739323632267468656d653d6c6967687426706572696f643d6461696c7926743d31373731373439313730383638"&gt;&lt;/a&gt;
 &lt;/p&gt;
&lt;br&gt;
&lt;a href="https://goreportcard.com/report/github.com/HexmosTech/git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Go Report Card" src="https://camo.githubusercontent.com/e74c0651c3ee9165a2ed01cb0f6842c494029960df30eb9c24cf622d3d21bf46/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f4865786d6f73546563682f6769742d6c7263"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml" rel="noopener noreferrer"&gt;&lt;img alt="gitleaks.yml" title="gitleaks.yml: Secret scanning workflow" src="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml" rel="noopener noreferrer"&gt;&lt;img alt="osv-scanner.yml" title="osv-scanner.yml: Dependency vulnerability scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml" rel="noopener noreferrer"&gt;&lt;img alt="govulncheck.yml" title="govulncheck.yml: Go vulnerability check" src="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml" rel="noopener noreferrer"&gt;&lt;img alt="semgrep.yml" title="semgrep.yml: Static analysis security scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml/badge.svg"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer" href="https://github.com/HexmosTech/git-lrc/./gfx/dependabot-enabled.svg"&gt;&lt;img alt="dependabot-enabled" title="dependabot-enabled: Automated dependency updates are enabled" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FHexmosTech%2Fgit-lrc%2FHEAD%2F.%2Fgfx%2Fdependabot-enabled.svg"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;

&lt;p&gt;AI agents write code fast. They also &lt;em&gt;silently remove logic&lt;/em&gt;, change behavior, and introduce bugs -- without telling you. You often find out in production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git-lrc&lt;/code&gt; fixes this.&lt;/strong&gt; It hooks into &lt;code&gt;git commit&lt;/code&gt; and reviews every diff &lt;em&gt;before&lt;/em&gt; it lands. 60-second setup. Completely free.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;See It In Action&lt;/h2&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See git-lrc catch serious security issues such as leaked credentials, expensive cloud
operations, and sensitive material in log statements&lt;/p&gt;
&lt;/blockquote&gt;

  
    
    

    &lt;span class="m-1"&gt;git-lrc-intro-60s.mp4&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;🤖 &lt;strong&gt;AI agents silently break things.&lt;/strong&gt; Code removed. Logic changed. Edge cases gone. You won't notice until production.&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;Catch it before it ships.&lt;/strong&gt; AI-powered inline comments show you &lt;em&gt;exactly&lt;/em&gt; what changed and what looks wrong.&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Build a&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>database</category>
      <category>webdev</category>
      <category>programming</category>
      <category>architecture</category>
    </item>
    <item>
      <title>From Queries to Bytecode: The Final Pieces of SQLite’s Frontend</title>
      <dc:creator>Athreya aka Maneshwar</dc:creator>
      <pubDate>Sat, 28 Mar 2026 17:50:23 +0000</pubDate>
      <link>https://dev.to/lovestaco/from-queries-to-bytecode-the-final-pieces-of-sqlites-frontend-2ejm</link>
      <guid>https://dev.to/lovestaco/from-queries-to-bytecode-the-final-pieces-of-sqlites-frontend-2ejm</guid>
      <description>&lt;p&gt;&lt;em&gt;Hello, I'm Maneshwar. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;Star Us&lt;/a&gt; to help devs discover the project. Do give it a try and share your feedback for improving the product.&lt;/em&gt;&lt;/p&gt; 

&lt;p&gt;In the previous part, you saw how SQLite selects indexes and balances filtering with sorting. &lt;/p&gt;

&lt;p&gt;Now we move into another important category of queries.&lt;/p&gt;

&lt;p&gt;Aggregation and subqueries.&lt;/p&gt;

&lt;p&gt;These introduce new challenges because SQLite is no longer just filtering rows. &lt;/p&gt;

&lt;p&gt;It is grouping, transforming, and sometimes restructuring queries entirely.&lt;/p&gt;

&lt;h2&gt;
  
  
  How SQLite Executes GROUP BY
&lt;/h2&gt;

&lt;p&gt;When you use a GROUP BY clause, SQLite introduces a special internal structure called an &lt;strong&gt;aggregator&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This is essentially a temporary table that stores:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;key&lt;/strong&gt; → formed by GROUP BY columns&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;value&lt;/strong&gt; → aggregate data like COUNT, SUM, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt; &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;SQLite processes this in two phases.&lt;/p&gt;

&lt;p&gt;First, it scans rows and builds groups.&lt;/p&gt;

&lt;p&gt;Then, it produces the final results.&lt;/p&gt;

&lt;p&gt;The execution pattern looks like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;where-begin  
    compute group-by key  
    focus on the group-by key  
    update aggregate terms  
where-end  
foreach group-by  
    compute result-set  
    send result to caller  
end-foreach
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;During the first phase, SQLite keeps updating aggregate values for each group.&lt;/p&gt;

&lt;p&gt;During the second phase, it outputs the final computed results for each group &lt;/p&gt;

&lt;p&gt;This approach ensures that rows are grouped efficiently without repeatedly scanning the same data.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Problem with Subqueries in FROM
&lt;/h2&gt;

&lt;p&gt;Now consider queries that use subqueries inside the FROM clause.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The default way to execute this is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run the inner query&lt;/li&gt;
&lt;li&gt;Store results in a temporary table&lt;/li&gt;
&lt;li&gt;Run the outer query on that table&lt;/li&gt;
&lt;li&gt;Delete the temporary table&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This approach has a major drawback.&lt;/p&gt;

&lt;p&gt;The temporary table has &lt;strong&gt;no indexes&lt;/strong&gt;, so any filtering or joining done by the outer query becomes inefficient. &lt;/p&gt;

&lt;p&gt;It also requires scanning data multiple times.&lt;/p&gt;
&lt;h2&gt;
  
  
  Subquery Flattening: A Smarter Approach
&lt;/h2&gt;

&lt;p&gt;To avoid this overhead, SQLite uses an optimization called &lt;strong&gt;subquery flattening&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of executing the subquery separately, SQLite merges it into the outer query.&lt;/p&gt;

&lt;p&gt;The previous example becomes:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now the query can be executed in a single pass over the table.&lt;/p&gt;

&lt;p&gt;This has two major benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Eliminates temporary tables&lt;/li&gt;
&lt;li&gt;Allows indexes on the base table to be used&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This significantly improves performance &lt;/p&gt;
&lt;h2&gt;
  
  
  When Flattening Is Allowed
&lt;/h2&gt;

&lt;p&gt;Flattening is not always possible.&lt;/p&gt;

&lt;p&gt;SQLite applies this optimization only when a strict set of conditions is satisfied.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The subquery and the outer query do not both use aggregates.
&lt;/li&gt;
&lt;li&gt;The subquery is not an aggregate or the outer query is not a join.
&lt;/li&gt;
&lt;li&gt;The subquery is not the right operand of a left outer join.
&lt;/li&gt;
&lt;li&gt;The subquery is not DISTINCT or the outer query is not a join.
&lt;/li&gt;
&lt;li&gt;The subquery is not DISTINCT or the outer query does not use aggregates.&lt;/li&gt;
&lt;li&gt;The subquery does not use aggregates or the outer query is not DISTINCT.&lt;/li&gt;
&lt;li&gt;The subquery has a FROM clause.
&lt;/li&gt;
&lt;li&gt;The subquery does not use LIMIT or the outer query is not a join.
&lt;/li&gt;
&lt;li&gt;The subquery does not use LIMIT or the outer query does not use aggregates.
&lt;/li&gt;
&lt;li&gt;The subquery does not use aggregates or the outer query does not use LIMIT.
&lt;/li&gt;
&lt;li&gt;The subquery and the outer query do not both have ORDER BY clauses.
&lt;/li&gt;
&lt;li&gt;The subquery and outer query do not both use LIMIT.
&lt;/li&gt;
&lt;li&gt;The subquery does not use OFFSET.&lt;/li&gt;
&lt;li&gt;The outer query is not part of a compound select or the subquery does not have both an  ORDER BY and a LIMIT clause&lt;/li&gt;
&lt;li&gt;The outer query is not an aggregate or the subquery does not contain ORDER BY&lt;/li&gt;
&lt;li&gt;The sub-query is not a compound select, or it is a UNION ALL compound clause made up  entirely of non-aggregate queries, and the parent query:
• is not itself part of a compound select,
• is not an aggregate or DISTINCT query, and
• has no other tables or sub-selects in the FROM clause.  The parent and sub-query may contain WHERE clauses. 
Subject to rules (11), (12) and (13),  they may also contain ORDER BY, LIMIT and OFFSET clauses.&lt;/li&gt;
&lt;li&gt;If the sub-query is a compound select, then all terms of the ORDER by clause of the parent  must be simple references to columns of the sub-query.&lt;/li&gt;
&lt;li&gt;The subquery does not use LIMIT or the outer query does not have a WHERE clause&lt;/li&gt;
&lt;li&gt;If the sub-query is a compound select, then it must not use an ORDER BY clause.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Query flattening is an important optimization when views are used because each use of a view  is translated into a su bquery.&lt;/p&gt;
&lt;h2&gt;
  
  
  Fast MIN and MAX Queries
&lt;/h2&gt;

&lt;p&gt;Aggregation is not always expensive.&lt;/p&gt;

&lt;p&gt;SQLite has a very efficient optimization for queries like:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;MIN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;MAX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If there is no index on the column, SQLite must scan the entire table.&lt;/p&gt;

&lt;p&gt;But if an index exists, SQLite can do something much faster.&lt;/p&gt;

&lt;p&gt;It directly navigates to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;first entry&lt;/strong&gt; in the index for MIN&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;last entry&lt;/strong&gt; in the index for MAX&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since indexes are stored as B-trees, this operation takes &lt;strong&gt;logarithmic time&lt;/strong&gt;, not linear time.&lt;/p&gt;

&lt;p&gt;If the column is an INTEGER PRIMARY KEY, SQLite can even use the table’s primary B+ tree directly.&lt;/p&gt;

&lt;p&gt;This makes MIN and MAX queries extremely efficient when proper indexing is in place &lt;/p&gt;
&lt;h2&gt;
  
  
  Bringing It All Together
&lt;/h2&gt;

&lt;p&gt;At this point, you have seen how SQLite handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Filtering using WHERE&lt;/li&gt;
&lt;li&gt;Choosing indexes&lt;/li&gt;
&lt;li&gt;Ordering joins&lt;/li&gt;
&lt;li&gt;Grouping results&lt;/li&gt;
&lt;li&gt;Flattening subqueries&lt;/li&gt;
&lt;li&gt;Optimizing aggregations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of this happens before execution, inside the frontend.&lt;/p&gt;

&lt;p&gt;By the time the Virtual Machine runs, everything has already been carefully planned and optimized.&lt;/p&gt;
&lt;h2&gt;
  
  
  Final Thoughts on the Frontend
&lt;/h2&gt;

&lt;p&gt;The SQLite frontend is a complete pipeline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The tokenizer breaks SQL into tokens&lt;/li&gt;
&lt;li&gt;The parser builds structured representations&lt;/li&gt;
&lt;li&gt;The optimizer reshapes queries for efficiency&lt;/li&gt;
&lt;li&gt;The code generator produces executable bytecode&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of this work is triggered by a single function call:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;sqlite3_prepare&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Query optimization remains one of the most complex and delicate parts of any database system. &lt;/p&gt;

&lt;p&gt;SQLite keeps things relatively simple by using heuristics instead of heavy statistical models, but still manages to achieve strong performance in most real-world scenarios &lt;/p&gt;
&lt;h2&gt;
  
  
  What’s Next
&lt;/h2&gt;

&lt;p&gt;We have now covered the entire frontend pipeline of SQLite, from raw SQL to optimized bytecode.&lt;/p&gt;

&lt;p&gt;In the next series, we will move beyond compilation and explore how SQLite interacts with the outside world.&lt;/p&gt;

&lt;p&gt;We will start with the &lt;strong&gt;SQLite Interface Handler&lt;/strong&gt;, where queries enter the system and results are returned.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzvpkxm9mga1pweneahx.png" alt="git-lrc" width="800" height="109"&gt;&lt;/a&gt; &lt;br&gt;
 *AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production. &lt;/p&gt;

&lt;p&gt;git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.* &lt;/p&gt;

&lt;p&gt;Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use. &lt;/p&gt;

&lt;p&gt;⭐ Star it on GitHub: &lt;br&gt;
 &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/HexmosTech" rel="noopener noreferrer"&gt;
        HexmosTech
      &lt;/a&gt; / &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;
        git-lrc
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Free, Unlimited AI Code Reviews That Run on Commit
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;p&gt;| &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.da.md" rel="noopener noreferrer"&gt;🇩🇰 Dansk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.es.md" rel="noopener noreferrer"&gt;🇪🇸 Español&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fa.md" rel="noopener noreferrer"&gt;🇮🇷 Farsi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fi.md" rel="noopener noreferrer"&gt;🇫🇮 Suomi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ja.md" rel="noopener noreferrer"&gt;🇯🇵 日本語&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.nn.md" rel="noopener noreferrer"&gt;🇳🇴 Norsk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.pt.md" rel="noopener noreferrer"&gt;🇵🇹 Português&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ru.md" rel="noopener noreferrer"&gt;🇷🇺 Русский&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.sq.md" rel="noopener noreferrer"&gt;🇦🇱 Shqip&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.zh.md" rel="noopener noreferrer"&gt;🇨🇳 中文&lt;/a&gt; |&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;img width="60" alt="git-lrc logo" src="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;git-lrc&lt;/h1&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Free, Unlimited AI Code Reviews That Run on Commit&lt;/h2&gt;
&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.producthunt.com/products/git-lrc?embed=true&amp;amp;utm_source=badge-top-post-badge&amp;amp;utm_medium=badge&amp;amp;utm_campaign=badge-git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt" width="200" src="https://camo.githubusercontent.com/87bf2d4283c1e0aa99e254bd17fefb1c67c0c0d39300043a243a4aa633b6cecc/68747470733a2f2f6170692e70726f6475637468756e742e636f6d2f776964676574732f656d6265642d696d6167652f76312f746f702d706f73742d62616467652e7376673f706f73745f69643d31303739323632267468656d653d6c6967687426706572696f643d6461696c7926743d31373731373439313730383638"&gt;&lt;/a&gt;
 &lt;/p&gt;
&lt;br&gt;
&lt;a href="https://goreportcard.com/report/github.com/HexmosTech/git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Go Report Card" src="https://camo.githubusercontent.com/e74c0651c3ee9165a2ed01cb0f6842c494029960df30eb9c24cf622d3d21bf46/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f4865786d6f73546563682f6769742d6c7263"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml" rel="noopener noreferrer"&gt;&lt;img alt="gitleaks.yml" title="gitleaks.yml: Secret scanning workflow" src="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml" rel="noopener noreferrer"&gt;&lt;img alt="osv-scanner.yml" title="osv-scanner.yml: Dependency vulnerability scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml" rel="noopener noreferrer"&gt;&lt;img alt="govulncheck.yml" title="govulncheck.yml: Go vulnerability check" src="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml" rel="noopener noreferrer"&gt;&lt;img alt="semgrep.yml" title="semgrep.yml: Static analysis security scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml/badge.svg"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer" href="https://github.com/HexmosTech/git-lrc/./gfx/dependabot-enabled.svg"&gt;&lt;img alt="dependabot-enabled" title="dependabot-enabled: Automated dependency updates are enabled" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FHexmosTech%2Fgit-lrc%2F.%2Fgfx%2Fdependabot-enabled.svg"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;

&lt;p&gt;AI agents write code fast. They also &lt;em&gt;silently remove logic&lt;/em&gt;, change behavior, and introduce bugs -- without telling you. You often find out in production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git-lrc&lt;/code&gt; fixes this.&lt;/strong&gt; It hooks into &lt;code&gt;git commit&lt;/code&gt; and reviews every diff &lt;em&gt;before&lt;/em&gt; it lands. 60-second setup. Completely free.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;See It In Action&lt;/h2&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See git-lrc catch serious security issues such as leaked credentials, expensive cloud
operations, and sensitive material in log statements&lt;/p&gt;
&lt;/blockquote&gt;

  
    
    

    &lt;span class="m-1"&gt;git-lrc-intro-60s.mp4&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;🤖 &lt;strong&gt;AI agents silently break things.&lt;/strong&gt; Code removed. Logic changed. Edge cases gone. You won't notice until production.&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;Catch it before it ships.&lt;/strong&gt; AI-powered inline comments show you &lt;em&gt;exactly&lt;/em&gt; what changed and what looks wrong.&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Build a&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>webdev</category>
      <category>programming</category>
      <category>database</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Which index should SQLite use?</title>
      <dc:creator>Athreya aka Maneshwar</dc:creator>
      <pubDate>Fri, 27 Mar 2026 19:12:01 +0000</pubDate>
      <link>https://dev.to/lovestaco/which-index-should-sqlite-use-43jl</link>
      <guid>https://dev.to/lovestaco/which-index-should-sqlite-use-43jl</guid>
      <description>&lt;p&gt;&lt;em&gt;Hello, I'm Maneshwar. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;Star Us&lt;/a&gt; to help devs discover the project. Do give it a try and share your feedback for improving the product.&lt;/em&gt;&lt;/p&gt; 

&lt;p&gt;Even when indexes exist, choosing the wrong one can slow down a query significantly. &lt;/p&gt;

&lt;p&gt;The optimizer’s job here is not just to use an index, but to use the &lt;strong&gt;right index&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  One Table, One Index (Mostly)
&lt;/h2&gt;

&lt;p&gt;For each table in a query, SQLite can typically use &lt;strong&gt;only one index&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;There is one exception. &lt;/p&gt;

&lt;p&gt;In OR-based queries, SQLite may use multiple indexes, but in most cases, it selects a single index per table.&lt;/p&gt;

&lt;p&gt;Because of this limitation, index selection becomes a critical decision. &lt;/p&gt;

&lt;p&gt;SQLite tries to ensure that at least one useful index is applied to each table whenever possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Multiple Indexes Exist
&lt;/h2&gt;

&lt;p&gt;Consider a table with multiple indexes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;table1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;i1&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;table1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;i2&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;table1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now look at this query:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;table1&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;SQLite has two choices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use index &lt;code&gt;i1&lt;/code&gt; to find rows where &lt;code&gt;x = 5&lt;/code&gt;, then filter &lt;code&gt;y = 6&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Use index &lt;code&gt;i2&lt;/code&gt; to find rows where &lt;code&gt;y = 6&lt;/code&gt;, then filter &lt;code&gt;x = 5&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both approaches are valid, but they may have very different costs.&lt;/p&gt;
&lt;h2&gt;
  
  
  How SQLite Chooses the Best Index
&lt;/h2&gt;

&lt;p&gt;SQLite estimates how much work each option will require and chooses the one with the lowest cost.&lt;/p&gt;

&lt;p&gt;The decision is based on heuristics such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How many rows are expected to match&lt;/li&gt;
&lt;li&gt;How selective the index is&lt;/li&gt;
&lt;li&gt;How much filtering is needed after lookup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If statistical data is available, SQLite makes better decisions.&lt;/p&gt;

&lt;p&gt;This is where the &lt;code&gt;sqlite_stat1&lt;/code&gt; table comes into play. &lt;/p&gt;

&lt;p&gt;It stores information about how many rows are typically associated with a given column value. &lt;/p&gt;

&lt;p&gt;Using this data, SQLite can estimate which index will reduce the result set the most.&lt;/p&gt;

&lt;p&gt;The index that is expected to return fewer rows is usually preferred.&lt;/p&gt;
&lt;h2&gt;
  
  
  Forcing SQLite to Ignore an Index
&lt;/h2&gt;

&lt;p&gt;Sometimes, you may want to override SQLite’s choice.&lt;/p&gt;

&lt;p&gt;SQLite provides a subtle mechanism for this using the unary &lt;code&gt;+&lt;/code&gt; operator.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;table1&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;+&lt;/code&gt; operator does nothing functionally, but it prevents SQLite from using the index on column &lt;code&gt;x&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This forces the optimizer to consider other indexes, such as &lt;code&gt;i2&lt;/code&gt; on column &lt;code&gt;y&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is a lightweight way to guide the optimizer without changing query semantics.&lt;/p&gt;
&lt;h2&gt;
  
  
  Balancing WHERE and ORDER BY
&lt;/h2&gt;

&lt;p&gt;Index selection is not only about filtering rows. &lt;/p&gt;

&lt;p&gt;SQLite also considers sorting requirements.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;table1&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now SQLite has a trade-off:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use an index on &lt;code&gt;x&lt;/code&gt; to filter efficiently&lt;/li&gt;
&lt;li&gt;Use an index on &lt;code&gt;y&lt;/code&gt; to avoid sorting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SQLite evaluates both options and chooses the one that results in the fastest overall execution.&lt;/p&gt;

&lt;p&gt;This means sometimes SQLite may sacrifice a slightly less efficient filter to avoid an expensive sort operation.&lt;/p&gt;
&lt;h2&gt;
  
  
  When Sorting Cannot Use an Index
&lt;/h2&gt;

&lt;p&gt;If no suitable index can satisfy the ORDER BY clause, SQLite must sort the results manually.&lt;/p&gt;

&lt;p&gt;This is done using a &lt;strong&gt;temporary sorter&lt;/strong&gt;, which behaves like a transient index.&lt;/p&gt;

&lt;p&gt;The process looks like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;open&lt;/span&gt; &lt;span class="n"&gt;sorter&lt;/span&gt;
&lt;span class="k"&gt;where&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;begin&lt;/span&gt;
    &lt;span class="k"&gt;extract&lt;/span&gt; &lt;span class="n"&gt;required&lt;/span&gt; &lt;span class="n"&gt;columns&lt;/span&gt;
    &lt;span class="n"&gt;build&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;
    &lt;span class="n"&gt;generate&lt;/span&gt; &lt;span class="n"&gt;sort&lt;/span&gt; &lt;span class="k"&gt;key&lt;/span&gt;
    &lt;span class="k"&gt;insert&lt;/span&gt; &lt;span class="k"&gt;into&lt;/span&gt; &lt;span class="n"&gt;sorter&lt;/span&gt;
&lt;span class="k"&gt;where&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;sort&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;each&lt;/span&gt; &lt;span class="n"&gt;sorted&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;
    &lt;span class="k"&gt;extract&lt;/span&gt; &lt;span class="k"&gt;data&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;result&lt;/span&gt;
&lt;span class="k"&gt;close&lt;/span&gt; &lt;span class="n"&gt;sorter&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This approach works, but it comes with a cost.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Additional memory usage&lt;/li&gt;
&lt;li&gt;Extra processing for sorting&lt;/li&gt;
&lt;li&gt;Potential performance overhead for large datasets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is why SQLite always tries to use an index for ORDER BY whenever possible.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Index Selection Is So Important
&lt;/h2&gt;

&lt;p&gt;At this stage, multiple layers of optimization come together:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WHERE clause determines candidate indexes&lt;/li&gt;
&lt;li&gt;Join ordering decides when a table is accessed&lt;/li&gt;
&lt;li&gt;Index selection decides how it is accessed&lt;/li&gt;
&lt;li&gt;ORDER BY may influence which index is preferred&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A single decision here can affect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Number of rows scanned&lt;/li&gt;
&lt;li&gt;Need for sorting&lt;/li&gt;
&lt;li&gt;Overall execution time&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Index selection is one of the most critical decisions in SQLite’s optimizer.&lt;/p&gt;

&lt;p&gt;Even when multiple indexes are available, SQLite carefully evaluates which one minimizes total work. &lt;/p&gt;

&lt;p&gt;It also balances filtering efficiency with sorting requirements to produce the fastest possible execution plan.&lt;/p&gt;

&lt;p&gt;Understanding how SQLite makes this decision helps you design better indexes and write queries that align with the optimizer.&lt;/p&gt;

&lt;p&gt;In the next part, we will explore &lt;strong&gt;GROUP BY and MIN/MAX optimizations&lt;/strong&gt;, where SQLite applies additional strategies to aggregate and summarize data efficiently.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzvpkxm9mga1pweneahx.png" alt="git-lrc" width="800" height="109"&gt;&lt;/a&gt; &lt;br&gt;
 *AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production. &lt;/p&gt;

&lt;p&gt;git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.* &lt;/p&gt;

&lt;p&gt;Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use. &lt;/p&gt;

&lt;p&gt;⭐ Star it on GitHub: &lt;br&gt;
 &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/HexmosTech" rel="noopener noreferrer"&gt;
        HexmosTech
      &lt;/a&gt; / &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;
        git-lrc
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Free, Unlimited AI Code Reviews That Run on Commit
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;p&gt;| &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.da.md" rel="noopener noreferrer"&gt;🇩🇰 Dansk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.es.md" rel="noopener noreferrer"&gt;🇪🇸 Español&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fa.md" rel="noopener noreferrer"&gt;🇮🇷 Farsi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fi.md" rel="noopener noreferrer"&gt;🇫🇮 Suomi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ja.md" rel="noopener noreferrer"&gt;🇯🇵 日本語&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.nn.md" rel="noopener noreferrer"&gt;🇳🇴 Norsk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.pt.md" rel="noopener noreferrer"&gt;🇵🇹 Português&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ru.md" rel="noopener noreferrer"&gt;🇷🇺 Русский&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.sq.md" rel="noopener noreferrer"&gt;🇦🇱 Shqip&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.zh.md" rel="noopener noreferrer"&gt;🇨🇳 中文&lt;/a&gt; |&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;img width="60" alt="git-lrc logo" src="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;git-lrc&lt;/h1&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Free, Unlimited AI Code Reviews That Run on Commit&lt;/h2&gt;
&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.producthunt.com/products/git-lrc?embed=true&amp;amp;utm_source=badge-top-post-badge&amp;amp;utm_medium=badge&amp;amp;utm_campaign=badge-git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt" width="200" src="https://camo.githubusercontent.com/87bf2d4283c1e0aa99e254bd17fefb1c67c0c0d39300043a243a4aa633b6cecc/68747470733a2f2f6170692e70726f6475637468756e742e636f6d2f776964676574732f656d6265642d696d6167652f76312f746f702d706f73742d62616467652e7376673f706f73745f69643d31303739323632267468656d653d6c6967687426706572696f643d6461696c7926743d31373731373439313730383638"&gt;&lt;/a&gt;
 &lt;/p&gt;
&lt;br&gt;
&lt;a href="https://goreportcard.com/report/github.com/HexmosTech/git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Go Report Card" src="https://camo.githubusercontent.com/e74c0651c3ee9165a2ed01cb0f6842c494029960df30eb9c24cf622d3d21bf46/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f4865786d6f73546563682f6769742d6c7263"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml" rel="noopener noreferrer"&gt;&lt;img alt="gitleaks.yml" title="gitleaks.yml: Secret scanning workflow" src="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml" rel="noopener noreferrer"&gt;&lt;img alt="osv-scanner.yml" title="osv-scanner.yml: Dependency vulnerability scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml" rel="noopener noreferrer"&gt;&lt;img alt="govulncheck.yml" title="govulncheck.yml: Go vulnerability check" src="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml" rel="noopener noreferrer"&gt;&lt;img alt="semgrep.yml" title="semgrep.yml: Static analysis security scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml/badge.svg"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer" href="https://github.com/HexmosTech/git-lrc/./gfx/dependabot-enabled.svg"&gt;&lt;img alt="dependabot-enabled" title="dependabot-enabled: Automated dependency updates are enabled" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FHexmosTech%2Fgit-lrc%2F.%2Fgfx%2Fdependabot-enabled.svg"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;

&lt;p&gt;AI agents write code fast. They also &lt;em&gt;silently remove logic&lt;/em&gt;, change behavior, and introduce bugs -- without telling you. You often find out in production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git-lrc&lt;/code&gt; fixes this.&lt;/strong&gt; It hooks into &lt;code&gt;git commit&lt;/code&gt; and reviews every diff &lt;em&gt;before&lt;/em&gt; it lands. 60-second setup. Completely free.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;See It In Action&lt;/h2&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See git-lrc catch serious security issues such as leaked credentials, expensive cloud
operations, and sensitive material in log statements&lt;/p&gt;
&lt;/blockquote&gt;

  
    
    

    &lt;span class="m-1"&gt;git-lrc-intro-60s.mp4&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;🤖 &lt;strong&gt;AI agents silently break things.&lt;/strong&gt; Code removed. Logic changed. Edge cases gone. You won't notice until production.&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;Catch it before it ships.&lt;/strong&gt; AI-powered inline comments show you &lt;em&gt;exactly&lt;/em&gt; what changed and what looks wrong.&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Build a&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>webdev</category>
      <category>programming</category>
      <category>architecture</category>
      <category>database</category>
    </item>
    <item>
      <title>Inside SQLite’s Frontend: Join Table Ordering</title>
      <dc:creator>Athreya aka Maneshwar</dc:creator>
      <pubDate>Thu, 26 Mar 2026 20:45:48 +0000</pubDate>
      <link>https://dev.to/lovestaco/inside-sqlites-frontend-join-table-ordering-idi</link>
      <guid>https://dev.to/lovestaco/inside-sqlites-frontend-join-table-ordering-idi</guid>
      <description>&lt;p&gt;&lt;em&gt;Hello, I'm Maneshwar. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;Star Us&lt;/a&gt; to help devs discover the project. Do give it a try and share your feedback for improving the product.&lt;/em&gt;&lt;/p&gt; 

&lt;p&gt;Even if your WHERE clause is perfectly optimized, a bad join order can still make your query slow.&lt;/p&gt;

&lt;h2&gt;
  
  
  How SQLite Executes Joins
&lt;/h2&gt;

&lt;p&gt;SQLite uses a very simple but effective strategy for joins.&lt;/p&gt;

&lt;p&gt;It always executes joins as &lt;strong&gt;nested loops&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That means for a query like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;SQLite will do something like:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for each row in A:
    for each row in B:
        process the combination
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The important detail here is that the order of tables determines how these loops are nested.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first table becomes the &lt;strong&gt;outer loop&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The last table becomes the &lt;strong&gt;inner loop&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the order in your FROM clause directly affects execution.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Order Matters
&lt;/h2&gt;

&lt;p&gt;Nested loops can be very expensive if the outer loop has too many rows.&lt;/p&gt;

&lt;p&gt;For example, if table A has 1 million rows and table B has 1 million rows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A outer → B inner = 1M × 1M operations&lt;/li&gt;
&lt;li&gt;B outer → A inner = also large, but may differ depending on indexes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is to reduce the number of iterations as early as possible.&lt;/p&gt;
&lt;h2&gt;
  
  
  SQLite Doesn’t Always Follow Your Order
&lt;/h2&gt;

&lt;p&gt;Although the default behavior follows the FROM clause order, SQLite can &lt;strong&gt;reorder tables&lt;/strong&gt; if it finds a better execution plan.&lt;/p&gt;

&lt;p&gt;It uses a &lt;strong&gt;greedy algorithm&lt;/strong&gt; to decide the order.&lt;/p&gt;

&lt;p&gt;Instead of trying all possible combinations, it builds the order step by step:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, pick the table that is cheapest to process&lt;/li&gt;
&lt;li&gt;Then pick the next cheapest&lt;/li&gt;
&lt;li&gt;Continue until all tables are placed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If two options are equally good, SQLite falls back to the original order in the query.&lt;/p&gt;
&lt;h2&gt;
  
  
  What “Cheapest” Means
&lt;/h2&gt;

&lt;p&gt;SQLite estimates cost using several factors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Availability of indexes&lt;/li&gt;
&lt;li&gt;How selective those indexes are&lt;/li&gt;
&lt;li&gt;Whether sorting can be avoided&lt;/li&gt;
&lt;li&gt;Estimated number of rows to scan&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An index that reduces 1 million rows to 1 row is extremely valuable&lt;/li&gt;
&lt;li&gt;An index that reduces 1 million rows to 900,000 rows is not very useful&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where the &lt;code&gt;ANALYZE&lt;/code&gt; command becomes important. It collects statistics so SQLite can better estimate how effective an index is.&lt;/p&gt;
&lt;h2&gt;
  
  
  Index Nested Loop Joins
&lt;/h2&gt;

&lt;p&gt;If a table has an index on the join column, SQLite often places it as the &lt;strong&gt;inner loop&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This allows efficient lookups for each row from the outer loop.&lt;/p&gt;

&lt;p&gt;This strategy is called an &lt;strong&gt;index nested loop join&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of scanning the entire inner table, SQLite uses the index to quickly find matching rows.&lt;/p&gt;
&lt;h2&gt;
  
  
  Special Cases: INNER vs OUTER Joins
&lt;/h2&gt;

&lt;p&gt;Inner joins are flexible.&lt;/p&gt;

&lt;p&gt;SQLite can freely reorder tables in inner joins because the result does not depend on order.&lt;/p&gt;

&lt;p&gt;Outer joins are different.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;LEFT OUTER JOIN&lt;/strong&gt; is not commutative, meaning order matters for correctness. Because of this, SQLite does not reorder outer joins.&lt;/p&gt;

&lt;p&gt;However, tables involved in inner joins around an outer join may still be reordered if it improves performance.&lt;/p&gt;
&lt;h2&gt;
  
  
  WHERE Clause Integration
&lt;/h2&gt;

&lt;p&gt;If you use ON or USING clauses in joins, SQLite internally converts them into additional WHERE clause conditions before optimization.&lt;/p&gt;

&lt;p&gt;This means all the WHERE clause optimizations you saw earlier still apply here.&lt;/p&gt;
&lt;h2&gt;
  
  
  Forcing Join Order
&lt;/h2&gt;

&lt;p&gt;In most cases, SQLite’s automatic reordering works well and you do not need to worry about it.&lt;/p&gt;

&lt;p&gt;But if you want to force a specific order, you can use a CROSS JOIN.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;table1&lt;/span&gt; &lt;span class="k"&gt;CROSS&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;table2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;table1&lt;/code&gt; will always be the outer loop&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;table2&lt;/code&gt; will always be the inner loop&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This gives you manual control when needed.&lt;/p&gt;

&lt;p&gt;In the next part, we will look at &lt;strong&gt;index selection&lt;/strong&gt;, where SQLite decides exactly which index to use when multiple options are available.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzvpkxm9mga1pweneahx.png" alt="git-lrc" width="800" height="109"&gt;&lt;/a&gt; &lt;br&gt;
 *AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production. &lt;/p&gt;

&lt;p&gt;git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.* &lt;/p&gt;

&lt;p&gt;Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use. &lt;/p&gt;

&lt;p&gt;⭐ Star it on GitHub: &lt;br&gt;
 &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/HexmosTech" rel="noopener noreferrer"&gt;
        HexmosTech
      &lt;/a&gt; / &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;
        git-lrc
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Free, Unlimited AI Code Reviews That Run on Commit
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;p&gt;| &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.da.md" rel="noopener noreferrer"&gt;🇩🇰 Dansk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.es.md" rel="noopener noreferrer"&gt;🇪🇸 Español&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fa.md" rel="noopener noreferrer"&gt;🇮🇷 Farsi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fi.md" rel="noopener noreferrer"&gt;🇫🇮 Suomi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ja.md" rel="noopener noreferrer"&gt;🇯🇵 日本語&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.nn.md" rel="noopener noreferrer"&gt;🇳🇴 Norsk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.pt.md" rel="noopener noreferrer"&gt;🇵🇹 Português&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ru.md" rel="noopener noreferrer"&gt;🇷🇺 Русский&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.sq.md" rel="noopener noreferrer"&gt;🇦🇱 Shqip&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.zh.md" rel="noopener noreferrer"&gt;🇨🇳 中文&lt;/a&gt; |&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;img width="60" alt="git-lrc logo" src="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;git-lrc&lt;/h1&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Free, Unlimited AI Code Reviews That Run on Commit&lt;/h2&gt;
&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.producthunt.com/products/git-lrc?embed=true&amp;amp;utm_source=badge-top-post-badge&amp;amp;utm_medium=badge&amp;amp;utm_campaign=badge-git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt" width="200" src="https://camo.githubusercontent.com/87bf2d4283c1e0aa99e254bd17fefb1c67c0c0d39300043a243a4aa633b6cecc/68747470733a2f2f6170692e70726f6475637468756e742e636f6d2f776964676574732f656d6265642d696d6167652f76312f746f702d706f73742d62616467652e7376673f706f73745f69643d31303739323632267468656d653d6c6967687426706572696f643d6461696c7926743d31373731373439313730383638"&gt;&lt;/a&gt;
 &lt;/p&gt;
&lt;br&gt;
&lt;a href="https://goreportcard.com/report/github.com/HexmosTech/git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Go Report Card" src="https://camo.githubusercontent.com/e74c0651c3ee9165a2ed01cb0f6842c494029960df30eb9c24cf622d3d21bf46/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f4865786d6f73546563682f6769742d6c7263"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml" rel="noopener noreferrer"&gt;&lt;img alt="gitleaks.yml" title="gitleaks.yml: Secret scanning workflow" src="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml" rel="noopener noreferrer"&gt;&lt;img alt="osv-scanner.yml" title="osv-scanner.yml: Dependency vulnerability scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml" rel="noopener noreferrer"&gt;&lt;img alt="govulncheck.yml" title="govulncheck.yml: Go vulnerability check" src="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml" rel="noopener noreferrer"&gt;&lt;img alt="semgrep.yml" title="semgrep.yml: Static analysis security scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml/badge.svg"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer" href="https://github.com/HexmosTech/git-lrc/./gfx/dependabot-enabled.svg"&gt;&lt;img alt="dependabot-enabled" title="dependabot-enabled: Automated dependency updates are enabled" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FHexmosTech%2Fgit-lrc%2F.%2Fgfx%2Fdependabot-enabled.svg"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;

&lt;p&gt;AI agents write code fast. They also &lt;em&gt;silently remove logic&lt;/em&gt;, change behavior, and introduce bugs -- without telling you. You often find out in production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git-lrc&lt;/code&gt; fixes this.&lt;/strong&gt; It hooks into &lt;code&gt;git commit&lt;/code&gt; and reviews every diff &lt;em&gt;before&lt;/em&gt; it lands. 60-second setup. Completely free.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;See It In Action&lt;/h2&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See git-lrc catch serious security issues such as leaked credentials, expensive cloud
operations, and sensitive material in log statements&lt;/p&gt;
&lt;/blockquote&gt;

  
    
    

    &lt;span class="m-1"&gt;git-lrc-intro-60s.mp4&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;🤖 &lt;strong&gt;AI agents silently break things.&lt;/strong&gt; Code removed. Logic changed. Edge cases gone. You won't notice until production.&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;Catch it before it ships.&lt;/strong&gt; AI-powered inline comments show you &lt;em&gt;exactly&lt;/em&gt; what changed and what looks wrong.&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Build a&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>webdev</category>
      <category>programming</category>
      <category>database</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Inside SQLite’s Frontend: BETWEEN, OR, LIKE, and GLOB Optimizations</title>
      <dc:creator>Athreya aka Maneshwar</dc:creator>
      <pubDate>Tue, 24 Mar 2026 18:16:55 +0000</pubDate>
      <link>https://dev.to/lovestaco/inside-sqlites-frontend-between-or-like-and-glob-optimizations-28p2</link>
      <guid>https://dev.to/lovestaco/inside-sqlites-frontend-between-or-like-and-glob-optimizations-28p2</guid>
      <description>&lt;p&gt;&lt;em&gt;Hello, I'm Maneshwar. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;Star Us&lt;/a&gt; to help devs discover the project. Do give it a try and share your feedback for improving the product.&lt;/em&gt;&lt;/p&gt; 

&lt;p&gt;In the previous part, you saw how SQLite breaks the WHERE clause into terms and uses strict rules to decide whether indexes can be applied. &lt;/p&gt;

&lt;p&gt;Now we go deeper into specific operators that appear frequently in real queries and how SQLite optimizes them.&lt;/p&gt;

&lt;p&gt;These operators may look simple at the SQL level, but internally SQLite often rewrites them or applies special strategies to make them efficient.&lt;/p&gt;

&lt;h2&gt;
  
  
  How SQLite Handles the BETWEEN Clause
&lt;/h2&gt;

&lt;p&gt;The BETWEEN clause is commonly used for range queries.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="k"&gt;BETWEEN&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;SQLite does not treat this as a special standalone operation. Instead, it rewrites it internally into two conditions:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This transformation introduces two &lt;strong&gt;virtual terms&lt;/strong&gt;. These terms are not explicitly written by the user, but they are used by the optimizer to reason about the query.&lt;/p&gt;

&lt;p&gt;If both of these conditions can be satisfied using an index, SQLite performs a &lt;strong&gt;range scan&lt;/strong&gt; on that index. It sets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The lower bound as &lt;code&gt;18&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The upper bound as &lt;code&gt;30&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this case, the original BETWEEN condition is completely eliminated during execution. &lt;/p&gt;

&lt;p&gt;No additional checks are required for each row because the index guarantees correctness.&lt;/p&gt;

&lt;p&gt;If the index cannot fully satisfy both conditions, SQLite still uses these virtual terms as hints for optimization. &lt;/p&gt;

&lt;p&gt;However, the original BETWEEN condition is then evaluated for each row, with the important detail that the expression on the left side is computed only once.&lt;/p&gt;
&lt;h2&gt;
  
  
  How SQLite Optimizes OR Conditions
&lt;/h2&gt;

&lt;p&gt;The OR operator is tricky because it often prevents straightforward index usage.&lt;/p&gt;

&lt;p&gt;Consider this query:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;SQLite first checks whether all OR-connected conditions refer to the same column. If they do, it rewrites the query into an IN clause:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This transformation allows SQLite to use an index efficiently.&lt;/p&gt;

&lt;p&gt;There are two important rules here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The same column must appear in every OR term&lt;/li&gt;
&lt;li&gt;The column can appear on either side of the equality operator&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If an index exists on that column, SQLite uses it just like any other IN query.&lt;/p&gt;
&lt;h3&gt;
  
  
  When OR Cannot Be Rewritten
&lt;/h3&gt;

&lt;p&gt;If the OR conditions involve different columns, SQLite cannot rewrite them into an IN clause.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In this case, SQLite applies a different strategy.&lt;/p&gt;

&lt;p&gt;It analyzes each OR term separately, almost as if each one is its own WHERE clause. &lt;/p&gt;

&lt;p&gt;If each term can use an index, SQLite executes them independently and then combines the results, removing duplicates if necessary.&lt;/p&gt;

&lt;p&gt;If some terms cannot use indexes, performance degrades. &lt;/p&gt;

&lt;p&gt;In the worst case, SQLite may fall back to a full table scan.&lt;/p&gt;
&lt;h2&gt;
  
  
  Pattern Matching with LIKE and GLOB
&lt;/h2&gt;

&lt;p&gt;The LIKE and GLOB operators are used for pattern matching.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;LIKE&lt;/span&gt; &lt;span class="s1"&gt;'A%'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;GLOB&lt;/span&gt; &lt;span class="s1"&gt;'A*'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Although these look simple, their optimization depends on several conditions.&lt;/p&gt;
&lt;h3&gt;
  
  
  Case Sensitivity Differences
&lt;/h3&gt;

&lt;p&gt;GLOB is always case sensitive.&lt;/p&gt;

&lt;p&gt;LIKE is more flexible.&lt;/p&gt;

&lt;p&gt;By default, LIKE is &lt;strong&gt;case-insensitive for basic ASCII characters&lt;/strong&gt;. This means:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="s1"&gt;'a'&lt;/span&gt; &lt;span class="k"&gt;LIKE&lt;/span&gt; &lt;span class="s1"&gt;'A'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;evaluates to true.&lt;/p&gt;

&lt;p&gt;You can change this behavior by enabling case-sensitive mode using a pragma or build configuration.&lt;/p&gt;

&lt;p&gt;However, for non-ASCII characters, comparisons are always case sensitive unless a custom collation is used.&lt;/p&gt;
&lt;h2&gt;
  
  
  When LIKE and GLOB Can Use Indexes
&lt;/h2&gt;

&lt;p&gt;SQLite can use indexes for LIKE and GLOB, but only if strict conditions are met.&lt;/p&gt;

&lt;p&gt;First, the left-hand side must be an indexed column with text affinity.&lt;/p&gt;

&lt;p&gt;Second, the pattern on the right-hand side must be a string literal or a bound parameter that behaves like a literal.&lt;/p&gt;

&lt;p&gt;Most importantly, the pattern must &lt;strong&gt;not start with a wildcard&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Example that can use an index:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;LIKE&lt;/span&gt; &lt;span class="s1"&gt;'A%'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Example that cannot use an index:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;LIKE&lt;/span&gt; &lt;span class="s1"&gt;'%A'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In the second case, SQLite cannot determine a starting point in the index, so it must scan rows.&lt;/p&gt;
&lt;h3&gt;
  
  
  Additional Conditions
&lt;/h3&gt;

&lt;p&gt;There are several other requirements for index usage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The ESCAPE clause must not be used&lt;/li&gt;
&lt;li&gt;The built-in LIKE or GLOB functions must not be overridden&lt;/li&gt;
&lt;li&gt;For GLOB, the column must use the default BINARY collation&lt;/li&gt;
&lt;li&gt;For LIKE:

&lt;ul&gt;
&lt;li&gt;If case-sensitive mode is enabled, BINARY collation is required&lt;/li&gt;
&lt;li&gt;If case-insensitive mode is used, NOCASE collation is required&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These constraints ensure that the index ordering matches how comparisons are performed.&lt;/p&gt;

&lt;p&gt;In the next part, we will look at &lt;strong&gt;join table ordering&lt;/strong&gt;, where SQLite decides the sequence in which tables are processed, which can have a major impact on performance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzvpkxm9mga1pweneahx.png" alt="git-lrc" width="800" height="109"&gt;&lt;/a&gt; &lt;br&gt;
 *AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production. &lt;/p&gt;

&lt;p&gt;git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.* &lt;/p&gt;

&lt;p&gt;Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use. &lt;/p&gt;

&lt;p&gt;⭐ Star it on GitHub: &lt;br&gt;
 &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/HexmosTech" rel="noopener noreferrer"&gt;
        HexmosTech
      &lt;/a&gt; / &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;
        git-lrc
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Free, Unlimited AI Code Reviews That Run on Commit
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;p&gt;| &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.da.md" rel="noopener noreferrer"&gt;🇩🇰 Dansk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.es.md" rel="noopener noreferrer"&gt;🇪🇸 Español&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fa.md" rel="noopener noreferrer"&gt;🇮🇷 Farsi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fi.md" rel="noopener noreferrer"&gt;🇫🇮 Suomi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ja.md" rel="noopener noreferrer"&gt;🇯🇵 日本語&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.nn.md" rel="noopener noreferrer"&gt;🇳🇴 Norsk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.pt.md" rel="noopener noreferrer"&gt;🇵🇹 Português&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ru.md" rel="noopener noreferrer"&gt;🇷🇺 Русский&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.sq.md" rel="noopener noreferrer"&gt;🇦🇱 Shqip&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.zh.md" rel="noopener noreferrer"&gt;🇨🇳 中文&lt;/a&gt; |&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;img width="60" alt="git-lrc logo" src="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;git-lrc&lt;/h1&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Free, Unlimited AI Code Reviews That Run on Commit&lt;/h2&gt;
&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.producthunt.com/products/git-lrc?embed=true&amp;amp;utm_source=badge-top-post-badge&amp;amp;utm_medium=badge&amp;amp;utm_campaign=badge-git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt" width="200" src="https://camo.githubusercontent.com/87bf2d4283c1e0aa99e254bd17fefb1c67c0c0d39300043a243a4aa633b6cecc/68747470733a2f2f6170692e70726f6475637468756e742e636f6d2f776964676574732f656d6265642d696d6167652f76312f746f702d706f73742d62616467652e7376673f706f73745f69643d31303739323632267468656d653d6c6967687426706572696f643d6461696c7926743d31373731373439313730383638"&gt;&lt;/a&gt;
 &lt;/p&gt;
&lt;br&gt;
&lt;a href="https://goreportcard.com/report/github.com/HexmosTech/git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Go Report Card" src="https://camo.githubusercontent.com/e74c0651c3ee9165a2ed01cb0f6842c494029960df30eb9c24cf622d3d21bf46/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f4865786d6f73546563682f6769742d6c7263"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml" rel="noopener noreferrer"&gt;&lt;img alt="gitleaks.yml" title="gitleaks.yml: Secret scanning workflow" src="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml" rel="noopener noreferrer"&gt;&lt;img alt="osv-scanner.yml" title="osv-scanner.yml: Dependency vulnerability scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml" rel="noopener noreferrer"&gt;&lt;img alt="govulncheck.yml" title="govulncheck.yml: Go vulnerability check" src="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml" rel="noopener noreferrer"&gt;&lt;img alt="semgrep.yml" title="semgrep.yml: Static analysis security scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml/badge.svg"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer" href="https://github.com/HexmosTech/git-lrc/./gfx/dependabot-enabled.svg"&gt;&lt;img alt="dependabot-enabled" title="dependabot-enabled: Automated dependency updates are enabled" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FHexmosTech%2Fgit-lrc%2F.%2Fgfx%2Fdependabot-enabled.svg"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;

&lt;p&gt;AI agents write code fast. They also &lt;em&gt;silently remove logic&lt;/em&gt;, change behavior, and introduce bugs -- without telling you. You often find out in production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git-lrc&lt;/code&gt; fixes this.&lt;/strong&gt; It hooks into &lt;code&gt;git commit&lt;/code&gt; and reviews every diff &lt;em&gt;before&lt;/em&gt; it lands. 60-second setup. Completely free.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;See It In Action&lt;/h2&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See git-lrc catch serious security issues such as leaked credentials, expensive cloud
operations, and sensitive material in log statements&lt;/p&gt;
&lt;/blockquote&gt;

  
    
    

    &lt;span class="m-1"&gt;git-lrc-intro-60s.mp4&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;🤖 &lt;strong&gt;AI agents silently break things.&lt;/strong&gt; Code removed. Logic changed. Edge cases gone. You won't notice until production.&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;Catch it before it ships.&lt;/strong&gt; AI-powered inline comments show you &lt;em&gt;exactly&lt;/em&gt; what changed and what looks wrong.&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Build a&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>webdev</category>
      <category>programming</category>
      <category>architecture</category>
      <category>database</category>
    </item>
    <item>
      <title>Inside SQLite’s Frontend: How the WHERE Clause Drives Optimization</title>
      <dc:creator>Athreya aka Maneshwar</dc:creator>
      <pubDate>Mon, 23 Mar 2026 17:01:26 +0000</pubDate>
      <link>https://dev.to/lovestaco/inside-sqlites-frontend-how-the-where-clause-drives-optimization-2l4</link>
      <guid>https://dev.to/lovestaco/inside-sqlites-frontend-how-the-where-clause-drives-optimization-2l4</guid>
      <description>&lt;p&gt;&lt;em&gt;Hello, I'm Maneshwar. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;Star Us&lt;/a&gt; to help devs discover the project. Do give it a try and share your feedback for improving the product.&lt;/em&gt;&lt;/p&gt; 

&lt;p&gt;In the previous part, you saw how the query optimizer chooses efficient plans using indexes and access paths. &lt;/p&gt;

&lt;p&gt;Now we go deeper into the most important part of almost every SQL query.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;WHERE clause&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This is where most of the filtering happens, and in practice, this is where most performance gains or losses come from.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the WHERE Clause Matters So Much
&lt;/h2&gt;

&lt;p&gt;Almost every real-world query includes a WHERE clause. It determines which rows should be retrieved, updated, or deleted.&lt;/p&gt;

&lt;p&gt;From SQLite’s perspective, the WHERE clause is not just a condition. It is a &lt;strong&gt;set of constraints&lt;/strong&gt; that can be used to reduce the amount of data scanned.&lt;/p&gt;

&lt;p&gt;The optimizer’s main goal here is simple.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use the WHERE clause to avoid touching unnecessary rows.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Breaking the WHERE Clause into Terms
&lt;/h2&gt;

&lt;p&gt;SQLite does not treat the WHERE clause as one big expression. Instead, it breaks it into smaller pieces called &lt;strong&gt;terms&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;These terms are connected using the AND operator.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;SQLite splits this into two terms:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a &amp;gt; 0
b &amp;lt; 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This format is called &lt;strong&gt;conjunctive normal form&lt;/strong&gt;, where conditions are separated into independent AND-connected components.&lt;/p&gt;

&lt;p&gt;Each term is then analyzed individually to see if it can use an index.&lt;/p&gt;
&lt;h2&gt;
  
  
  What Happens with OR Conditions
&lt;/h2&gt;

&lt;p&gt;Things change when OR appears.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In this case, SQLite treats the entire WHERE clause as a &lt;strong&gt;single term&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;This makes index usage more complex and often disables straightforward index optimization.&lt;/p&gt;

&lt;p&gt;A common workaround is to rewrite such queries using UNION:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="k"&gt;UNION&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If the two result sets do not overlap, using UNION ALL is even faster:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="k"&gt;UNION&lt;/span&gt; &lt;span class="k"&gt;ALL&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This allows SQLite to optimize each part separately.&lt;/p&gt;
&lt;h2&gt;
  
  
  How SQLite Evaluates Each Term
&lt;/h2&gt;

&lt;p&gt;For every term in the WHERE clause, SQLite tries to answer one question.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can this term be satisfied using an index?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If yes, SQLite uses the index to directly filter rows. In this case, the condition does not need to be checked again because the index lookup already guarantees it.&lt;/p&gt;

&lt;p&gt;If not, SQLite evaluates the condition manually for each row retrieved.&lt;/p&gt;

&lt;p&gt;This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Index-supported terms reduce the number of rows scanned&lt;/li&gt;
&lt;li&gt;Non-indexed terms act as filters after rows are retrieved&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sometimes, a term partially helps with index selection but still needs to be evaluated later. In such cases, it contributes to narrowing down candidates but is not fully handled by the index.&lt;/p&gt;
&lt;h2&gt;
  
  
  Virtual Terms: Hidden Optimization
&lt;/h2&gt;

&lt;p&gt;While analyzing conditions, SQLite may introduce additional &lt;strong&gt;virtual terms&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;These are not written in your query, but they are derived from existing conditions.&lt;/p&gt;

&lt;p&gt;Virtual terms are typically used for index optimization and are not explicitly evaluated against rows. They help SQLite improve access paths without changing query semantics.&lt;/p&gt;
&lt;h2&gt;
  
  
  When Indexes Can Be Used
&lt;/h2&gt;

&lt;p&gt;SQLite only uses indexes under certain conditions.&lt;/p&gt;

&lt;p&gt;First, the WHERE clause must be structured using AND-connected terms.&lt;/p&gt;

&lt;p&gt;Second, specific operators and patterns must be used.&lt;/p&gt;

&lt;p&gt;Indexes are usable when terms look like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;column = expression&lt;/li&gt;
&lt;li&gt;column &amp;gt; expression (and similar inequalities)&lt;/li&gt;
&lt;li&gt;column IN (value list or subquery)&lt;/li&gt;
&lt;li&gt;column IS NULL&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If a term does not match these patterns, it cannot directly drive index usage.&lt;/p&gt;

&lt;p&gt;IN clauses are particularly useful because they allow multiple values to be searched efficiently using indexes.&lt;/p&gt;
&lt;h2&gt;
  
  
  When Indexes Are Not Used
&lt;/h2&gt;

&lt;p&gt;Indexes are often not used in these situations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When conditions are connected using OR&lt;/li&gt;
&lt;li&gt;When no index exists on the relevant column&lt;/li&gt;
&lt;li&gt;When the condition does not match indexable patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In such cases, SQLite falls back to scanning rows and applying filters afterward.&lt;/p&gt;
&lt;h2&gt;
  
  
  Understanding Multi-Column Indexes
&lt;/h2&gt;

&lt;p&gt;Single-column indexes are simple. Multi-column indexes are where things get interesting.&lt;/p&gt;

&lt;p&gt;Consider an index like:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx1&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;table1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This index is ordered first by &lt;code&gt;a&lt;/code&gt;, then by &lt;code&gt;b&lt;/code&gt;, then &lt;code&gt;c&lt;/code&gt;, and so on.&lt;/p&gt;

&lt;p&gt;SQLite can only use this index &lt;strong&gt;from left to right&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It starts with column &lt;code&gt;a&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Then moves to &lt;code&gt;b&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Then &lt;code&gt;c&lt;/code&gt;, and so on&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the leftmost column is not used, the index cannot be used at all.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Left-to-Right Rule
&lt;/h2&gt;

&lt;p&gt;For a multi-column index to be usable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The leftmost column must appear in the WHERE clause&lt;/li&gt;
&lt;li&gt;Columns must be used consecutively without gaps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This uses the index efficiently.&lt;/p&gt;

&lt;p&gt;But:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This cannot use the index because &lt;code&gt;a&lt;/code&gt; is missing.&lt;/p&gt;
&lt;h2&gt;
  
  
  Equality vs Inequality
&lt;/h2&gt;

&lt;p&gt;There is another important rule.&lt;/p&gt;

&lt;p&gt;All columns in the index must use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Equality (&lt;code&gt;=&lt;/code&gt;) or IN&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Except for the &lt;strong&gt;rightmost column&lt;/strong&gt;, which can use inequalities like &lt;code&gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;&lt;/code&gt;, &lt;code&gt;&amp;gt;=&lt;/code&gt;, &lt;code&gt;&amp;lt;=&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; use equality/IN&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;c&lt;/code&gt; uses inequality&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is valid, and the index can still be used.&lt;/p&gt;
&lt;h2&gt;
  
  
  What Happens After an Inequality
&lt;/h2&gt;

&lt;p&gt;Once an inequality appears, SQLite stops using further columns in the index.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'hello'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In this case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;a&lt;/code&gt;, &lt;code&gt;b&lt;/code&gt;, and &lt;code&gt;c&lt;/code&gt; are used for indexing&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;d&lt;/code&gt; is not used for indexing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even though &lt;code&gt;d&lt;/code&gt; has an equality condition, it appears after an inequality (&lt;code&gt;c &amp;gt; 100&lt;/code&gt;), so it cannot be part of the index search.&lt;/p&gt;

&lt;p&gt;Instead, &lt;code&gt;d&lt;/code&gt; becomes a filter applied after rows are retrieved.&lt;/p&gt;
&lt;h2&gt;
  
  
  No Gaps Allowed
&lt;/h2&gt;

&lt;p&gt;Another key rule is that there cannot be gaps in index usage.&lt;/p&gt;

&lt;p&gt;If a column in the sequence is missing, all columns to the right become unusable for indexing.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Since &lt;code&gt;c&lt;/code&gt; is missing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; can be used&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;d&lt;/code&gt; cannot be used&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SQLite enforces strict left-to-right continuity.&lt;/p&gt;

&lt;p&gt;The WHERE clause is the heart of query optimization in SQLite.&lt;/p&gt;

&lt;p&gt;By breaking conditions into terms, analyzing each one, and applying strict rules for index usage, SQLite ensures that queries are executed efficiently.&lt;/p&gt;

&lt;p&gt;In the next part, we will look at specific operators like BETWEEN, LIKE, and GLOB, and how they influence index usage and query performance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzvpkxm9mga1pweneahx.png" alt="git-lrc" width="800" height="109"&gt;&lt;/a&gt; &lt;br&gt;
 *AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production. &lt;/p&gt;

&lt;p&gt;git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.* &lt;/p&gt;

&lt;p&gt;Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use. &lt;/p&gt;

&lt;p&gt;⭐ Star it on GitHub: &lt;br&gt;
 &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/HexmosTech" rel="noopener noreferrer"&gt;
        HexmosTech
      &lt;/a&gt; / &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;
        git-lrc
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Free, Unlimited AI Code Reviews That Run on Commit
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;p&gt;| &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.da.md" rel="noopener noreferrer"&gt;🇩🇰 Dansk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.es.md" rel="noopener noreferrer"&gt;🇪🇸 Español&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fa.md" rel="noopener noreferrer"&gt;🇮🇷 Farsi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fi.md" rel="noopener noreferrer"&gt;🇫🇮 Suomi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ja.md" rel="noopener noreferrer"&gt;🇯🇵 日本語&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.nn.md" rel="noopener noreferrer"&gt;🇳🇴 Norsk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.pt.md" rel="noopener noreferrer"&gt;🇵🇹 Português&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ru.md" rel="noopener noreferrer"&gt;🇷🇺 Русский&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.sq.md" rel="noopener noreferrer"&gt;🇦🇱 Shqip&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.zh.md" rel="noopener noreferrer"&gt;🇨🇳 中文&lt;/a&gt; |&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;img width="60" alt="git-lrc logo" src="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;git-lrc&lt;/h1&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Free, Unlimited AI Code Reviews That Run on Commit&lt;/h2&gt;
&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.producthunt.com/products/git-lrc?embed=true&amp;amp;utm_source=badge-top-post-badge&amp;amp;utm_medium=badge&amp;amp;utm_campaign=badge-git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt" width="200" src="https://camo.githubusercontent.com/87bf2d4283c1e0aa99e254bd17fefb1c67c0c0d39300043a243a4aa633b6cecc/68747470733a2f2f6170692e70726f6475637468756e742e636f6d2f776964676574732f656d6265642d696d6167652f76312f746f702d706f73742d62616467652e7376673f706f73745f69643d31303739323632267468656d653d6c6967687426706572696f643d6461696c7926743d31373731373439313730383638"&gt;&lt;/a&gt;
 &lt;/p&gt;
&lt;br&gt;
&lt;a href="https://goreportcard.com/report/github.com/HexmosTech/git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Go Report Card" src="https://camo.githubusercontent.com/e74c0651c3ee9165a2ed01cb0f6842c494029960df30eb9c24cf622d3d21bf46/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f4865786d6f73546563682f6769742d6c7263"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml" rel="noopener noreferrer"&gt;&lt;img alt="gitleaks.yml" title="gitleaks.yml: Secret scanning workflow" src="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml" rel="noopener noreferrer"&gt;&lt;img alt="osv-scanner.yml" title="osv-scanner.yml: Dependency vulnerability scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml" rel="noopener noreferrer"&gt;&lt;img alt="govulncheck.yml" title="govulncheck.yml: Go vulnerability check" src="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml" rel="noopener noreferrer"&gt;&lt;img alt="semgrep.yml" title="semgrep.yml: Static analysis security scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml/badge.svg"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer" href="https://github.com/HexmosTech/git-lrc/./gfx/dependabot-enabled.svg"&gt;&lt;img alt="dependabot-enabled" title="dependabot-enabled: Automated dependency updates are enabled" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FHexmosTech%2Fgit-lrc%2F.%2Fgfx%2Fdependabot-enabled.svg"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;

&lt;p&gt;AI agents write code fast. They also &lt;em&gt;silently remove logic&lt;/em&gt;, change behavior, and introduce bugs -- without telling you. You often find out in production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git-lrc&lt;/code&gt; fixes this.&lt;/strong&gt; It hooks into &lt;code&gt;git commit&lt;/code&gt; and reviews every diff &lt;em&gt;before&lt;/em&gt; it lands. 60-second setup. Completely free.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;See It In Action&lt;/h2&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See git-lrc catch serious security issues such as leaked credentials, expensive cloud
operations, and sensitive material in log statements&lt;/p&gt;
&lt;/blockquote&gt;

  
    
    

    &lt;span class="m-1"&gt;git-lrc-intro-60s.mp4&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;🤖 &lt;strong&gt;AI agents silently break things.&lt;/strong&gt; Code removed. Logic changed. Edge cases gone. You won't notice until production.&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;Catch it before it ships.&lt;/strong&gt; AI-powered inline comments show you &lt;em&gt;exactly&lt;/em&gt; what changed and what looks wrong.&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Build a&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>webdev</category>
      <category>programming</category>
      <category>architecture</category>
      <category>database</category>
    </item>
    <item>
      <title>Inside SQLite’s Frontend: How the Query Optimizer Makes Your SQL Fast</title>
      <dc:creator>Athreya aka Maneshwar</dc:creator>
      <pubDate>Sun, 22 Mar 2026 11:52:17 +0000</pubDate>
      <link>https://dev.to/lovestaco/inside-sqlites-frontend-how-the-query-optimizer-makes-your-sql-fast-3ij</link>
      <guid>https://dev.to/lovestaco/inside-sqlites-frontend-how-the-query-optimizer-makes-your-sql-fast-3ij</guid>
      <description>&lt;p&gt;&lt;em&gt;Hello, I'm Maneshwar. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;Star Us&lt;/a&gt; to help devs discover the project. Do give it a try and share your feedback for improving the product.&lt;/em&gt;&lt;/p&gt; 

&lt;p&gt;In the previous part, you saw how SQLite converts a parse tree into bytecode. At that point, SQLite knows exactly what to do and how to execute it.&lt;/p&gt;

&lt;p&gt;But there is still one critical question left.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is this the fastest way to do it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is where the &lt;strong&gt;query optimizer&lt;/strong&gt; comes in. &lt;/p&gt;

&lt;p&gt;It sits between parsing and code generation and decides how your query should actually be executed for the best performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Optimization Exists at All
&lt;/h2&gt;

&lt;p&gt;Given a single SQL query, there are often multiple ways to execute it.&lt;/p&gt;

&lt;p&gt;Take a simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This query can be executed in different ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scan the entire table and check each row&lt;/li&gt;
&lt;li&gt;Use an index on &lt;code&gt;age&lt;/code&gt; to directly find matching rows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both approaches produce the same result, but the performance difference can be massive.&lt;/p&gt;

&lt;p&gt;The job of the optimizer is to pick the approach that produces the &lt;strong&gt;most efficient bytecode program&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As described, different parse trees can represent equivalent relational operations, and each can lead to different execution strategies. &lt;/p&gt;

&lt;p&gt;The optimizer’s role is to select the one that minimizes execution time and resource usage &lt;/p&gt;
&lt;h2&gt;
  
  
  Plans, Not Just Queries
&lt;/h2&gt;

&lt;p&gt;Internally, every SQL query is converted into a &lt;strong&gt;query plan&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A plan is essentially a strategy that answers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which tables to access first&lt;/li&gt;
&lt;li&gt;Which indexes to use&lt;/li&gt;
&lt;li&gt;How to filter rows&lt;/li&gt;
&lt;li&gt;How to handle intermediate results&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each parse tree corresponds to a specific plan. The optimizer evaluates possible alternatives and chooses a plan that is efficient enough.&lt;/p&gt;

&lt;p&gt;Finding the absolute best plan is computationally expensive, so SQLite does not try to be perfect. &lt;/p&gt;

&lt;p&gt;Instead, it focuses on avoiding bad plans and finding a &lt;strong&gt;good enough plan quickly&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  SQLite’s Philosophy: Frontend Does All the Work
&lt;/h2&gt;

&lt;p&gt;One important design choice in SQLite is that the Virtual Machine does not optimize anything.&lt;/p&gt;

&lt;p&gt;It simply executes bytecode instructions exactly as given.&lt;/p&gt;

&lt;p&gt;This means &lt;strong&gt;all optimization must happen in the frontend&lt;/strong&gt;, before bytecode is generated. &lt;/p&gt;

&lt;p&gt;If the optimizer makes a poor decision, the VM will blindly execute inefficient instructions.&lt;/p&gt;

&lt;p&gt;That is why query optimization is one of the most critical responsibilities in SQLite’s architecture &lt;/p&gt;
&lt;h2&gt;
  
  
  The Real Cost: Accessing Tables
&lt;/h2&gt;

&lt;p&gt;The biggest cost in query execution is not computation. It is &lt;strong&gt;accessing data from disk&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Every time SQLite reads rows from a table, it performs I/O operations, which are expensive.&lt;/p&gt;

&lt;p&gt;So the optimizer’s main goal is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reduce the number of rows read from base tables.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The fewer rows accessed, the faster the query runs.&lt;/p&gt;
&lt;h2&gt;
  
  
  Choosing Between Full Scan and Index Scan
&lt;/h2&gt;

&lt;p&gt;For every table involved in a query, the optimizer must decide how to access it.&lt;/p&gt;

&lt;p&gt;There are two main options.&lt;/p&gt;
&lt;h3&gt;
  
  
  Full Table Scan
&lt;/h3&gt;

&lt;p&gt;SQLite reads every row in the table in rowid order.&lt;/p&gt;

&lt;p&gt;This happens when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No index exists on the column being filtered&lt;/li&gt;
&lt;li&gt;The optimizer decides an index is not beneficial&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This requires scanning the entire table.&lt;/p&gt;
&lt;h3&gt;
  
  
  Index Scan
&lt;/h3&gt;

&lt;p&gt;If an index exists, SQLite can use it to narrow down the rows.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If there is an index on &lt;code&gt;age&lt;/code&gt;, SQLite can jump directly to matching entries instead of scanning everything.&lt;/p&gt;

&lt;p&gt;For very specific queries like:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;rowid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;SQLite can directly access a single row using the table’s primary B+ tree, making the query extremely fast.&lt;/p&gt;

&lt;p&gt;If no index exists for a condition like:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;SQLite has no choice but to scan the entire table and check each row individually &lt;/p&gt;
&lt;h2&gt;
  
  
  How Indexes Actually Work in SQLite
&lt;/h2&gt;

&lt;p&gt;Each table in SQLite is stored as a &lt;strong&gt;B+ tree&lt;/strong&gt;, where the key is the rowid. This is called the primary index.&lt;/p&gt;

&lt;p&gt;In addition to that, SQLite can have &lt;strong&gt;secondary indexes&lt;/strong&gt;, which are also B-trees built on other columns.&lt;/p&gt;

&lt;p&gt;When using a secondary index, SQLite typically performs two steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Search the index to find matching entries&lt;/li&gt;
&lt;li&gt;Extract the rowid from the index&lt;/li&gt;
&lt;li&gt;Use the rowid to fetch the actual row from the table&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This means an indexed lookup often involves &lt;strong&gt;two tree searches&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;However, there is an important optimization.&lt;/p&gt;

&lt;p&gt;If all required columns are already present in the index, SQLite does not need to access the base table at all.&lt;/p&gt;

&lt;p&gt;This avoids the second lookup and can significantly improve performance, sometimes making queries nearly twice as fast &lt;/p&gt;
&lt;h2&gt;
  
  
  Two Core Challenges in Optimization
&lt;/h2&gt;

&lt;p&gt;For any query, the optimizer has to solve two main problems:&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Which Plans Should Be Considered
&lt;/h3&gt;

&lt;p&gt;There are many possible ways to execute a query. &lt;/p&gt;

&lt;p&gt;The optimizer cannot explore all of them, so it uses heuristics to narrow down the options.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. How to Estimate Cost
&lt;/h3&gt;

&lt;p&gt;For each plan, SQLite estimates how expensive it will be.&lt;/p&gt;

&lt;p&gt;Since SQLite does not maintain detailed statistics about tables, its cost estimation is relatively simple compared to larger database systems.&lt;/p&gt;

&lt;p&gt;Despite this, it performs surprisingly well in practice.&lt;/p&gt;
&lt;h2&gt;
  
  
  Optimization Is Different for Different Queries
&lt;/h2&gt;

&lt;p&gt;Not all queries benefit equally from optimization.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;INSERT statements have limited optimization opportunities&lt;/li&gt;
&lt;li&gt;Queries without a WHERE clause usually result in full table scans&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most optimization effort is focused on queries that filter data, especially SELECT statements.&lt;/p&gt;
&lt;h2&gt;
  
  
  Special Handling for DELETE and UPDATE
&lt;/h2&gt;

&lt;p&gt;DELETE and UPDATE statements follow a slightly different execution model.&lt;/p&gt;

&lt;p&gt;They are processed in two phases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;SQLite identifies the rows that match the condition and stores their rowids in a temporary structure (RowSet)&lt;/li&gt;
&lt;li&gt;It then performs the actual deletion or update using those rowids&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There is also a special optimization.&lt;/p&gt;

&lt;p&gt;If you run:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;SQLite uses a special opcode (&lt;code&gt;OP_Clear&lt;/code&gt;) to wipe the entire table efficiently.&lt;/p&gt;

&lt;p&gt;If you want to prevent this optimization, you can force a condition:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This forces SQLite to go through the normal row-by-row process &lt;/p&gt;
&lt;h2&gt;
  
  
  How SQLite Organizes Optimization Work
&lt;/h2&gt;

&lt;p&gt;SQLite breaks queries into &lt;strong&gt;query blocks&lt;/strong&gt; and optimizes each block independently.&lt;/p&gt;

&lt;p&gt;Most of the optimization logic lives in the &lt;code&gt;where.c&lt;/code&gt; file, which handles decisions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which indexes to use&lt;/li&gt;
&lt;li&gt;How to structure loops&lt;/li&gt;
&lt;li&gt;How to filter rows efficiently&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the same component that works closely with the code generator to produce efficient loops for WHERE clauses.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzvpkxm9mga1pweneahx.png" alt="git-lrc" width="800" height="109"&gt;&lt;/a&gt; &lt;br&gt;
 *AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production. &lt;/p&gt;

&lt;p&gt;git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.* &lt;/p&gt;

&lt;p&gt;Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use. &lt;/p&gt;

&lt;p&gt;⭐ Star it on GitHub: &lt;br&gt;
 &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/HexmosTech" rel="noopener noreferrer"&gt;
        HexmosTech
      &lt;/a&gt; / &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;
        git-lrc
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Free, Unlimited AI Code Reviews That Run on Commit
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;p&gt;| &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.da.md" rel="noopener noreferrer"&gt;🇩🇰 Dansk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.es.md" rel="noopener noreferrer"&gt;🇪🇸 Español&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fa.md" rel="noopener noreferrer"&gt;🇮🇷 Farsi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fi.md" rel="noopener noreferrer"&gt;🇫🇮 Suomi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ja.md" rel="noopener noreferrer"&gt;🇯🇵 日本語&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.nn.md" rel="noopener noreferrer"&gt;🇳🇴 Norsk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.pt.md" rel="noopener noreferrer"&gt;🇵🇹 Português&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ru.md" rel="noopener noreferrer"&gt;🇷🇺 Русский&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.sq.md" rel="noopener noreferrer"&gt;🇦🇱 Shqip&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.zh.md" rel="noopener noreferrer"&gt;🇨🇳 中文&lt;/a&gt; |&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;img width="60" alt="git-lrc logo" src="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;git-lrc&lt;/h1&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Free, Unlimited AI Code Reviews That Run on Commit&lt;/h2&gt;
&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.producthunt.com/products/git-lrc?embed=true&amp;amp;utm_source=badge-top-post-badge&amp;amp;utm_medium=badge&amp;amp;utm_campaign=badge-git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt" width="200" src="https://camo.githubusercontent.com/87bf2d4283c1e0aa99e254bd17fefb1c67c0c0d39300043a243a4aa633b6cecc/68747470733a2f2f6170692e70726f6475637468756e742e636f6d2f776964676574732f656d6265642d696d6167652f76312f746f702d706f73742d62616467652e7376673f706f73745f69643d31303739323632267468656d653d6c6967687426706572696f643d6461696c7926743d31373731373439313730383638"&gt;&lt;/a&gt;
 &lt;/p&gt;
&lt;br&gt;
&lt;a href="https://goreportcard.com/report/github.com/HexmosTech/git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Go Report Card" src="https://camo.githubusercontent.com/e74c0651c3ee9165a2ed01cb0f6842c494029960df30eb9c24cf622d3d21bf46/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f4865786d6f73546563682f6769742d6c7263"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml" rel="noopener noreferrer"&gt;&lt;img alt="gitleaks.yml" title="gitleaks.yml: Secret scanning workflow" src="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml" rel="noopener noreferrer"&gt;&lt;img alt="osv-scanner.yml" title="osv-scanner.yml: Dependency vulnerability scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml" rel="noopener noreferrer"&gt;&lt;img alt="govulncheck.yml" title="govulncheck.yml: Go vulnerability check" src="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml" rel="noopener noreferrer"&gt;&lt;img alt="semgrep.yml" title="semgrep.yml: Static analysis security scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml/badge.svg"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer" href="https://github.com/HexmosTech/git-lrc/./gfx/dependabot-enabled.svg"&gt;&lt;img alt="dependabot-enabled" title="dependabot-enabled: Automated dependency updates are enabled" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FHexmosTech%2Fgit-lrc%2F.%2Fgfx%2Fdependabot-enabled.svg"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;

&lt;p&gt;AI agents write code fast. They also &lt;em&gt;silently remove logic&lt;/em&gt;, change behavior, and introduce bugs -- without telling you. You often find out in production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git-lrc&lt;/code&gt; fixes this.&lt;/strong&gt; It hooks into &lt;code&gt;git commit&lt;/code&gt; and reviews every diff &lt;em&gt;before&lt;/em&gt; it lands. 60-second setup. Completely free.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;See It In Action&lt;/h2&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See git-lrc catch serious security issues such as leaked credentials, expensive cloud
operations, and sensitive material in log statements&lt;/p&gt;
&lt;/blockquote&gt;

  
    
    

    &lt;span class="m-1"&gt;git-lrc-intro-60s.mp4&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;🤖 &lt;strong&gt;AI agents silently break things.&lt;/strong&gt; Code removed. Logic changed. Edge cases gone. You won't notice until production.&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;Catch it before it ships.&lt;/strong&gt; AI-powered inline comments show you &lt;em&gt;exactly&lt;/em&gt; what changed and what looks wrong.&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Build a&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>webdev</category>
      <category>architecture</category>
      <category>database</category>
      <category>programming</category>
    </item>
    <item>
      <title>Inside SQLite’s Frontend: How Bytecode Is Generated and Names Are Resolved</title>
      <dc:creator>Athreya aka Maneshwar</dc:creator>
      <pubDate>Sat, 21 Mar 2026 17:51:01 +0000</pubDate>
      <link>https://dev.to/lovestaco/inside-sqlites-frontend-how-bytecode-is-generated-and-names-are-resolved-256g</link>
      <guid>https://dev.to/lovestaco/inside-sqlites-frontend-how-bytecode-is-generated-and-names-are-resolved-256g</guid>
      <description>&lt;p&gt;&lt;em&gt;Hello, I'm Maneshwar. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;Star Us&lt;/a&gt; to help devs discover the project. Do give it a try and share your feedback for improving the product.&lt;/em&gt;&lt;/p&gt; 

&lt;p&gt;In the previous part, you saw how the parser converts tokens into a structured parse tree and validates the query. &lt;/p&gt;

&lt;p&gt;At that point, SQLite fully understands what your query means, but it still cannot execute it.&lt;/p&gt;

&lt;p&gt;Now comes the stage where SQLite turns that understanding into action.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;code generator&lt;/strong&gt; takes the parse tree and produces a &lt;strong&gt;bytecode program&lt;/strong&gt; that the Virtual Machine (VDBE) can execute step by step.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Parse Tree to Executable Program
&lt;/h2&gt;

&lt;p&gt;Most database systems evaluate queries by traversing complex trees of objects at runtime. SQLite takes a different route.&lt;/p&gt;

&lt;p&gt;Instead of interpreting trees directly, it generates a &lt;strong&gt;procedural bytecode program&lt;/strong&gt;, similar to assembly language. This program is then executed by the VM.&lt;/p&gt;

&lt;p&gt;So instead of saying “evaluate this tree,” SQLite says “run these instructions.”&lt;/p&gt;

&lt;p&gt;The code generator accepts an optimized parse tree from the optimizer and emits bytecode instructions that perform the exact operations described by the query.&lt;/p&gt;

&lt;p&gt;This subsystem is not small. It is actually the largest and most complex part of SQLite, making up roughly &lt;strong&gt;40% of the entire library code&lt;/strong&gt;. Unlike other components, it does not have a clean boundary. &lt;/p&gt;

&lt;p&gt;It is deeply integrated with the parser and optimizer, which allows it to generate efficient code without unnecessary abstractions.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Bytecode Gets Built
&lt;/h2&gt;

&lt;p&gt;At the core of code generation is the &lt;strong&gt;Vdbe object&lt;/strong&gt;, which acts as a container for bytecode instructions.&lt;/p&gt;

&lt;p&gt;The code generator gradually fills this object with instructions as it walks through the parse tree.&lt;/p&gt;

&lt;p&gt;There are several internal routines that make this process possible.&lt;/p&gt;

&lt;p&gt;The function &lt;code&gt;sqlite3GetVdbe&lt;/code&gt; is responsible for retrieving the current Vdbe object. If it does not exist yet, it creates one. This ensures that there is always a valid place to store the generated instructions.&lt;/p&gt;

&lt;p&gt;Once the Vdbe object is available, instructions are added using functions like &lt;code&gt;sqlite3VdbeAddOp&lt;/code&gt;. These functions append new bytecode operations to the program.&lt;/p&gt;

&lt;p&gt;If an instruction needs to be modified later, functions like &lt;code&gt;sqlite3VdbeChangeP1&lt;/code&gt; through &lt;code&gt;sqlite3VdbeChangeP5&lt;/code&gt; are used to update its operands. This is important because some instructions cannot be fully defined until later stages of generation.&lt;/p&gt;

&lt;p&gt;To keep track of where instructions are being inserted, the generator uses &lt;code&gt;sqlite3VdbeCurrentAddr&lt;/code&gt;, which returns the address of the next instruction slot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generating Code for Expressions
&lt;/h2&gt;

&lt;p&gt;Expressions are everywhere in SQL, from simple comparisons to complex nested conditions.&lt;/p&gt;

&lt;p&gt;The function &lt;code&gt;sqlite3ExprCode&lt;/code&gt; is used to generate bytecode for evaluating expressions. For example, it can generate instructions to compute &lt;code&gt;age &amp;gt; 25&lt;/code&gt; or evaluate arithmetic expressions.&lt;/p&gt;

&lt;p&gt;Branching logic is handled using two important routines.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sqlite3ExprIfTrue&lt;/code&gt; generates bytecode that jumps to a specific location if a condition evaluates to true.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sqlite3ExprIfFalse&lt;/code&gt; does the opposite and branches when the condition is false.&lt;/p&gt;

&lt;p&gt;These functions are essential for implementing WHERE clauses, conditional logic, and control flow inside the bytecode program.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preparing for Database Operations
&lt;/h2&gt;

&lt;p&gt;Before executing any meaningful operation, SQLite must ensure that the database is in a consistent state.&lt;/p&gt;

&lt;p&gt;The function &lt;code&gt;sqlite3CodeVerifySchema&lt;/code&gt; generates instructions to verify the schema version (schema cookie) and ensures that a read transaction has started. This step is critical because SQLite must confirm that the database schema has not changed unexpectedly.&lt;/p&gt;

&lt;p&gt;For operations that modify data, such as INSERT, UPDATE, or DELETE, the function &lt;code&gt;sqlite3BeginWriteOperation&lt;/code&gt; prepares the system by starting a write transaction if one is not already active.&lt;/p&gt;

&lt;p&gt;When schema changes occur, such as creating or dropping tables, the function &lt;code&gt;sqlite3ChangeCookie&lt;/code&gt; generates instructions to update the schema version.&lt;/p&gt;

&lt;p&gt;There is also a special function called &lt;code&gt;sqlite3NestedParse&lt;/code&gt;, which allows SQLite to parse and generate code for one SQL statement inside another. &lt;/p&gt;

&lt;p&gt;This is primarily used for operations on internal tables like &lt;code&gt;sqlite_master&lt;/code&gt;, which are involved in schema changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  How WHERE Clauses Become Loops
&lt;/h2&gt;

&lt;p&gt;One of the most important parts of query execution is filtering rows using the WHERE clause.&lt;/p&gt;

&lt;p&gt;SQLite handles this using logic implemented in the &lt;code&gt;where.c&lt;/code&gt; file. This part of the system decides how to search for rows and whether indexes should be used.&lt;/p&gt;

&lt;p&gt;The process works like this.&lt;/p&gt;

&lt;p&gt;The code generator calls &lt;code&gt;sqlite3WhereBegin&lt;/code&gt;, which sets up the beginning of a loop. This loop will iterate over all rows that match the WHERE condition.&lt;/p&gt;

&lt;p&gt;After that, the generator emits instructions that process a single row, such as returning results or updating values.&lt;/p&gt;

&lt;p&gt;Finally, it calls &lt;code&gt;sqlite3WhereEnd&lt;/code&gt;, which closes the loop.&lt;/p&gt;

&lt;p&gt;The combination of these two functions effectively creates a loop in bytecode that runs once for each matching row.&lt;/p&gt;

&lt;p&gt;This is where many performance optimizations come into play, including index selection and efficient scan strategies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Name Resolution: Making Sense of Identifiers
&lt;/h2&gt;

&lt;p&gt;Before bytecode can be fully generated, SQLite must resolve all identifiers used in the query.&lt;/p&gt;

&lt;p&gt;When you write something like:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="h8v4rm"&lt;br&gt;
SELECT name FROM users;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


SQLite needs to determine exactly what `name` refers to. Is it a column in the `users` table, or does it come from somewhere else?

This process is called **name resolution**.

SQLite uses a structure called **NameContext** to manage this. A NameContext is built from two main components:

* A SrcList, which defines the available data sources
* An ExprList, which defines available expressions

Together, these define the scope in which names can be resolved.

## Handling Nested Queries

Things get more interesting with subqueries.

Consider:



```sql id="3a0smg"
SELECT name FROM users 
WHERE id IN (
    SELECT user_id FROM orders
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Here, there are two contexts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The outer query (&lt;code&gt;users&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;The inner query (&lt;code&gt;orders&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SQLite creates a separate NameContext for each query. The inner context has a reference to the outer one.&lt;/p&gt;

&lt;p&gt;When resolving names inside the subquery, SQLite first checks the inner context. If it cannot find a match, it moves outward and checks the outer context.&lt;/p&gt;

&lt;p&gt;This is how SQLite handles &lt;strong&gt;correlated subqueries&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If a name resolves in the outer context, the subquery depends on the outer query and must be executed repeatedly. These are called correlated subqueries.&lt;/p&gt;

&lt;p&gt;If all names are resolved within the inner context, the subquery is independent and can be executed once, with results reused. These are non-correlated subqueries.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzvpkxm9mga1pweneahx.png" alt="git-lrc" width="800" height="109"&gt;&lt;/a&gt; &lt;br&gt;
 *AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production. &lt;/p&gt;

&lt;p&gt;git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.* &lt;/p&gt;

&lt;p&gt;Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use. &lt;/p&gt;

&lt;p&gt;⭐ Star it on GitHub: &lt;br&gt;
 &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/HexmosTech" rel="noopener noreferrer"&gt;
        HexmosTech
      &lt;/a&gt; / &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;
        git-lrc
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Free, Unlimited AI Code Reviews That Run on Commit
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;p&gt;| &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.da.md" rel="noopener noreferrer"&gt;🇩🇰 Dansk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.es.md" rel="noopener noreferrer"&gt;🇪🇸 Español&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fa.md" rel="noopener noreferrer"&gt;🇮🇷 Farsi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fi.md" rel="noopener noreferrer"&gt;🇫🇮 Suomi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ja.md" rel="noopener noreferrer"&gt;🇯🇵 日本語&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.nn.md" rel="noopener noreferrer"&gt;🇳🇴 Norsk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.pt.md" rel="noopener noreferrer"&gt;🇵🇹 Português&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ru.md" rel="noopener noreferrer"&gt;🇷🇺 Русский&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.sq.md" rel="noopener noreferrer"&gt;🇦🇱 Shqip&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.zh.md" rel="noopener noreferrer"&gt;🇨🇳 中文&lt;/a&gt; |&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;img width="60" alt="git-lrc logo" src="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;git-lrc&lt;/h1&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Free, Unlimited AI Code Reviews That Run on Commit&lt;/h2&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
&lt;p&gt;&lt;a href="https://www.producthunt.com/products/git-lrc?embed=true&amp;amp;utm_source=badge-top-post-badge&amp;amp;utm_medium=badge&amp;amp;utm_campaign=badge-git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt" width="200" src="https://camo.githubusercontent.com/87bf2d4283c1e0aa99e254bd17fefb1c67c0c0d39300043a243a4aa633b6cecc/68747470733a2f2f6170692e70726f6475637468756e742e636f6d2f776964676574732f656d6265642d696d6167652f76312f746f702d706f73742d62616467652e7376673f706f73745f69643d31303739323632267468656d653d6c6967687426706572696f643d6461696c7926743d31373731373439313730383638"&gt;&lt;/a&gt;
 &lt;/p&gt;
&lt;br&gt;
&lt;a href="https://goreportcard.com/report/github.com/HexmosTech/git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Go Report Card" src="https://camo.githubusercontent.com/e74c0651c3ee9165a2ed01cb0f6842c494029960df30eb9c24cf622d3d21bf46/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f4865786d6f73546563682f6769742d6c7263"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml" rel="noopener noreferrer"&gt;&lt;img alt="gitleaks.yml" title="gitleaks.yml: Secret scanning workflow" src="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml" rel="noopener noreferrer"&gt;&lt;img alt="osv-scanner.yml" title="osv-scanner.yml: Dependency vulnerability scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml" rel="noopener noreferrer"&gt;&lt;img alt="govulncheck.yml" title="govulncheck.yml: Go vulnerability check" src="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml" rel="noopener noreferrer"&gt;&lt;img alt="semgrep.yml" title="semgrep.yml: Static analysis security scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml/badge.svg"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer" href="https://github.com/HexmosTech/git-lrc/./gfx/dependabot-enabled.svg"&gt;&lt;img alt="dependabot-enabled" title="dependabot-enabled: Automated dependency updates are enabled" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FHexmosTech%2Fgit-lrc%2F.%2Fgfx%2Fdependabot-enabled.svg"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;

&lt;p&gt;AI agents write code fast. They also &lt;em&gt;silently remove logic&lt;/em&gt;, change behavior, and introduce bugs -- without telling you. You often find out in production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git-lrc&lt;/code&gt; fixes this.&lt;/strong&gt; It hooks into &lt;code&gt;git commit&lt;/code&gt; and reviews every diff &lt;em&gt;before&lt;/em&gt; it lands. 60-second setup. Completely free.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;See It In Action&lt;/h2&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See git-lrc catch serious security issues such as leaked credentials, expensive cloud
operations, and sensitive material in log statements&lt;/p&gt;
&lt;/blockquote&gt;

  
    
    

    &lt;span class="m-1"&gt;git-lrc-intro-60s.mp4&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;🤖 &lt;strong&gt;AI agents silently break things.&lt;/strong&gt; Code removed. Logic changed. Edge cases gone. You won't notice until production.&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;Catch it before it ships.&lt;/strong&gt; AI-powered inline comments show you &lt;em&gt;exactly&lt;/em&gt; what changed and what looks wrong.&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Build a&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>webdev</category>
      <category>programming</category>
      <category>database</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Inside SQLite’s Frontend: The Parser- Turning Tokens into Meaning</title>
      <dc:creator>Athreya aka Maneshwar</dc:creator>
      <pubDate>Fri, 20 Mar 2026 11:21:48 +0000</pubDate>
      <link>https://dev.to/lovestaco/inside-sqlites-frontend-the-parser-turning-tokens-into-meaning-5p8</link>
      <guid>https://dev.to/lovestaco/inside-sqlites-frontend-the-parser-turning-tokens-into-meaning-5p8</guid>
      <description>&lt;p&gt;&lt;em&gt;Hello, I'm Maneshwar. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;Star Us&lt;/a&gt; to help devs discover the project. Do give it a try and share your feedback for improving the product.&lt;/em&gt;&lt;/p&gt; 

&lt;p&gt;In the previous part, you saw how SQLite takes raw SQL and breaks it into tokens. &lt;/p&gt;

&lt;p&gt;At that stage, SQLite has pieces of information, but it still does not understand the meaning or structure of the query.&lt;/p&gt;

&lt;p&gt;Now comes the stage where everything starts to make sense.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;parser&lt;/strong&gt; takes those tokens and organizes them into a structured representation that SQLite can reason about and eventually execute.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Parser Actually Does
&lt;/h2&gt;

&lt;p&gt;The parser sits right after the tokenizer in the pipeline. It accepts a stream of tokens and transforms them into a &lt;strong&gt;parse tree&lt;/strong&gt;, which is a structured representation of the SQL statement.&lt;/p&gt;

&lt;p&gt;Think of it this way. The tokenizer gives you words, but the parser builds a sentence with grammar and meaning.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;At the tokenizer level, this is just a sequence of tokens. &lt;/p&gt;

&lt;p&gt;At the parser level, this becomes a structured tree that clearly defines what is being selected, from where, and under what condition.&lt;/p&gt;

&lt;p&gt;The parser is also responsible for ensuring that the query is valid, both syntactically and semantically. &lt;/p&gt;

&lt;p&gt;It checks whether the SQL statement follows the correct grammar and whether the referenced tables and columns actually exist.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Building Blocks of the Parse Tree
&lt;/h2&gt;

&lt;p&gt;SQLite builds its parse tree using a set of core data structures. These structures are the foundation of how SQL is represented internally.&lt;/p&gt;
&lt;h3&gt;
  
  
  Token
&lt;/h3&gt;

&lt;p&gt;A Token represents a single unit from the SQL input. It carries the actual text value, such as a literal, table name, or column name. The tokenizer produces these, and the parser consumes them.&lt;/p&gt;

&lt;p&gt;The tokenizer output looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvvtlupinl7zwr7t553n4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvvtlupinl7zwr7t553n4.png" alt="Figure 8.1: A typical tokenizer output." width="718" height="561"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each piece you see in that output is wrapped as a Token object and passed into the parser for further processing.&lt;/p&gt;
&lt;h3&gt;
  
  
  Expr
&lt;/h3&gt;

&lt;p&gt;An Expr represents a single operator or operand within an expression. When combined, multiple Expr nodes form a tree that represents a complete expression.&lt;/p&gt;

&lt;p&gt;For example, in:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;age&lt;/code&gt;, &lt;code&gt;&amp;gt;&lt;/code&gt;, and &lt;code&gt;25&lt;/code&gt; are all represented as parts of an Expr tree.&lt;/p&gt;
&lt;h3&gt;
  
  
  ExprList
&lt;/h3&gt;

&lt;p&gt;An ExprList is a collection of expressions. Each expression in the list can optionally have an identifier and sorting information such as ascending or descending order.&lt;/p&gt;

&lt;p&gt;You typically see this in SELECT clauses or ORDER BY clauses.&lt;/p&gt;
&lt;h3&gt;
  
  
  IdList
&lt;/h3&gt;

&lt;p&gt;An IdList is simply a list of identifiers. These identifiers could be column names or other named entities.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;(id, name, age)&lt;/code&gt; part is stored as an IdList.&lt;/p&gt;
&lt;h3&gt;
  
  
  SrcList
&lt;/h3&gt;

&lt;p&gt;A SrcList represents data sources. These could be tables, views, or even subqueries. Essentially, anything that can produce rows of data is considered a source.&lt;/p&gt;

&lt;p&gt;For INSERT, UPDATE, and DELETE statements, this list usually contains a single source. For SELECT queries, it can contain multiple sources, especially when joins are involved.&lt;/p&gt;
&lt;h3&gt;
  
  
  Select
&lt;/h3&gt;

&lt;p&gt;The Select structure represents a full SELECT statement. This is especially important for handling subqueries, where one SELECT is nested inside another.&lt;/p&gt;
&lt;h2&gt;
  
  
  How These Structures Represent SQL
&lt;/h2&gt;

&lt;p&gt;These data structures are combined to form a complete parse tree for different types of SQL statements.&lt;/p&gt;

&lt;p&gt;For example, a DELETE statement can be represented as:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;srclist&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;An UPDATE statement looks like:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;srclist&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exprlist&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Or more explicitly:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;srclist&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;expr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;expr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...)&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;An INSERT statement can take two forms:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;srclist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;idlist&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;exprlist&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;srclist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;idlist&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;A SELECT statement combines multiple structures:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exprlist&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;srclist&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exprlist&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Each part of these statements maps directly to one of the core structures like Expr, ExprList, IdList, or SrcList. This mapping is what allows SQLite to understand the intent behind the query.&lt;/p&gt;
&lt;h2&gt;
  
  
  Syntax and Semantic Validation
&lt;/h2&gt;

&lt;p&gt;The parser does more than just build a tree. It also validates the query.&lt;/p&gt;

&lt;p&gt;First, it checks syntax. If the SQL statement is malformed, the parser will reject it immediately.&lt;/p&gt;

&lt;p&gt;Then it performs basic semantic checks. &lt;/p&gt;

&lt;p&gt;It verifies that referenced tables exist and that the columns mentioned in the query belong to those tables. &lt;/p&gt;

&lt;p&gt;This prevents invalid queries from progressing further into execution.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Parse Object: Carrying Context Through the System
&lt;/h2&gt;

&lt;p&gt;When SQLite begins parsing, it creates a &lt;strong&gt;Parse object&lt;/strong&gt;. This object represents the entire parsing context for a single SQL statement.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd5sp8kjga65gptcgju8q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd5sp8kjga65gptcgju8q.png" alt="Figure 8.2: The Parse object." width="605" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This object is passed through all parsing routines and carries global information required during the parsing process.&lt;/p&gt;

&lt;p&gt;One of the most important things inside the Parse object is a pointer to a &lt;strong&gt;Vdbe object&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Connection to Bytecode Generation
&lt;/h2&gt;

&lt;p&gt;At this stage, the Vdbe object exists but is empty. It is essentially a container waiting to be filled with bytecode instructions.&lt;/p&gt;

&lt;p&gt;As parsing progresses, and later when code generation kicks in, this object starts getting populated with instructions that represent the query.&lt;/p&gt;

&lt;p&gt;This tight coupling between parsing and code generation is one of the reasons SQLite is so efficient. Instead of building large intermediate representations, it incrementally moves toward executable bytecode.&lt;/p&gt;

&lt;p&gt;If you explore SQLite’s source code, especially the &lt;code&gt;build.c&lt;/code&gt; file, you can see how parsing and code generation work together, particularly for operations like creating tables and indexes.&lt;/p&gt;

&lt;p&gt;In the next part, we will look at how this structured representation is converted into executable instructions, focusing on the &lt;strong&gt;Code Generator&lt;/strong&gt; and &lt;strong&gt;name resolution&lt;/strong&gt;, where SQLite turns understanding into action.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzvpkxm9mga1pweneahx.png" alt="git-lrc" width="800" height="109"&gt;&lt;/a&gt; &lt;br&gt;
 *AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production. &lt;/p&gt;

&lt;p&gt;git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.* &lt;/p&gt;

&lt;p&gt;Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use. &lt;/p&gt;

&lt;p&gt;⭐ Star it on GitHub: &lt;br&gt;
 &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/HexmosTech" rel="noopener noreferrer"&gt;
        HexmosTech
      &lt;/a&gt; / &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;
        git-lrc
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Free, Unlimited AI Code Reviews That Run on Commit
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;p&gt;| &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.da.md" rel="noopener noreferrer"&gt;🇩🇰 Dansk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.es.md" rel="noopener noreferrer"&gt;🇪🇸 Español&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fa.md" rel="noopener noreferrer"&gt;🇮🇷 Farsi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fi.md" rel="noopener noreferrer"&gt;🇫🇮 Suomi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ja.md" rel="noopener noreferrer"&gt;🇯🇵 日本語&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.nn.md" rel="noopener noreferrer"&gt;🇳🇴 Norsk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.pt.md" rel="noopener noreferrer"&gt;🇵🇹 Português&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ru.md" rel="noopener noreferrer"&gt;🇷🇺 Русский&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.sq.md" rel="noopener noreferrer"&gt;🇦🇱 Shqip&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.zh.md" rel="noopener noreferrer"&gt;🇨🇳 中文&lt;/a&gt; |&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;img width="60" alt="git-lrc logo" src="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;git-lrc&lt;/h1&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Free, Unlimited AI Code Reviews That Run on Commit&lt;/h2&gt;
&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.producthunt.com/products/git-lrc?embed=true&amp;amp;utm_source=badge-top-post-badge&amp;amp;utm_medium=badge&amp;amp;utm_campaign=badge-git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt" width="200" src="https://camo.githubusercontent.com/87bf2d4283c1e0aa99e254bd17fefb1c67c0c0d39300043a243a4aa633b6cecc/68747470733a2f2f6170692e70726f6475637468756e742e636f6d2f776964676574732f656d6265642d696d6167652f76312f746f702d706f73742d62616467652e7376673f706f73745f69643d31303739323632267468656d653d6c6967687426706572696f643d6461696c7926743d31373731373439313730383638"&gt;&lt;/a&gt;
 &lt;/p&gt;
&lt;br&gt;
&lt;a href="https://goreportcard.com/report/github.com/HexmosTech/git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Go Report Card" src="https://camo.githubusercontent.com/e74c0651c3ee9165a2ed01cb0f6842c494029960df30eb9c24cf622d3d21bf46/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f4865786d6f73546563682f6769742d6c7263"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml" rel="noopener noreferrer"&gt;&lt;img alt="gitleaks.yml" title="gitleaks.yml: Secret scanning workflow" src="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml" rel="noopener noreferrer"&gt;&lt;img alt="osv-scanner.yml" title="osv-scanner.yml: Dependency vulnerability scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml" rel="noopener noreferrer"&gt;&lt;img alt="govulncheck.yml" title="govulncheck.yml: Go vulnerability check" src="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml" rel="noopener noreferrer"&gt;&lt;img alt="semgrep.yml" title="semgrep.yml: Static analysis security scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml/badge.svg"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer" href="https://github.com/HexmosTech/git-lrc/./gfx/dependabot-enabled.svg"&gt;&lt;img alt="dependabot-enabled" title="dependabot-enabled: Automated dependency updates are enabled" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FHexmosTech%2Fgit-lrc%2F.%2Fgfx%2Fdependabot-enabled.svg"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;

&lt;p&gt;AI agents write code fast. They also &lt;em&gt;silently remove logic&lt;/em&gt;, change behavior, and introduce bugs -- without telling you. You often find out in production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git-lrc&lt;/code&gt; fixes this.&lt;/strong&gt; It hooks into &lt;code&gt;git commit&lt;/code&gt; and reviews every diff &lt;em&gt;before&lt;/em&gt; it lands. 60-second setup. Completely free.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;See It In Action&lt;/h2&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See git-lrc catch serious security issues such as leaked credentials, expensive cloud
operations, and sensitive material in log statements&lt;/p&gt;
&lt;/blockquote&gt;

  
    
    

    &lt;span class="m-1"&gt;git-lrc-intro-60s.mp4&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;🤖 &lt;strong&gt;AI agents silently break things.&lt;/strong&gt; Code removed. Logic changed. Edge cases gone. You won't notice until production.&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;Catch it before it ships.&lt;/strong&gt; AI-powered inline comments show you &lt;em&gt;exactly&lt;/em&gt; what changed and what looks wrong.&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Build a&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>webdev</category>
      <category>programming</category>
      <category>database</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Inside SQLite’s Frontend: How Your SQL Becomes Bytecode</title>
      <dc:creator>Athreya aka Maneshwar</dc:creator>
      <pubDate>Thu, 19 Mar 2026 18:54:19 +0000</pubDate>
      <link>https://dev.to/lovestaco/inside-sqlites-frontend-how-your-sql-becomes-bytecode-108p</link>
      <guid>https://dev.to/lovestaco/inside-sqlites-frontend-how-your-sql-becomes-bytecode-108p</guid>
      <description>&lt;p&gt;&lt;em&gt;Hello, I'm Maneshwar. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;Star Us&lt;/a&gt; to help devs discover the project. Do give it a try and share your feedback for improving the product.&lt;/em&gt;&lt;/p&gt; 

&lt;p&gt;When you write something as simple as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;SQLite doesn’t execute it directly.&lt;/p&gt;

&lt;p&gt;Instead, it &lt;strong&gt;transforms your SQL into a machine-like program&lt;/strong&gt; that its internal Virtual Machine (VM) can run efficiently. &lt;/p&gt;

&lt;p&gt;This transformation happens in the &lt;strong&gt;frontend&lt;/strong&gt;—one of the most critical (and often overlooked) parts of SQLite.&lt;/p&gt;

&lt;p&gt;This blog breaks down how that frontend works, from raw SQL text to executable bytecode.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is the SQLite Frontend?
&lt;/h2&gt;

&lt;p&gt;Every SQL database needs a way to &lt;strong&gt;understand and execute queries&lt;/strong&gt;. Most databases build complex tree-like structures internally. SQLite takes a different approach.&lt;/p&gt;

&lt;p&gt;It compiles SQL into a &lt;strong&gt;bytecode program&lt;/strong&gt;, similar to a lightweight assembly language.&lt;/p&gt;

&lt;p&gt;This compilation is handled by the &lt;strong&gt;frontend subsystem&lt;/strong&gt;, which:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Preprocesses SQL statements&lt;/li&gt;
&lt;li&gt;Analyzes their structure&lt;/li&gt;
&lt;li&gt;Optimizes them&lt;/li&gt;
&lt;li&gt;Converts them into bytecode&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That bytecode is then executed by SQLite’s backend engine (VM).&lt;/p&gt;

&lt;p&gt;If you ever run:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;EXPLAIN&lt;/span&gt; &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You’ll actually see the &lt;strong&gt;bytecode instructions&lt;/strong&gt; generated by the frontend.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Four Core Components
&lt;/h2&gt;

&lt;p&gt;SQLite’s frontend is built from four key subsystems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Tokenizer&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Parser&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Optimizer&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Code Generator&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Think of it like a compiler pipeline:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SQL → Tokens → Parse Tree → Optimized Tree → Bytecode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Let’s break each one down.&lt;/p&gt;
&lt;h2&gt;
  
  
  1. The Tokenizer (Lexical Analysis)
&lt;/h2&gt;

&lt;p&gt;The tokenizer is the &lt;strong&gt;first point of contact&lt;/strong&gt; for your SQL query.&lt;/p&gt;
&lt;h3&gt;
  
  
  What it does:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Scans the raw SQL string&lt;/li&gt;
&lt;li&gt;Breaks it into &lt;strong&gt;tokens&lt;/strong&gt; (small meaningful units)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Input SQL:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Tokenizer output:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Each of these pieces is called a &lt;strong&gt;token&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Types of Tokens
&lt;/h3&gt;

&lt;p&gt;The tokenizer classifies tokens into categories like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Keywords&lt;/strong&gt; → &lt;code&gt;SELECT&lt;/code&gt;, &lt;code&gt;FROM&lt;/code&gt;, &lt;code&gt;WHERE&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Identifiers&lt;/strong&gt; → table names, column names (&lt;code&gt;users&lt;/code&gt;, &lt;code&gt;name&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Literals&lt;/strong&gt; → &lt;code&gt;'hello'&lt;/code&gt;, &lt;code&gt;123&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Symbols&lt;/strong&gt; → &lt;code&gt;(&lt;/code&gt;, &lt;code&gt;)&lt;/code&gt;, &lt;code&gt;=&lt;/code&gt;, &lt;code&gt;;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SQLite defines &lt;strong&gt;~140 token classes&lt;/strong&gt;, each prefixed with &lt;code&gt;TK_&lt;/code&gt; (e.g., &lt;code&gt;TK_SELECT&lt;/code&gt;, &lt;code&gt;TK_ID&lt;/code&gt;).&lt;/p&gt;
&lt;h3&gt;
  
  
  Key Behaviors
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ignores whitespace and comments&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Uses a &lt;strong&gt;keyword hash table&lt;/strong&gt; to detect SQL keywords&lt;/li&gt;
&lt;li&gt;If something isn’t a keyword → it’s treated as an identifier (&lt;code&gt;TK_ID&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;table1&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;SELECT&lt;/code&gt; → keyword&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;table1&lt;/code&gt; → identifier (&lt;code&gt;TK_ID&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data&lt;/code&gt; → identifier&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Implementation Details
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Main file: &lt;code&gt;tokenize.c&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Keyword lookup: &lt;code&gt;keywordhash.h&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Token definitions: generated via &lt;strong&gt;Lemon parser generator&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  2. The Parser (Structure Builder)
&lt;/h2&gt;

&lt;p&gt;Once tokens are generated, they’re passed to the parser.&lt;/p&gt;
&lt;h3&gt;
  
  
  What it does:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Takes tokens&lt;/li&gt;
&lt;li&gt;Builds a &lt;strong&gt;parse tree&lt;/strong&gt; (structured representation of the query)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;For:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The parser creates a tree like:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
 &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
 &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
 &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="n"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This step ensures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The query is &lt;strong&gt;syntactically valid&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The structure is clearly defined for later stages&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Under the Hood
&lt;/h3&gt;

&lt;p&gt;SQLite uses a tool called &lt;strong&gt;Lemon&lt;/strong&gt; (its own parser generator) to build this system.&lt;/p&gt;
&lt;h2&gt;
  
  
  3. The Optimizer (Making It Fast)
&lt;/h2&gt;

&lt;p&gt;This is where SQLite gets smart.&lt;/p&gt;

&lt;p&gt;The optimizer takes the parse tree and transforms it into a &lt;strong&gt;more efficient version&lt;/strong&gt;—without changing the result.&lt;/p&gt;
&lt;h3&gt;
  
  
  Why Optimization Matters
&lt;/h3&gt;

&lt;p&gt;Two queries can produce the same result but have &lt;strong&gt;very different performance&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If there’s an index on &lt;code&gt;age&lt;/code&gt;, the optimizer ensures SQLite &lt;strong&gt;uses it&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Common Optimization Techniques
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Index selection&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Query rewriting&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Constant folding&lt;/strong&gt; (precomputing values)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Join reordering&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Removing redundant conditions&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Output
&lt;/h3&gt;

&lt;p&gt;The optimizer produces a &lt;strong&gt;new parse tree&lt;/strong&gt; that is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logically equivalent&lt;/li&gt;
&lt;li&gt;Computationally cheaper&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  4. The Code Generator (Final Translation)
&lt;/h2&gt;

&lt;p&gt;This is the final stage of the frontend.&lt;/p&gt;
&lt;h3&gt;
  
  
  What it does:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Walks through the optimized parse tree&lt;/li&gt;
&lt;li&gt;Converts it into &lt;strong&gt;bytecode instructions&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  What is Bytecode?
&lt;/h3&gt;

&lt;p&gt;Bytecode is a low-level instruction set executed by SQLite’s &lt;strong&gt;Virtual Database Engine (VDBE)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Think of it like:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Open table → Scan rows → Apply filter → Return results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Internal Representation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Stored as a &lt;strong&gt;Vdbe object&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Executed step-by-step by SQLite’s VM&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Example (Conceptual)
&lt;/h3&gt;

&lt;p&gt;For:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Generated bytecode might look like:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OpenRead users
Rewind
Column name
ResultRow
Next
Halt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  The Full Flow (End-to-End)
&lt;/h2&gt;

&lt;p&gt;Here’s how everything connects:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Input SQL
   ↓
2. Tokenizer → breaks into tokens
   ↓
3. Parser → builds parse tree
   ↓
4. Optimizer → improves the tree
   ↓
5. Code Generator → emits bytecode
   ↓
6. VDBE → executes bytecode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  The Role of &lt;code&gt;sqlite3_prepare&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;All of this is triggered by a single API call:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;sqlite3_prepare&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This function:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Takes SQL as input&lt;/li&gt;
&lt;li&gt;Runs the entire frontend pipeline&lt;/li&gt;
&lt;li&gt;Produces a &lt;strong&gt;bytecode program&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  What’s Next?
&lt;/h2&gt;

&lt;p&gt;In the next part, we’ll go deeper into:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Parser&lt;/strong&gt; — how SQLite builds and validates query structures using grammar rules.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzvpkxm9mga1pweneahx.png" alt="git-lrc" width="800" height="109"&gt;&lt;/a&gt; &lt;br&gt;
 *AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production. &lt;/p&gt;

&lt;p&gt;git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.* &lt;/p&gt;

&lt;p&gt;Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use. &lt;/p&gt;

&lt;p&gt;⭐ Star it on GitHub: &lt;br&gt;
 &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/HexmosTech" rel="noopener noreferrer"&gt;
        HexmosTech
      &lt;/a&gt; / &lt;a href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;
        git-lrc
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Free, Unlimited AI Code Reviews That Run on Commit
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;p&gt;| &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.da.md" rel="noopener noreferrer"&gt;🇩🇰 Dansk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.es.md" rel="noopener noreferrer"&gt;🇪🇸 Español&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fa.md" rel="noopener noreferrer"&gt;🇮🇷 Farsi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.fi.md" rel="noopener noreferrer"&gt;🇫🇮 Suomi&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ja.md" rel="noopener noreferrer"&gt;🇯🇵 日本語&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.nn.md" rel="noopener noreferrer"&gt;🇳🇴 Norsk&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.pt.md" rel="noopener noreferrer"&gt;🇵🇹 Português&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.ru.md" rel="noopener noreferrer"&gt;🇷🇺 Русский&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.sq.md" rel="noopener noreferrer"&gt;🇦🇱 Shqip&lt;/a&gt; | &lt;a href="https://github.com/HexmosTech/git-lrc/readme/README.zh.md" rel="noopener noreferrer"&gt;🇨🇳 中文&lt;/a&gt; |&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;img width="60" alt="git-lrc logo" src="https://camo.githubusercontent.com/948c8f2d5cf41b48985cd364d48c3a2dc9bfbfd42eab3e0a9a1b3e61f5f17ce3/68747470733a2f2f6865786d6f732e636f6d2f66726565646576746f6f6c732f7075626c69632f6c725f6c6f676f2e737667"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;git-lrc&lt;/h1&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Free, Unlimited AI Code Reviews That Run on Commit&lt;/h2&gt;
&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.producthunt.com/products/git-lrc?embed=true&amp;amp;utm_source=badge-top-post-badge&amp;amp;utm_medium=badge&amp;amp;utm_campaign=badge-git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt" width="200" src="https://camo.githubusercontent.com/87bf2d4283c1e0aa99e254bd17fefb1c67c0c0d39300043a243a4aa633b6cecc/68747470733a2f2f6170692e70726f6475637468756e742e636f6d2f776964676574732f656d6265642d696d6167652f76312f746f702d706f73742d62616467652e7376673f706f73745f69643d31303739323632267468656d653d6c6967687426706572696f643d6461696c7926743d31373731373439313730383638"&gt;&lt;/a&gt;
 &lt;/p&gt;
&lt;br&gt;
&lt;a href="https://goreportcard.com/report/github.com/HexmosTech/git-lrc" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Go Report Card" src="https://camo.githubusercontent.com/e74c0651c3ee9165a2ed01cb0f6842c494029960df30eb9c24cf622d3d21bf46/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f4865786d6f73546563682f6769742d6c7263"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml" rel="noopener noreferrer"&gt;&lt;img alt="gitleaks.yml" title="gitleaks.yml: Secret scanning workflow" src="https://github.com/HexmosTech/git-lrc/actions/workflows/gitleaks.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml" rel="noopener noreferrer"&gt;&lt;img alt="osv-scanner.yml" title="osv-scanner.yml: Dependency vulnerability scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/osv-scanner.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml" rel="noopener noreferrer"&gt;&lt;img alt="govulncheck.yml" title="govulncheck.yml: Go vulnerability check" src="https://github.com/HexmosTech/git-lrc/actions/workflows/govulncheck.yml/badge.svg"&gt;&lt;/a&gt; &lt;a href="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml" rel="noopener noreferrer"&gt;&lt;img alt="semgrep.yml" title="semgrep.yml: Static analysis security scan" src="https://github.com/HexmosTech/git-lrc/actions/workflows/semgrep.yml/badge.svg"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer" href="https://github.com/HexmosTech/git-lrc/./gfx/dependabot-enabled.svg"&gt;&lt;img alt="dependabot-enabled" title="dependabot-enabled: Automated dependency updates are enabled" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FHexmosTech%2Fgit-lrc%2F.%2Fgfx%2Fdependabot-enabled.svg"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;

&lt;p&gt;AI agents write code fast. They also &lt;em&gt;silently remove logic&lt;/em&gt;, change behavior, and introduce bugs -- without telling you. You often find out in production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git-lrc&lt;/code&gt; fixes this.&lt;/strong&gt; It hooks into &lt;code&gt;git commit&lt;/code&gt; and reviews every diff &lt;em&gt;before&lt;/em&gt; it lands. 60-second setup. Completely free.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;See It In Action&lt;/h2&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;See git-lrc catch serious security issues such as leaked credentials, expensive cloud
operations, and sensitive material in log statements&lt;/p&gt;
&lt;/blockquote&gt;

  
    
    

    &lt;span class="m-1"&gt;git-lrc-intro-60s.mp4&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;🤖 &lt;strong&gt;AI agents silently break things.&lt;/strong&gt; Code removed. Logic changed. Edge cases gone. You won't notice until production.&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;Catch it before it ships.&lt;/strong&gt; AI-powered inline comments show you &lt;em&gt;exactly&lt;/em&gt; what changed and what looks wrong.&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Build a&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/HexmosTech/git-lrc" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>webdev</category>
      <category>programming</category>
      <category>database</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
