The Chess Query Language (CQL) is a statically-typed, domain-specific language used to find chess games and positions that match arbitrary criteria.
CQL queries can be used to inspect game characteristics (such as the information provided in PGN tags, starting position, length of the game, etc), position characteristics (locations of pieces on the board, side to move, move number, pins, xrays, squares attacked, pawn structure, etc.), and complex relationships between different positions in a game.
CQL provides a rich set of powerful intrinsic operations and an expressive language by which these may be combined to form concise queries that represent complex search criteria. Matching games are extracted and information about matching components of the query may be dynamically inserted into the game via comments or PGN tags.
About CQL
CQL was developed by Gady Costeff and Lewis Stiller around 2003 being described as a tool “designed to allow researchers, authors, and players to search for games, problems, and studies that match specific themes”. CQL 3 was introduced in EG 151 in January 2004 which provided several examples including the following which finds a pair of positions within a game that are identical except that White is missing between 1 and 10 pieces in the later position.
(match
:pgn heijden.pgn
:output out.pgn
:result 1-0 ;return only win studies
(position
:markall
:relation (:missingpiececount A 1 10)
)
)
CQL 3 provided powerful and innovative search features allowing users to classify endgame studies by theme, extract studies containing specific positional characteristics and inter-positional relationships. The CQL language remained largely unchanged until the release of CQL 5 in 2017 which introduced a more expressive and approachable syntax and increased functionality. Released in 2019, CQL 6 expanded upon this base and CQL 6.1 (the version described in this manual) provides many refinements including support for string and dictionary types, string regular expression matching, generalized tag manipulation, and a dedicated interface for querying the HHdbVI endgame study database.
About CQLi
CQLi is a from-scratch clone of CQL which incorporates many new features and improvements including:
- Imaginary position exploration
CQLi extends the
movefilter to allow exploration of positions not reached within a recorded game. The newimaginefilter allows the board to be temporarily modified in arbitrary ways by placing, removing, or swapping pieces and querying the resulting position. This feature may be used to find unplayed moves that would result in mate, stalemate, or some other condition and is instrumental in using CQLi to solve and generate various types of chess problems.
- Variant support
CQLi fully supports several popular chess variants including Chess960, Crazyhouse, Racing Kings, Atomic, Losing Chess, Suicide, Giveaway, Three-check Chess, King of the Hill, and Horde. The variant of each game is automatically determined from the value of the Variant PGN tag allowing a single PGN file to contain games of different variants. CQLi contains extensions to applicable filters to support these variants and adds new filters to identify variants and their specific win/loss/draw conditions.
- Unicode support
CQLi supports UTF-8 encoded PGN and cql query files. Unicode characters are supported and preserved within PGN strings and comments and within cql queries. String operations are Unicode aware and pattern matching and comparison operations are performed using Unicode aware facilities.
- Powerful Extensibility
The Command Pipe feature allows CQL queries to easily interact with external programs in order to delegate complex operations, such as engine analysis, tablebase lookup, ECO or rating assignments, etc., and utilize the results of those operations within the query.
Other improvements include expressive diagnostics that more precisely identify issues and distinguish errors from warnings, 64-bit numeric types, smarter “smart comments”, greater flexibility over output PGN formatting, transactional evaluation of line filters, unreachable position detection, support for persistent variables in multi-threaded mode, implicit promoted piece tracking, reverse move generation, splitting output across multiple files, cqlbegin and cqlend blocks that are evaluated at the start and end of processing, immediate output using the –nosort option, Polyglot-compatible zobrist key calculation, and scoped variables.
Typographical Conventions
The following typographical conventions are used in this reference manual:
Italic text is used to introduce new terms, refer to specific chess variants, and as a general emphasis mechanism.
Bold monospace textis used when referring to CQL filters, options, chess moves, and inline code snippets.External links are underlined in red and internal links are underlined in blue, such links can be clicked on to navigate to the link target in most pdf readers.
CQL code blocks are presented with syntax highlighting in a blue shaded box.
Chess diagrams use colored circles to draw attention to specific pieces, highlighting to emphasize particular squares, and arrows to represent pertinent moves or rays.
The colors used in this document are intended to be easily distinguishable by readers with various forms of color-blindness. If you are color-blind and have difficulty differentiating the colors used in this document, please let us know.
Notes for CQL6 Users
In most cases CQLi may be used as a drop-in replacement for CQL 6.1 but there are some differences in the feature set and default behaviors that current users of CQL 6.1 should be aware of. The most notable differences are provided below, see here for a more comprehensive accounting of the differences between CQL 6.1 and CQLi.
CQL 6.1 combines multiple comments at a single position into a single conglomerate comment. By default, CQLi will write multiple comments as separate individual comments, e.g.
e4 {A} {B}instead ofe4 {A B}. Use the–coalescecommentsoption to obtain the CQL 6.1 behavior.Variables declared in the body of an iteration filter are not visible outside the filter which may result in a syntax error for queries accepted by CQL 6.1. The solution is to move the declaration outside the iteration filter. See Variable Scopes for more information.
CQLi does not yet support the
--gui,--guipgnstdin, or--guipgnstdoutoptions which are planned for a future version of CQLi. The option-o stdoutcan be used to cause matching games to be printed tostdout.
System Requirements
Supported Operating Systems
Native 64-bit CQLi binaries are provided that support the following platforms:
- Windows 7 SP1 and up.
- macOS 10.14 and up (macOS 11.0 and up for ARM64 builds).
- Linux kernel version 4.15+ with glibc version 2.27+.
Hardware Requirements
- x86-64 or ARM64 (macOS only) compatible CPU.
CQLi will take advantage of multiple cores by default. For relatively slow queries, multi-threaded processing scales well to several processors. For fast queries, IO and other bottlenecks may limit the gains realized by parallel processing.
- 64MB RAM (256MB recommended).
Since, by default, CQLi stores matching games in memory until the end of processing, the amount of memory consumed by CQLi is largely proportional to the number of games matching a particular query and the size of matching games. On average, CQLi will utilize 1-2KB of memory per matching game. The
–nosortoption may be used to prevent the storing of matching games, causing them to be written immediately at the expense of not being sorted first.
File Encoding
PGN database and CQL query files processed by CQLi should be encoded in UTF-8 (note that 7-bit ASCII is a subset of UTF-8). Output generated by CQLi will similarly be UTF-8 encoded. PGN and CQL files with other encodings (such as extended 8-bit ASCII encodings or UTF-16) will need to first be converted to UTF-8 before being processed by CQLi. Such conversions may be performed by tools such as iconv on Linux and macOS, or PowerShell on Windows. Many text editors support conversion to UTF-8 as well. For example, to convert from CP 1251 to UTF-8 with the Windows PowerShell use:
Get-Content -Encoding ([System.Text.Encoding]::GetEncoding(1251)) test.pgn | Set-Content -Encoding utf8 test-utf8.pgn
To perform the same conversion with iconv use:
iconv -f WINDOWS-1251 -t UTF-8 test.pgn -o test-utf8.pgn
Acknowledgements
Thanks to Lewis Stiller and Gady Costeff for designing the CQL language and making the CQL program freely available.
Thanks to Lewis Stiller for his consistent and gracious support which was instrumental in understanding many of the more subtle aspects and design choices of CQL and for the feedback and encouragement he provided during the development of CQLi.