npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@dortdb/lang-sql

v2.1.1

Published

SQL parser and executor for DortDB

Readme

@dortdb/lang-sql

A SQL language plug-in for DortDB. It adds a PostgreSQL-flavored SELECT language for row-shaped data, meaning arrays of plain JavaScript objects where each object is a row and each property is a column.

Installation

npm install @dortdb/core @dortdb/lang-sql

@dortdb/core is a peer dependency.

Usage

import { DortDB } from '@dortdb/core';
import { defaultRules } from '@dortdb/core/optimizer';
import { SQL } from '@dortdb/lang-sql';

const db = new DortDB({
  mainLang: SQL(),
  optimizer: { rules: defaultRules },
});

db.registerSource(
  ['people'],
  [
    { id: 1, name: 'Alice', city: 'Prague' },
    { id: 2, name: 'Bob', city: 'Ankara' },
    { id: 3, name: 'Carol', city: 'Prague' },
  ],
);

const result = db.query(`
  SELECT city, count(*) AS total
  FROM people
  GROUP BY city
  ORDER BY total DESC
`);
// result.data -> [{ city: 'Prague', total: 2 }, { city: 'Ankara', total: 1 }]

SQL reads sources through the ObjectDataAdapter, which reads each array element as a row and each property as a column. To query data with another shape, such as rows backed by a Map, pass a custom adapter to SQL().

Dialect

The dialect follows PostgreSQL and covers its data-selection subset. It includes a few features other SQL flavors lack.

  • Lateral joins. A JOIN LATERAL (...) subquery can reference tables that appear earlier in the FROM clause, and it runs once per outer row.
  • DISTINCT ON. It keeps the first row per distinct value of the given expressions instead of deduplicating whole rows.
  • Filtered and ordered aggregates, such as count(...) FILTER (WHERE ...), count(DISTINCT ...), and collect(x ORDER BY x).

There is no data definition or modification. CREATE, INSERT, and UPDATE have no equivalent here, because DortDB queries data that already exists in memory. Window functions and grouping sets (ROLLUP, CUBE, GROUPING SETS) are not implemented.

Restrictions without a schema

DortDB sources declare no schema, so the parser rejects queries that a schema would be needed to read one way.

  • An unqualified column requires a single, non-joined source. Otherwise, qualify it as t1.attr. The same holds in ORDER BY, where a SELECT-list alias counts as a bare name, so order by the qualified expression.
  • Natural joins are disabled, because there is no schema to infer the join columns from.
  • Every FROM subquery needs an alias.
  • SELECT * is not supported.
  • Identifiers are case-sensitive. A column that a row does not have is absent from the result instead of raising an error, so a case mismatch shows up as a missing column.

Inside a language that does not prefix identifiers, such as Cypher, prefix a column with the nonlocal schema to resolve it against the surrounding scope. Without that prefix the name resolves against the current table, and the query returns nulls instead of failing.

Documentation

See the SQL overview and the dialect reference, or the full docs at filipjezek.github.io/dortdb.