<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.5">Jekyll</generator><link href="gqlite.org/feed.xml" rel="self" type="application/atom+xml" /><link href="gqlite.org/" rel="alternate" type="text/html" /><updated>2026-02-20T21:01:44+00:00</updated><id>gqlite.org/feed.xml</id><title type="html">GQLite</title><subtitle>GQLite - an embeddable Graph Database library.</subtitle><entry><title type="html">GQLite - Logos/Nom parser</title><link href="gqlite.org/blog/gqlite-logos-nom-parser/" rel="alternate" type="text/html" title="GQLite - Logos/Nom parser" /><published>2026-02-20T17:55:10+00:00</published><updated>2026-02-20T17:55:10+00:00</updated><id>gqlite.org/blog/gqlite-logos-nom-parser</id><content type="html" xml:base="gqlite.org/blog/gqlite-logos-nom-parser/"><![CDATA[<p>Among the exciting new features coming with <a href="https://gqlite.org">GQLite</a> 1.6, there is a new parser based on <a href="https://logos.maciej.codes/">logos</a> for lexing and <a href="https://github.com/rust-bakery/nom">nom</a> for parsing.
This new parser, added to <a href="https://crates.io/crates/gqlparser">gqlparser</a> library, offers increased maintainability and performance. While performance is important, the parser is not a bottleneck in <code class="language-plaintext highlighter-rouge">GQLite</code>. However, the increased maintainability will make it easier to fix some of the parsing bugs, and extend the missing functionalities.</p>

<h2 id="pest">pest</h2>

<p>After trying to use <code class="language-plaintext highlighter-rouge">flex/bison</code>, some 20 years ago, for parsing a programming language, I quickly switched to hand writting lexer and parser. The primary motivation is that those tools tend to have more drawbacks than benefits. However, I believe that it is important to constantly reassess your views, and check if tooling has improved.</p>

<p>While there are dozens of available generators, I don’t have the time to evaluate all of them. When converting <code class="language-plaintext highlighter-rouge">GQLite</code> from <code class="language-plaintext highlighter-rouge">C++</code> to <code class="language-plaintext highlighter-rouge">Rust</code>, I settled on <a href="https://pest.rs/">pest</a>, it appeared to be very popular with <code class="language-plaintext highlighter-rouge">195M</code> downloads on <a href="https://crates.io/crates/pest">crates.io</a>, it has an extension for VSCode and it is maintained. I also liked that the syntax of the grammar makes is closed to the <a href="https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_form">BNF Notation</a>, which makes it easier to read.</p>

<p>While <code class="language-plaintext highlighter-rouge">pest</code> is popular it fell short for GQLite. The core issue: it doesn’t generate a proper parse tree. The resulting data structure is cumbersome, lacks compile-time guarantees, and loses critical parsing information. For a complex language like OpenCypher, this became a major obstacle. It might be suitable for smaller language, but it becomes a major pain with larger language like <code class="language-plaintext highlighter-rouge">OpenCypher</code>. The main problem is that the structure can be simplified to:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">struct</span> <span class="n">Node</span>
<span class="p">{</span>
  <span class="n">rule</span><span class="p">:</span> <span class="n">Rule</span><span class="p">,</span>
  <span class="n">children</span><span class="p">:</span> <span class="nb">Vec</span><span class="o">&lt;</span><span class="n">Node</span><span class="o">&gt;</span><span class="p">,</span> 
<span class="p">}</span>
</code></pre></div></div>

<p>Where <code class="language-plaintext highlighter-rouge">Rule</code> is an enum that specify the rule. So essentially, <code class="language-plaintext highlighter-rouge">pest</code> translate the <code class="language-plaintext highlighter-rouge">text</code> source input into an other structure, that then need to be parsed into your final structure. In theory, the <code class="language-plaintext highlighter-rouge">children</code> part of the structure is constant for each <code class="language-plaintext highlighter-rouge">rule</code>. However, if you want to write safe Rust code, you shouldn’t make that assumption. There has been a number of effort for <code class="language-plaintext highlighter-rouge">pest</code> to provide a parse tree (<a href="https://github.com/pest-parser/ast">pest-ast</a>, <a href="https://github.com/pest-parser/pest/discussions/885">pest 3</a>) but none have delivered yet.</p>

<h2 id="logosnom">logos/nom</h2>

