Your Linear backlog,
as SQL tables.
Issues, projects and teams live in Linear. ChalkSQL reads them as tables, turns your WHERE clause into Linear's own GraphQL filter, and joins the open issues with your helpdesk or warehouse in the same query.
Run SQL against a Linear workspace
Pick a query or write your own, then press Run query. On the right is every GraphQL request ChalkSQL sent to Linear, with the filter it pushed down and how many issues came back.
The team, an IN list on priority and the workflow state become one IssueFilter, so Linear only returns the five matching issues.
Run a query to see the requests.
Results appear here.
The workspace belongs to Fernhill, a fictional analytics company. Its teams, projects and issues are served by a stand-in for Linear's GraphQL API (the issues, projects and teams queries, their filters and cursor pagination), so the exact requests are visible. The connector does not depend on the stand-in: point it at api.linear.app with an API key and it reads a real workspace. ChalkSQL and the connector run live on a Chalk scaling group.
How it works
Linear is a schema provider in ChalkSQL's catalog, next to your warehouse, your databases and your other tools. Queries over it get the same optimizer as everything else.
Issues become a table
Register a Linear API key and linear.issues, linear.projects and linear.teams appear in the catalog, with state, priority, estimate, assignee, labels, project and dates as typed columns.
WHERE becomes an IssueFilter
Before the scan runs, the optimizer offers it the query's predicates. The ones Linear can evaluate go into the GraphQL query's filter variable, so Linear only returns the issues you asked for.
SQL does the rest
Joins with your helpdesk or warehouse, aggregates, date math and anything Linear cannot evaluate run in ChalkSQL. Results stream in a page at a time by following Linear's cursors.
A Linear source in one catalog call
The connector is a ChalkSQL schema provider. Each table is a pushdown-capable batch function over Linear's GraphQL API that translates SQL predicates into the query's filter variable and pages with first and after.
Register it once and Linear is queryable from anywhere ChalkSQL runs, joined with anything else in the catalog.
-- Linear's issues, projects and teams are tables.
SELECT i.identifier, i.title, sum(t.account_arr) AS arr_waiting
FROM linear.issues i
JOIN support.tickets t ON t.linear_issue = i.identifier
WHERE i.team = 'ENG' -- runs in Linear
AND i.priority IN (1, 2) -- runs in Linear
AND contains(i.labels, 'customer-reported') -- runs in Linear
GROUP BY i.identifier, i.title
ORDER BY arr_waiting DESCWhat runs in Linear
The connector only pushes a predicate when Linear can answer it. Everything else stays in ChalkSQL, so a query returns the same rows whether or not it was pushed.
Numbers and dates
=, <, <=, > and >= on priority, estimate, due_date, created_at and completed_at become Linear's eq, lt, lte, gt and gte. IN becomes Linear's in. Exact, so ChalkSQL drops them.
Text
= and LIKE 'x%', '%x' or '%x%' on a title become eq, startsWith, endsWith and contains. Linear's string comparators are case-sensitive, like SQL's, so these are exact too.
Relations
state, team, assignee and project become nested filters such as { state: { type: { eq } } }. IS NULL and IS NOT NULL become { assignee: { null: true } }.
Labels
contains(labels, 'bug') becomes { labels: { some: { name: { eq: 'bug' } } } }, matched against the issue's label set.
<> and NOT IN
These become neq and nin to narrow the scan, but SQL drops NULLs and an API may keep them, so ChalkSQL re-checks the rows that come back.
LIMIT and paging
A LIMIT with no ORDER BY becomes first, and the scan stops once it has enough rows. Otherwise it follows endCursor, 100 issues per page.
Query the tools your team already uses
Linear, Notion, your warehouse and your databases in one SQL query. Talk to an engineer about the sources you want to join.