QQL: A Query Language for Quino

Published by marco on

Updated by marco on

In late 2011 and early 2012, Encodo designed a querying language for Quino. Quino has an ORM that, combined with .NET Linq provides a powerful querying interface for developers. QQL is a DSL that brings this power to non-developers.

QQL never made it to implementation—only specification. In the meantime, the world moved on and we have common, generic querying APIs like OData. The time for QQL is past, but the specification is still an interesting artifact, in its own right.

Who knows? Maybe we’ll get around to implementing some of it, at some point.

At any rate, you can download the specification from Encodo or here at earthli.

The following excerpts should give you an idea of what you’re in for, should you download and read the 80-page document.


The TOC lists the following top-level chapters:

  1. Introduction
  2. Examples
  3. Context & Scopes
  4. Standard Queries
  5. Grouping Queries
  6. Evaluation
  7. Syntax
  8. Data Types and Operators
  9. Libraries
  10. Best Practices
  11. Implementation Details
  12. Future Enhancements

From the abstract in the document:

“The Quino Query Language (QQL) defines a syntax and semantics for formulating data requests against hierarchical data structures. It is easy to read and learn both for those familiar with SQL and non-programmers with a certain capacity for abstract thinking (i.e. power users). Learning only a few basic rules is enough to allow a user to quickly determine which data will be returned by all but the more complex queries. As with any other language, more complex concepts result in more complex texts, but the syntax of QQL limits these cases.”

From the overview:

“QQL defines a syntax and semantics for writing queries against hierarchical data structures. A query describes a set of data by choosing an initial context in the data and specifying which data are to be returned and how the results are to be organized. An execution engine generates this result by applying the query to the data.”


Standard Projections

The follow is from chapter 2.1, “Simple Standard Query”:

The following query returns the first and last name of all active people as well as their 10 most recent time entries, reverse-sorted first by last name, then by first name.

    FirstName; LastName;
    Sample:= TimeEntries { orderby Date desc; limit 10 }
  where Active
    LastName desc;
    FirstName desc;

In chapter 2, there are also “2.2 Intermediate Standard Query” and “2.3 Complex Standard Query” examples.

Grouping Projections

The following is from chapter 2.4, “Simple Grouping Query”:

The following query groups active people by last name and returns the age of the youngest person and the maximum contracts for each last name. Results are ordered by the maximum contracts for each group and then by last name.

group Person
  groupby LastName;
    Age:= (Now − BirthDate.Min).Year;
    MaxContracts:= Contracts.Count.Max
  where Active;
    MaxContracts desc;
    LastName desc;

In chapter 2, there are also “2.5 Complex Grouping Query”, “2.6 Standard Query with Grouping Query” and “2.7 Nested Grouping Queries” examples.