<p>So after deciding to drop <code class="language-plaintext highlighter-rouge">pest</code>, I was left with the choice of trying an other tool, or writting a parser from scratch. The original <code class="language-plaintext highlighter-rouge">C++</code> parser was easy to write, as over the years, I have developed my own toolbox for parsing in <code class="language-plaintext highlighter-rouge">C++</code>. Since, it is the first parser I wrote in <code class="language-plaintext highlighter-rouge">Rust</code>, I had nothing to start with. I looked around to see what is available, and a popular choice in the <code class="language-plaintext highlighter-rouge">Rust</code> ecosystem is <code class="language-plaintext highlighter-rouge">nom</code> with <code class="language-plaintext highlighter-rouge">422M</code> downloads on <a href="https://crates.io/crates/nom">crates.io</a>.</p>

<p>The nice thing about <code class="language-plaintext highlighter-rouge">nom</code> is that it gives you the primitives to work with and write your hand-crafted parser. By default, it works on stream of characters, while I was developing the parser this felt awkward. At least for a language like <code class="language-plaintext highlighter-rouge">OpenCypher</code>, it is more natural to look at it as a stream of token. So I needed a lexer, and after looking for what is available I settled for <a href="https://logos.maciej.codes/">logos</a>, it is well documented, well maintained, and fast.</p>

<table>
  <thead>
    <tr>
      <th>parser</th>
      <th>mean</th>
      <th>median</th>
      <th>slowest</th>
      <th>fastest</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>pest</td>
      <td>1.126 s</td>
      <td>945.2 ms</td>
      <td>2.923 s</td>
      <td>907.3 ms</td>
    </tr>
    <tr>
      <td>nom</td>
      <td>1.194 s</td>
      <td>1.175 s</td>
      <td>1.733 s</td>
      <td>901 ms</td>
    </tr>
    <tr>
      <td>logos/nom</td>
      <td>779.1 ms</td>
      <td>767.7 ms</td>
      <td>1.359 s</td>
      <td>690.4 ms</td>
    </tr>
  </tbody>
</table>

