
Context-aware autocomplete
. or a space, with a 50ms debounce. There is no minimum prefix. With nothing typed yet, the popup stays hidden in clauses where listing everything is noise (for example after a comma in a SELECT list); it still opens automatically after FROM, JOIN, ON, and other clauses where browsing helps.
Completion Types
SQL Keywords
Table Names
Tables appear after FROM, JOIN, INSERT INTO, and similar keywords:Column Names
Columns are suggested in SELECT, WHERE, ORDER BY, GROUP BY, and other column contexts. If a FROM clause exists anywhere in the statement (even after the cursor), columns come from those tables. If no FROM clause exists yet, columns from all cached tables appear as fallback; ambiguous names are qualified:users.id, orders.id.
Alias Resolution
Type an alias followed by. to see that table’s columns:
Derived Tables and CTEs
An alias for a subquery (derived table) or aWITH table completes the columns that subquery’s SELECT list produces, including AS renames:
AS name), bare (country), and qualified (t.col) columns resolve. A SELECT * subquery and unaliased expressions like AVG(score) have no name to suggest, so they are skipped.
Functions
SQL functions appear in SELECT, WHERE, and expression contexts:CONVERT_TIMEZONE on Snowflake, SAFE_CAST on BigQuery) appear alongside the common SQL functions.
Operators
Operators the connection’s dialect declares appear in WHERE, ON, HAVING, and AND contexts, each with what it does and the types it works on. On PostgreSQL that covers the JSON operators, array and range containment, regex matching, full-text search, and the network operators:jsonb from the ones json accepts too, so @> is not offered as if it worked on a json column.
Casts
Typing:: offers the dialect’s type names, in the spelling you write rather than the internal catalog name:
MongoDB
MongoDB connections use MQL instead of SQL, and the popup follows the shape of the query rather than SQL clauses. What you get depends on exactly where the cursor is:$match inside a filter document, or $gte where a pipeline stage belongs, is worse than offering nothing. $set and $unset mean different things as an update operator and as a pipeline stage, and the popup describes whichever one applies at the cursor.
Field names come from a sample of the collection’s documents and include nested paths, so a document with address: { city, zip } suggests address, address.city and address.zip. Objects inside an array contribute paths too. Shallower fields sort first. Nothing in the query is executed to build the list.
The sample is cached per collection and cleared when you switch database or refresh the connection.
Completion is suppressed inside comments, and braces or brackets inside a string literal do not count as opening a document.
Favorite Keywords
Favorites you’ve assigned a keyword to (DB-stored or linked-file@keyword frontmatter) appear in the popup as a top-priority match. Type the keyword, accept the suggestion, and the favorite’s full SQL replaces the keyword inline. A ;; in the favorite’s SQL sets where the cursor lands after expansion. See Favorites for how to assign keywords and place the marker.
Schema Names
For databases with multiple schemas (PostgreSQL):public.users resolve in FROM, JOIN, UPDATE, INSERT INTO, and CREATE INDEX.
For databases organized as database, schema, table (Snowflake, BigQuery), every segment completes. Tables of schemas you haven’t opened in the sidebar are fetched on demand:
Schema Cache
On connection, TablePro fetches table names and loads columns in the background. The column cache holds up to 50 tables with LRU eviction. There is no time-based expiry: cached columns stay until you switch databases or refresh the connection. A failed schema load waits 30 seconds before retrying, to avoid hammering the server. After external schema changes (migrations, CLI work), pressCmd+R (Query > Refresh) to reload it. Right-clicking the sidebar’s Tables header and choosing Refresh does the same.