<p>The parsing was done on <a href="https://gitlab.com/auksys/data/gqlite_bench/-/blob/stable/pokec_small_import.cypher?ref_type=heads">pokec_small_import.cypher</a>, a <code class="language-plaintext highlighter-rouge">5MB</code> big, 131716 lines long creation query. You could argue that a different choice of query would give different results. However, when it comes to <code class="language-plaintext highlighter-rouge">OpenCypher</code> the only long queries are the queries for creating nodes. And that is the only time parsing speed has an affect, as can be seen on the <a href="https://benchmarks.gqlite.org/">benchmark</a> results.</p>]]></content><author><name></name></author><category term="blog" /><category term="gqlite" /><summary type="html"><![CDATA[Among the exciting new features coming with GQLite 1.6, there is a new parser based on logos for lexing and nom for parsing. This new parser, added to gqlparser library, offers increased maintainability and performance. While performance is important, the parser is not a bottleneck in GQLite. However, the increased maintainability will make it easier to fix some of the parsing bugs, and extend the missing functionalities.]]></summary></entry><entry><title type="html">GQLite 1.5 - Released</title><link href="gqlite.org/news/gqlite-1-5/" rel="alternate" type="text/html" title="GQLite 1.5 - Released" /><published>2026-01-18T08:02:15+00:00</published><updated>2026-01-18T08:02:15+00:00</updated><id>gqlite.org/news/gqlite-1-5</id><content type="html" xml:base="gqlite.org/news/gqlite-1-5/"><![CDATA[<p>This new release of GQLite brings support for <code class="language-plaintext highlighter-rouge">postgres</code> backend, non-blocking queries in <code class="language-plaintext highlighter-rouge">gqlitebrowser</code> and new functions.</p>

<p>The main new feature is the <code class="language-plaintext highlighter-rouge">postgres</code> backend which is currently implemented as a client-side library, with server-side extension still on the todo list. This pave the way with integration into <a href="https://gitlab.com/auksys/kdb">kDB</a>.
This new backend is on par with other backends in term of supported <code class="language-plaintext highlighter-rouge">OpenCypher</code> queries.</p>

<p>A major change is that only the <code class="language-plaintext highlighter-rouge">redb</code> backend is enabled by default in the <code class="language-plaintext highlighter-rouge">gqlitedb</code> rust crate. However all three backends are enabled for the <code class="language-plaintext highlighter-rouge">python</code>, <code class="language-plaintext highlighter-rouge">ruby</code> and <code class="language-plaintext highlighter-rouge">C/C++</code> bindings.</p>

<p>You can check our <a href="/documentation/5/libraries/gqlite/installation/">installation instructions</a>. And the up-to-date <a href="https://gitlab.com/auksys/GQLite/-/blob/v1.5.0/CHANGELOG.md">changelog</a> for the query enginge.</p>]]></content><author><name></name></author><category term="news" /><summary type="html"><![CDATA[This new release of GQLite brings support for postgres backend, non-blocking queries in gqlitebrowser and new functions.]]></summary></entry><entry><title type="html">GQLite 1.4 - Released</title><link href="gqlite.org/news/gqlite-1-4/" rel="alternate" type="text/html" title="GQLite 1.4 - Released" /><published>2025-11-11T20:47:10+00:00</published><updated>2025-11-11T20:47:10+00:00</updated><id>gqlite.org/news/gqlite-1-4</id><content type="html" xml:base="gqlite.org/news/gqlite-1-4/"><![CDATA[<p>This new release of GQLite brings support for storing timestamps, the introduction of <a href="https://crates.io/crates/gqls">GQLS (GQL Schema)</a>, an ORB-like API for OpenCypher Queries, and paves the way for support of more SQL databases.</p>

<p>It also includes all the fix from the 1.3.x series, including improvement to the GQL GUI Browser, and fixes to query engine.</p>

<p>You can check our <a href="/documentation/5/libraries/gqlite/installation/">installation instructions</a>. And the up-to-date <a href="https://gitlab.com/auksys/GQLite/-/blob/v1.4.0/CHANGELOG.md">changelog</a> for the query enginge.</p>]]></content><author><name></name></author><category term="news" /><summary type="html"><![CDATA[This new release of GQLite brings support for storing timestamps, the introduction of GQLS (GQL Schema), an ORB-like API for OpenCypher Queries, and paves the way for support of more SQL databases.]]></summary></entry><entry><title type="html">GQLite 1.3 - Released</title><link href="gqlite.org/news/gqlite-1-3/" rel="alternate" type="text/html" title="GQLite 1.3 - Released" /><published>2025-09-01T13:55:10+00:00</published><updated>2025-09-01T13:55:10+00:00</updated><id>gqlite.org/news/gqlite-1-3</id><content type="html" xml:base="gqlite.org/news/gqlite-1-3/"><![CDATA[<p>This new release of GQLite brings an upgrade to Redb3, the introduction of <a href="https://crates.io/crates/gqb">GQB (Graph Query Builder)</a> , an API for building OpenCypher Queries, and various improvement to the Rust API.</p>

<p>It also includes all the fix from the 1.2.x series, including the GQL GUI Browser, improvements to aggregation, support for multi-threaded environments.</p>

<p>You can check our <a href="/documentation/5/libraries/gqlite/installation/">installation instructions</a>. And the up-to-date <a href="https://gitlab.com/auksys/GQLite/-/blob/v1.3.0/CHANGELOG.md">changelog</a> for the query enginge.</p>]]></content><author><name></name></author><category term="news" /><summary type="html"><![CDATA[This new release of GQLite brings an upgrade to Redb3, the introduction of GQB (Graph Query Builder) , an API for building OpenCypher Queries, and various improvement to the Rust API.]]></summary></entry><entry><title type="html">GQLite 1.2.1 - Ruby/Python In Rust</title><link href="gqlite.org/blog/gqlite-1-2-1-ruby-python/" rel="alternate" type="text/html" title="GQLite 1.2.1 - Ruby/Python In Rust" /><published>2025-07-17T21:03:59+00:00</published><updated>2025-07-17T21:03:59+00:00</updated><id>gqlite.org/blog/gqlite-1-2-1-ruby-python</id><content type="html" xml:base="gqlite.org/blog/gqlite-1-2-1-ruby-python/"><![CDATA[<p>A new minor version of GQLite was just released, with the new Rust-based bindings for Ruby and Python, which have been pushed to <a href="https://rubygems.org/gems/gqlite">gem</a> and <a href="https://pypi.org/project/gqlitedb/">PyPi</a>.</p>

<p>This release also include the first attempt at looking to support multithreading, through an experimental <code class="language-plaintext highlighter-rouge">ConnecitonServer</code>.</p>]]></content><author><name></name></author><category term="blog" /><summary type="html"><![CDATA[A new minor version of GQLite was just released, with the new Rust-based bindings for Ruby and Python, which have been pushed to gem and PyPi.]]></summary></entry><entry><title type="html">GQLite 1.2 - Released</title><link href="gqlite.org/news/gqlite-1-2/" rel="alternate" type="text/html" title="GQLite 1.2 - Released" /><published>2025-07-13T21:55:11+00:00</published><updated>2025-07-13T21:55:11+00:00</updated><id>gqlite.org/news/gqlite-1-2</id><content type="html" xml:base="gqlite.org/news/gqlite-1-2/"><![CDATA[<p>This is the third release of GQLite. It is an important milestone in the life of the project, it was completely rewritten in Rust. GQLite follow a new architecture with a clear separation between parser, compiler and executer. This new architecture make it easy to integrate with different database backend, currently two backends are supported <a href="https://sqlite.org/">SQLite</a> and (redb)[https://www.redb.org/]. <code class="language-plaintext highlighter-rouge">SQLite</code> is the recommended backend, as the database engine is more mature, while <code class="language-plaintext highlighter-rouge">redb</code> offer a pure-rust alternative for project that requires it.</p>

<p>The roadmap includes support for a Redb and SQLite backends, improvement to the Ruby/Python bindings, continuous improvement to the support of OpenCypher.</p>

<p>You can check our <a href="/documentation/5/libraries/gqlite/installation/">installation instructions</a>.</p>]]></content><author><name></name></author><category term="news" /><summary type="html"><![CDATA[This is the third release of GQLite. It is an important milestone in the life of the project, it was completely rewritten in Rust. GQLite follow a new architecture with a clear separation between parser, compiler and executer. This new architecture make it easy to integrate with different database backend, currently two backends are supported SQLite and (redb)[https://www.redb.org/]. SQLite is the recommended backend, as the database engine is more mature, while redb offer a pure-rust alternative for project that requires it.]]></summary></entry><entry><title type="html">GQlite is moving to auKsys</title><link href="gqlite.org/news/gqlite-moved/" rel="alternate" type="text/html" title="GQlite is moving to auKsys" /><published>2025-06-15T21:09:58+00:00</published><updated>2025-06-15T21:09:58+00:00</updated><id>gqlite.org/news/gqlite-moved</id><content type="html" xml:base="gqlite.org/news/gqlite-moved/"><![CDATA[<p>The <a href="/documentation/5/libraries/gqlite/">GQLite</a> project is joining the auKsys project. GQLite provides a lightweight implementation of <a href="/documentation/5/libraries/gqlite/opencypher/">OpenCypher</a>, a property graph query language. OpenCypher and, its ISO-standardized sibling, GQL are making good progress toward combining advanced Machine Learning and Knowledge Representation. It is very exciting to see what future synergy and integration between GQLite and <a href="/documentation/5/libraries/kdb/">kDB</a> can bring to the idea of autonomous knowledge systems.</p>]]></content><author><name></name></author><category term="news" /><summary type="html"><![CDATA[The GQLite project is joining the auKsys project. GQLite provides a lightweight implementation of OpenCypher, a property graph query language. OpenCypher and, its ISO-standardized sibling, GQL are making good progress toward combining advanced Machine Learning and Knowledge Representation. It is very exciting to see what future synergy and integration between GQLite and kDB can bring to the idea of autonomous knowledge systems.]]></summary></entry><entry><title type="html">gqlite 1.1</title><link href="gqlite.org/news/gqlite-1-1/" rel="alternate" type="text/html" title="gqlite 1.1" /><published>2024-05-18T00:00:00+00:00</published><updated>2024-05-18T00:00:00+00:00</updated><id>gqlite.org/news/gqlite-1-1</id><content type="html" xml:base="gqlite.org/news/gqlite-1-1/"><![CDATA[<p>This is the second release of GQLite. The main improvements is the support for aggregation and OPTIONAL, more details available in the <a href="/documentation/5/libraries/gqlite/opencypher/">documentation</a>.</p>

<p>You can check our <a href="/documentation/5/libraries/gqlite/installation/">installation instructions</a>.</p>]]></content><author><name></name></author><category term="news" /><summary type="html"><![CDATA[Second release with aggregation and OPTIONAL support. And many bug fixes and conformance improvements.]]></summary></entry><entry><title type="html">gqlite 1.0</title><link href="gqlite.org/news/gqlite-1-0/" rel="alternate" type="text/html" title="gqlite 1.0" /><published>2023-11-17T00:00:00+00:00</published><updated>2023-11-17T00:00:00+00:00</updated><id>gqlite.org/news/gqlite-1-0</id><content type="html" xml:base="gqlite.org/news/gqlite-1-0/"><![CDATA[<p>This is the first release of GQLite with support for SQLite backend, and the basic features of OpenCypher Query Language. It can now execute queries on a single graph, called <code class="language-plaintext highlighter-rouge">default</code>. Creation, matching, editing queries are currently supported, more details available in the <a href="/documentation/5/libraries/gqlite/opencypher/">documentation</a>.</p>

<p>GQLite 1.0 can be used in C, C++, Ruby, Python and Crystal program. QML bindings are coming via the <a href="https://gitlab.com/cyloncore/Cyqlops/">Cyqlops library</a>.</p>

<p>You can check our <a href="/documentation/5/libraries/gqlite/installation/">installation instructions</a>.</p>]]></content><author><name></name></author><category term="news" /><summary type="html"><![CDATA[First release, with SQLite backend, graph creation, editing and matching. Bindings for C/C++, Ruby, Python and more.]]></summary></entry></feed>