<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://gluesql.org/docs/0.19.0/blog</id>
    <title>GlueSQL Blog</title>
    <updated>2023-11-18T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://gluesql.org/docs/0.19.0/blog"/>
    <subtitle>GlueSQL Blog</subtitle>
    <icon>https://gluesql.org/docs/0.19.0/img/favicon.ico</icon>
    <entry>
        <title type="html"><![CDATA[Release v0.15]]></title>
        <id>https://gluesql.org/docs/0.19.0/blog/release-v0.15</id>
        <link href="https://gluesql.org/docs/0.19.0/blog/release-v0.15"/>
        <updated>2023-11-18T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Release Note - v0.15]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorWithStickyNavbar_LWe7" id="-breaking-changes">🌊 Breaking Changes<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.15#-breaking-changes" class="hash-link" aria-label="Direct link to 🌊 Breaking Changes" title="Direct link to 🌊 Breaking Changes">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="-python-support">🍀 Python Support<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.15#-python-support" class="hash-link" aria-label="Direct link to 🍀 Python Support" title="Direct link to 🍀 Python Support">​</a></h3>
<ul>
<li><a href="https://pypi.org/project/gluesql/" target="_blank" rel="noopener noreferrer">https://pypi.org/project/gluesql/</a></li>
</ul>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="code-samples">Code Samples<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.15#code-samples" class="hash-link" aria-label="Direct link to Code Samples" title="Direct link to Code Samples">​</a></h4>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> gluesql </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> Glue</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> MemoryStorage</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> tabulate </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> tabulate</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">db </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> Glue</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">MemoryStorage</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">sql </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token triple-quoted-string string" style="color:#e3116c">"""</span><br></span><span class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    SELECT</span><br></span><span class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    u.name as user,</span><br></span><span class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    d.name as device</span><br></span><span class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    FROM User u</span><br></span><span class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    JOIN Device d ON u.id = d.userId</span><br></span><span class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">"""</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">strip</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">replace</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"    "</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">""</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">result </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> db</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">query</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">sql</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">rows </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> result</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"rows"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string-interpolation string" style="color:#e3116c">f"\n[Query]\n</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">sql</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">tabulate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">rows</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> headers</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"keys"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> showindex</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> tablefmt</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"simple_outline"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<ul>
<li>feat: Implement Python Binding <a href="https://github.com/jopemachine" target="_blank" rel="noopener noreferrer">@jopemachine</a> (<a href="https://github.com/gluesql/gluesql/pull/1357" target="_blank" rel="noopener noreferrer">#1357</a>)</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="-redis-storage">🍀 Redis Storage<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.15#-redis-storage" class="hash-link" aria-label="Direct link to 🍀 Redis Storage" title="Direct link to 🍀 Redis Storage">​</a></h3>
<ul>
<li>Feature: redis storage <a href="https://github.com/gurugio" target="_blank" rel="noopener noreferrer">@gurugio</a> (<a href="https://github.com/gluesql/gluesql/pull/1396" target="_blank" rel="noopener noreferrer">#1396</a>)</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="-csv-storage">🍀 CSV Storage<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.15#-csv-storage" class="hash-link" aria-label="Direct link to 🍀 CSV Storage" title="Direct link to 🍀 CSV Storage">​</a></h3>
<ul>
<li>Add CsvStorage support to CLI &amp; Rust package <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1437" target="_blank" rel="noopener noreferrer">#1437</a>)</li>
<li>Implement CSV Storage, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1280" target="_blank" rel="noopener noreferrer">#1280</a>)</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="-more-operators-and-functions">🍀 More operators and functions<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.15#-more-operators-and-functions" class="hash-link" aria-label="Direct link to 🍀 More operators and functions" title="Direct link to 🍀 More operators and functions">​</a></h3>
<ul>
<li>feat: add index_by node <a href="https://github.com/seonghun-dev" target="_blank" rel="noopener noreferrer">@seonghun-dev</a> (<a href="https://github.com/gluesql/gluesql/pull/1355" target="_blank" rel="noopener noreferrer">#1355</a>)</li>
<li>Implement DEDUP function <a href="https://github.com/jinlee0" target="_blank" rel="noopener noreferrer">@jinlee0</a> (<a href="https://github.com/gluesql/gluesql/pull/1430" target="_blank" rel="noopener noreferrer">#1430</a>)</li>
<li>Bitwise Shift Right Operator Implementation <a href="https://github.com/2-NOW" target="_blank" rel="noopener noreferrer">@2-NOW</a> (<a href="https://github.com/gluesql/gluesql/pull/1394" target="_blank" rel="noopener noreferrer">#1394</a>)</li>
<li>feat: implement ast_builder for values function <a href="https://github.com/tgsong827" target="_blank" rel="noopener noreferrer">@tgsong827</a> (<a href="https://github.com/gluesql/gluesql/pull/1375" target="_blank" rel="noopener noreferrer">#1375</a>)</li>
<li>Implement <code>ADD_MONTH</code> function  <a href="https://github.com/kite707" target="_blank" rel="noopener noreferrer">@kite707</a> (<a href="https://github.com/gluesql/gluesql/pull/1341" target="_blank" rel="noopener noreferrer">#1341</a>)</li>
<li>Implement <code>SPLICE</code> function <a href="https://github.com/jinlee0" target="_blank" rel="noopener noreferrer">@jinlee0</a> (<a href="https://github.com/gluesql/gluesql/pull/1371" target="_blank" rel="noopener noreferrer">#1371</a>)</li>
<li>Implement <code>SLICE</code> function <a href="https://github.com/Kwontaehwon" target="_blank" rel="noopener noreferrer">@Kwontaehwon</a> (<a href="https://github.com/gluesql/gluesql/pull/1340" target="_blank" rel="noopener noreferrer">#1340</a>)</li>
<li>Implement entries in ast builder <a href="https://github.com/2-NOW" target="_blank" rel="noopener noreferrer">@2-NOW</a> (<a href="https://github.com/gluesql/gluesql/pull/1364" target="_blank" rel="noopener noreferrer">#1364</a>)</li>
<li>Implement GREATEST function <a href="https://github.com/TheMan1697" target="_blank" rel="noopener noreferrer">@TheMan1697</a> (<a href="https://github.com/gluesql/gluesql/pull/1312" target="_blank" rel="noopener noreferrer">#1312</a>)</li>
<li>Implement bitwise-not operator (~) in ast builder <a href="https://github.com/gurugio" target="_blank" rel="noopener noreferrer">@gurugio</a> (<a href="https://github.com/gluesql/gluesql/pull/1366" target="_blank" rel="noopener noreferrer">#1366</a>)</li>
<li>Implement COALESCE function <a href="https://github.com/cake-monotone" target="_blank" rel="noopener noreferrer">@cake-monotone</a> (<a href="https://github.com/gluesql/gluesql/pull/1333" target="_blank" rel="noopener noreferrer">#1333</a>)</li>
<li>feat: Implement select without table function in ast_builder <a href="https://github.com/ding-co" target="_blank" rel="noopener noreferrer">@ding-co</a> (<a href="https://github.com/gluesql/gluesql/pull/1365" target="_blank" rel="noopener noreferrer">#1365</a>)</li>
<li>Add ExprWithAliasNode to ast builder <a href="https://github.com/julia-ing" target="_blank" rel="noopener noreferrer">@julia-ing</a> (<a href="https://github.com/gluesql/gluesql/pull/1359" target="_blank" rel="noopener noreferrer">#1359</a>)</li>
<li>feat: Implement take function in ast_builder <a href="https://github.com/ding-co" target="_blank" rel="noopener noreferrer">@ding-co</a> (<a href="https://github.com/gluesql/gluesql/pull/1346" target="_blank" rel="noopener noreferrer">#1346</a>)</li>
<li>Implement last_day function in ast_builder <a href="https://github.com/cjy13753" target="_blank" rel="noopener noreferrer">@cjy13753</a> (<a href="https://github.com/gluesql/gluesql/pull/1344" target="_blank" rel="noopener noreferrer">#1344</a>)</li>
<li>Implement LAST_DAY function <a href="https://github.com/gluesql/gluesql/pull/1315" target="_blank" rel="noopener noreferrer">#1315</a> <a href="https://github.com/cjy13753" target="_blank" rel="noopener noreferrer">@cjy13753</a> (<a href="https://github.com/gluesql/gluesql/pull/1323" target="_blank" rel="noopener noreferrer">#1323</a>)</li>
<li>Implement ast_builder for is_empty function <a href="https://github.com/julia-ing" target="_blank" rel="noopener noreferrer">@julia-ing</a> (<a href="https://github.com/gluesql/gluesql/pull/1337" target="_blank" rel="noopener noreferrer">#1337</a>)</li>
<li>Implement <code>ast_builder</code> for skip function <a href="https://github.com/cl-kim" target="_blank" rel="noopener noreferrer">@cl-kim</a> (<a href="https://github.com/gluesql/gluesql/pull/1334" target="_blank" rel="noopener noreferrer">#1334</a>)</li>
<li>Implement ENTRIES function <a href="https://github.com/2-NOW" target="_blank" rel="noopener noreferrer">@2-NOW</a> (<a href="https://github.com/gluesql/gluesql/pull/1315" target="_blank" rel="noopener noreferrer">#1315</a>)</li>
<li>Feature/operator bit not <a href="https://github.com/gurugio" target="_blank" rel="noopener noreferrer">@gurugio</a> (<a href="https://github.com/gluesql/gluesql/pull/1321" target="_blank" rel="noopener noreferrer">#1321</a>)</li>
<li>Implement Skip function <a href="https://github.com/cl-kim" target="_blank" rel="noopener noreferrer">@cl-kim</a> (<a href="https://github.com/gluesql/gluesql/pull/1325" target="_blank" rel="noopener noreferrer">#1325</a>)</li>
<li>Implement VALUES function for Map type <a href="https://github.com/tgsong827" target="_blank" rel="noopener noreferrer">@tgsong827</a> (<a href="https://github.com/gluesql/gluesql/pull/1288" target="_blank" rel="noopener noreferrer">#1288</a>)</li>
<li>Feat: impl bitwise-and operation <a href="https://github.com/jinlee0" target="_blank" rel="noopener noreferrer">@jinlee0</a> (<a href="https://github.com/gluesql/gluesql/pull/1281" target="_blank" rel="noopener noreferrer">#1281</a>)</li>
<li>Implement BIT_SHIFT_LEFT operation <a href="https://github.com/codernineteen" target="_blank" rel="noopener noreferrer">@codernineteen</a> (<a href="https://github.com/gluesql/gluesql/pull/1286" target="_blank" rel="noopener noreferrer">#1286</a>)</li>
<li>implement <code>SORT</code> function <a href="https://github.com/Jaehui-Lee" target="_blank" rel="noopener noreferrer">@Jaehui-Lee</a> (<a href="https://github.com/gluesql/gluesql/pull/1300" target="_blank" rel="noopener noreferrer">#1300</a>)</li>
<li>feat: Implement <code>LENGTH</code> function <a href="https://github.com/jopemachine" target="_blank" rel="noopener noreferrer">@jopemachine</a> (<a href="https://github.com/gluesql/gluesql/pull/1298" target="_blank" rel="noopener noreferrer">#1298</a>)</li>
<li>[Function] Implement TAKE function  <a href="https://github.com/ding-co" target="_blank" rel="noopener noreferrer">@ding-co</a> (<a href="https://github.com/gluesql/gluesql/pull/1283" target="_blank" rel="noopener noreferrer">#1283</a>)</li>
<li>feat: implement <code>ast_builder</code> for replace function <a href="https://github.com/ChobobDev" target="_blank" rel="noopener noreferrer">@ChobobDev</a> (<a href="https://github.com/gluesql/gluesql/pull/1275" target="_blank" rel="noopener noreferrer">#1275</a>)</li>
<li>feat: implement IS_EMPTY function <a href="https://github.com/julia-ing" target="_blank" rel="noopener noreferrer">@julia-ing</a> (<a href="https://github.com/gluesql/gluesql/pull/1282" target="_blank" rel="noopener noreferrer">#1282</a>)</li>
<li>[Function] Implement REPLACE function <a href="https://github.com/ChobobDev" target="_blank" rel="noopener noreferrer">@ChobobDev</a> (<a href="https://github.com/gluesql/gluesql/pull/1266" target="_blank" rel="noopener noreferrer">#1266</a>)</li>
<li>Implement MD5 Function <a href="https://github.com/seonghun-dev" target="_blank" rel="noopener noreferrer">@seonghun-dev</a> (<a href="https://github.com/gluesql/gluesql/pull/1242" target="_blank" rel="noopener noreferrer">#1242</a>)</li>
<li>[AST Builder] Implement ascii, chr function in ast <a href="https://github.com/seonghun-dev" target="_blank" rel="noopener noreferrer">@seonghun-dev</a> (<a href="https://github.com/gluesql/gluesql/pull/1244" target="_blank" rel="noopener noreferrer">#1244</a>)</li>
<li>[AST Builder] Implement Geometic Point Type and Geometric Function in AST Builder <a href="https://github.com/seonghun-dev" target="_blank" rel="noopener noreferrer">@seonghun-dev</a> (<a href="https://github.com/gluesql/gluesql/pull/1222" target="_blank" rel="noopener noreferrer">#1222</a>)</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="-features">🚀 Features<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.15#-features" class="hash-link" aria-label="Direct link to 🚀 Features" title="Direct link to 🚀 Features">​</a></h2>
<ul>
<li>feat: implement <code>select</code> iterator utility function <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1429" target="_blank" rel="noopener noreferrer">#1429</a>)</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="-improvements">🌟 Improvements<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.15#-improvements" class="hash-link" aria-label="Direct link to 🌟 Improvements" title="Direct link to 🌟 Improvements">​</a></h2>
<ul>
<li>Fix parsing of BigDecimal literals with zero fraction part as floats, not integer <a href="https://github.com/zmrdltl" target="_blank" rel="noopener noreferrer">@zmrdltl</a> (<a href="https://github.com/gluesql/gluesql/pull/1416" target="_blank" rel="noopener noreferrer">#1416</a>)</li>
<li>Update docs/ast-builder padding.md code block lang keyword, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1436" target="_blank" rel="noopener noreferrer">#1436</a>)</li>
<li>Support StoreMut trait to Optional  <a href="https://github.com/seonghun-dev" target="_blank" rel="noopener noreferrer">@seonghun-dev</a> (<a href="https://github.com/gluesql/gluesql/pull/1435" target="_blank" rel="noopener noreferrer">#1435</a>)</li>
<li>docs: write docmentation for padding <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1434" target="_blank" rel="noopener noreferrer">#1434</a>)</li>
<li>test: add test cases for astb-padding <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1433" target="_blank" rel="noopener noreferrer">#1433</a>)</li>
<li>Upgrade to chrono v0.4.31 and adjust millisecond value in Timestamp Creation <a href="https://github.com/zmrdltl" target="_blank" rel="noopener noreferrer">@zmrdltl</a> (<a href="https://github.com/gluesql/gluesql/pull/1427" target="_blank" rel="noopener noreferrer">#1427</a>)</li>
<li>Remove unnecessary comments in evalaute/function.rs <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1431" target="_blank" rel="noopener noreferrer">#1431</a>)</li>
<li>write docmentation for character_conversion <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1428" target="_blank" rel="noopener noreferrer">#1428</a>)</li>
<li>docs: Add <code>SLICE</code> function doc <a href="https://github.com/fregataa" target="_blank" rel="noopener noreferrer">@fregataa</a> (<a href="https://github.com/gluesql/gluesql/pull/1425" target="_blank" rel="noopener noreferrer">#1425</a>)</li>
<li>test: add cases to character_conversion <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1424" target="_blank" rel="noopener noreferrer">#1424</a>)</li>
<li>docs<!-- -->:Add<!-- --> doc about SPLICE function <a href="https://github.com/jinlee0" target="_blank" rel="noopener noreferrer">@jinlee0</a> (<a href="https://github.com/gluesql/gluesql/pull/1423" target="_blank" rel="noopener noreferrer">#1423</a>)</li>
<li>Change store RowIter type from Iterator to Stream <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1419" target="_blank" rel="noopener noreferrer">#1419</a>)</li>
<li>Reflect Deprecation of <code>from_utc</code> in Crate <code>chrono</code> <a href="https://github.com/zmrdltl" target="_blank" rel="noopener noreferrer">@zmrdltl</a> (<a href="https://github.com/gluesql/gluesql/pull/1415" target="_blank" rel="noopener noreferrer">#1415</a>)</li>
<li>Remove eval_to_{int|float..} macro uses in core/../evaluate/function.rs, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1361" target="_blank" rel="noopener noreferrer">#1361</a>)</li>
<li>test: write example for ast builder <a href="https://github.com/daengdaengLee" target="_blank" rel="noopener noreferrer">@daengdaengLee</a> (<a href="https://github.com/gluesql/gluesql/pull/1259" target="_blank" rel="noopener noreferrer">#1259</a>)</li>
<li>Fix merge conflict in data/value/mod.rs <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1406" target="_blank" rel="noopener noreferrer">#1406</a>)</li>
<li>chore: implement <code>ConvertError</code>, <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1401" target="_blank" rel="noopener noreferrer">#1401</a>)</li>
<li>refactor: remove implementation of from Value trait for Evaluated <a href="https://github.com/tgsong827" target="_blank" rel="noopener noreferrer">@tgsong827</a> (<a href="https://github.com/gluesql/gluesql/pull/1399" target="_blank" rel="noopener noreferrer">#1399</a>)</li>
<li>refactor: update function module's namespacing in ast_builder <a href="https://github.com/tgsong827" target="_blank" rel="noopener noreferrer">@tgsong827</a> (<a href="https://github.com/gluesql/gluesql/pull/1398" target="_blank" rel="noopener noreferrer">#1398</a>)</li>
<li>chore: remove <code>Result</code> from <code>ast_builder::transaction</code> return type <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1404" target="_blank" rel="noopener noreferrer">#1404</a>)</li>
<li>chore: bump rust version to 1.72 <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1388" target="_blank" rel="noopener noreferrer">#1388</a>)</li>
<li>chore: add example of convert from payload to custom struct <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1379" target="_blank" rel="noopener noreferrer">#1379</a>)</li>
<li>Update Chrono version to 0.4.26, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1374" target="_blank" rel="noopener noreferrer">#1374</a>)</li>
<li>Update test-suite Tester::run to return Payload, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1373" target="_blank" rel="noopener noreferrer">#1373</a>)</li>
<li>Remove .unwrap() uses in test-suite/ test codes, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1372" target="_blank" rel="noopener noreferrer">#1372</a>)</li>
<li>Replace run!, test! and count! macros in test-suite to Tester methods, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1368" target="_blank" rel="noopener noreferrer">#1368</a>)</li>
<li>Update coverage.yml gh-action to ignore await only lines, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1370" target="_blank" rel="noopener noreferrer">#1370</a>)</li>
<li>Apply pretty_assertions::assert_eq! to core/ ast_builder unit tests <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1369" target="_blank" rel="noopener noreferrer">#1369</a>)</li>
<li>Simplify value evaluate cmp with literal <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1353" target="_blank" rel="noopener noreferrer">#1353</a>)</li>
<li>Update gh-action author assign - add zmrdltl to reviewers <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1342" target="_blank" rel="noopener noreferrer">#1342</a>)</li>
<li>Refactor GCD and LCM functions <a href="https://github.com/cake-monotone" target="_blank" rel="noopener noreferrer">@cake-monotone</a> (<a href="https://github.com/gluesql/gluesql/pull/1331" target="_blank" rel="noopener noreferrer">#1331</a>)</li>
<li>Refactor write_rows <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1319" target="_blank" rel="noopener noreferrer">#1319</a>)</li>
<li>Js pkg wasm pack build not to generate readme and packagejson <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1327" target="_blank" rel="noopener noreferrer">#1327</a>)</li>
<li>Update pkg/javascript dist directories to use dist_web/ and dist_node… <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1326" target="_blank" rel="noopener noreferrer">#1326</a>)</li>
<li>Upgrade bigdecimal to 0.4.1, sqlparser to 0.36.1 <a href="https://github.com/jinlee0" target="_blank" rel="noopener noreferrer">@jinlee0</a> (<a href="https://github.com/gluesql/gluesql/pull/1322" target="_blank" rel="noopener noreferrer">#1322</a>)</li>
<li>Update wasm-pack-action version to 0.4.0, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1316" target="_blank" rel="noopener noreferrer">#1316</a>)</li>
<li>Update JavaScript package load_indexeddb method to get namespace as a… <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1320" target="_blank" rel="noopener noreferrer">#1320</a>)</li>
<li>Upgrade sqlparser-rs version to 0.35, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1292" target="_blank" rel="noopener noreferrer">#1292</a>)</li>
<li>Remove unused error variant in JsonStorage <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1278" target="_blank" rel="noopener noreferrer">#1278</a>)</li>
<li>Implement CAST text literal or value to MAP or LIST, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1267" target="_blank" rel="noopener noreferrer">#1267</a>)</li>
<li>Simplity JsonStorage Store::fetch_all_schemas codes, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1264" target="_blank" rel="noopener noreferrer">#1264</a>)</li>
<li>Change console.log in gluesql.js -&gt; console.debug <a href="https://github.com/parkma99" target="_blank" rel="noopener noreferrer">@parkma99</a> (<a href="https://github.com/gluesql/gluesql/pull/1256" target="_blank" rel="noopener noreferrer">#1256</a>)</li>
<li>Replace <code>actions-rs/toolchain</code> with <code>dtolnay/rust-toolchain</code> <a href="https://github.com/jongwooo" target="_blank" rel="noopener noreferrer">@jongwooo</a> (<a href="https://github.com/gluesql/gluesql/pull/1251" target="_blank" rel="noopener noreferrer">#1251</a>)</li>
<li>ci: Automatically assign a PR to its author <a href="https://github.com/rapsealk" target="_blank" rel="noopener noreferrer">@rapsealk</a> (<a href="https://github.com/gluesql/gluesql/pull/1253" target="_blank" rel="noopener noreferrer">#1253</a>)</li>
<li>Remove sync methods in core/ Glue struct, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1247" target="_blank" rel="noopener noreferrer">#1247</a>)</li>
<li>Remove test function in test-suite tester, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1246" target="_blank" rel="noopener noreferrer">#1246</a>)</li>
<li>fix: allow interval cast-related functions to accept only literals instead of evaluations <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1238" target="_blank" rel="noopener noreferrer">#1238</a>)</li>
<li>Split custom Partial{Eq|Ord} impl of Value &amp; Literal into evaluate_{eq|cmp} <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1233" target="_blank" rel="noopener noreferrer">#1233</a>)</li>
<li>Improve example codes formatting <a href="https://github.com/jopemachine" target="_blank" rel="noopener noreferrer">@jopemachine</a> (<a href="https://github.com/gluesql/gluesql/pull/1235" target="_blank" rel="noopener noreferrer">#1235</a>)</li>
<li>feat: fmt list and map <a href="https://github.com/Mehrbod2002" target="_blank" rel="noopener noreferrer">@Mehrbod2002</a> (<a href="https://github.com/gluesql/gluesql/pull/1226" target="_blank" rel="noopener noreferrer">#1226</a>)</li>
<li>Update README.md - add blog article links <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1232" target="_blank" rel="noopener noreferrer">#1232</a>)</li>
<li>Write the blog article - revolutionizing databases by unifying the qu… <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1231" target="_blank" rel="noopener noreferrer">#1231</a>)</li>
<li>Write the blog article - test driven documentation <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1229" target="_blank" rel="noopener noreferrer">#1229</a>)</li>
<li>Write the blog article - breaking the boundary between sql and nosql … <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1228" target="_blank" rel="noopener noreferrer">#1228</a>)</li>
<li>Add test and doc for ast-builder::statements::querying::data-aggregation <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1224" target="_blank" rel="noopener noreferrer">#1224</a>)</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="-bug-fixes">🐛 Bug Fixes<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.15#-bug-fixes" class="hash-link" aria-label="Direct link to 🐛 Bug Fixes" title="Direct link to 🐛 Bug Fixes">​</a></h2>
<ul>
<li>fix: Literal comparison with BinaryOperator <a href="https://github.com/ding-co" target="_blank" rel="noopener noreferrer">@ding-co</a> (<a href="https://github.com/gluesql/gluesql/pull/1397" target="_blank" rel="noopener noreferrer">#1397</a>)</li>
<li>fix: update Key.cmp to compare a type with other type <a href="https://github.com/tgsong827" target="_blank" rel="noopener noreferrer">@tgsong827</a> (<a href="https://github.com/gluesql/gluesql/pull/1367" target="_blank" rel="noopener noreferrer">#1367</a>)</li>
<li>Fix Value::evaluate_cmp_with_literal between Decimal and Literal::Num… <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1352" target="_blank" rel="noopener noreferrer">#1352</a>)</li>
<li>Fix spool on <code>tabular off</code> and <code>SelectMap</code> <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1314" target="_blank" rel="noopener noreferrer">#1314</a>)</li>
<li>Update auto-assign-action to be triggered on PR open from fork repos <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1313" target="_blank" rel="noopener noreferrer">#1313</a>)</li>
<li>Fix Scala Subquery should contain only 1 column <a href="https://github.com/ChobobDev" target="_blank" rel="noopener noreferrer">@ChobobDev</a> (<a href="https://github.com/gluesql/gluesql/pull/1284" target="_blank" rel="noopener noreferrer">#1284</a>)</li>
<li>Wrap config path by quotes in auto-author-assign.yml <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1258" target="_blank" rel="noopener noreferrer">#1258</a>)</li>
<li>Apply word-wrap to docs/ article h1 <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1230" target="_blank" rel="noopener noreferrer">#1230</a>)</li>
<li>Fix docusaurus.config.js themeConfig handler <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1225" target="_blank" rel="noopener noreferrer">#1225</a>)</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="-new-contributors">👏 New Contributors<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.15#-new-contributors" class="hash-link" aria-label="Direct link to 👏 New Contributors" title="Direct link to 👏 New Contributors">​</a></h2>
<ul>
<li><a href="https://github.com/Mehrbod2002" target="_blank" rel="noopener noreferrer">@Mehrbod2002</a> made their first contribution in <a href="https://github.com/gluesql/gluesql/pull/1226" target="_blank" rel="noopener noreferrer">https://github.com/gluesql/gluesql/pull/1226</a></li>
<li><a href="https://github.com/jopemachine" target="_blank" rel="noopener noreferrer">@jopemachine</a> made their first contribution in <a href="https://github.com/gluesql/gluesql/pull/1235" target="_blank" rel="noopener noreferrer">https://github.com/gluesql/gluesql/pull/1235</a></li>
<li><a href="https://github.com/rapsealk" target="_blank" rel="noopener noreferrer">@rapsealk</a> made their first contribution in <a href="https://github.com/gluesql/gluesql/pull/1253" target="_blank" rel="noopener noreferrer">https://github.com/gluesql/gluesql/pull/1253</a></li>
<li><a href="https://github.com/parkma99" target="_blank" rel="noopener noreferrer">@parkma99</a> made their first contribution in <a href="https://github.com/gluesql/gluesql/pull/1256" target="_blank" rel="noopener noreferrer">https://github.com/gluesql/gluesql/pull/1256</a></li>
<li><a href="https://github.com/julia-ing" target="_blank" rel="noopener noreferrer">@julia-ing</a> made their first contribution in <a href="https://github.com/gluesql/gluesql/pull/1282" target="_blank" rel="noopener noreferrer">https://github.com/gluesql/gluesql/pull/1282</a></li>
<li><a href="https://github.com/ding-co" target="_blank" rel="noopener noreferrer">@ding-co</a> made their first contribution in <a href="https://github.com/gluesql/gluesql/pull/1283" target="_blank" rel="noopener noreferrer">https://github.com/gluesql/gluesql/pull/1283</a></li>
<li><a href="https://github.com/Jaehui-Lee" target="_blank" rel="noopener noreferrer">@Jaehui-Lee</a> made their first contribution in <a href="https://github.com/gluesql/gluesql/pull/1300" target="_blank" rel="noopener noreferrer">https://github.com/gluesql/gluesql/pull/1300</a></li>
<li><a href="https://github.com/jinlee0" target="_blank" rel="noopener noreferrer">@jinlee0</a> made their first contribution in <a href="https://github.com/gluesql/gluesql/pull/1322" target="_blank" rel="noopener noreferrer">https://github.com/gluesql/gluesql/pull/1322</a></li>
<li><a href="https://github.com/codernineteen" target="_blank" rel="noopener noreferrer">@codernineteen</a> made their first contribution in <a href="https://github.com/gluesql/gluesql/pull/1286" target="_blank" rel="noopener noreferrer">https://github.com/gluesql/gluesql/pull/1286</a></li>
<li><a href="https://github.com/tgsong827" target="_blank" rel="noopener noreferrer">@tgsong827</a> made their first contribution in <a href="https://github.com/gluesql/gluesql/pull/1288" target="_blank" rel="noopener noreferrer">https://github.com/gluesql/gluesql/pull/1288</a></li>
<li><a href="https://github.com/cl-kim" target="_blank" rel="noopener noreferrer">@cl-kim</a> made their first contribution in <a href="https://github.com/gluesql/gluesql/pull/1325" target="_blank" rel="noopener noreferrer">https://github.com/gluesql/gluesql/pull/1325</a></li>
<li><a href="https://github.com/gurugio" target="_blank" rel="noopener noreferrer">@gurugio</a> made their first contribution in <a href="https://github.com/gluesql/gluesql/pull/1321" target="_blank" rel="noopener noreferrer">https://github.com/gluesql/gluesql/pull/1321</a></li>
<li><a href="https://github.com/2-NOW" target="_blank" rel="noopener noreferrer">@2-NOW</a> made their first contribution in <a href="https://github.com/gluesql/gluesql/pull/1315" target="_blank" rel="noopener noreferrer">https://github.com/gluesql/gluesql/pull/1315</a></li>
<li><a href="https://github.com/cake-monotone" target="_blank" rel="noopener noreferrer">@cake-monotone</a> made their first contribution in <a href="https://github.com/gluesql/gluesql/pull/1331" target="_blank" rel="noopener noreferrer">https://github.com/gluesql/gluesql/pull/1331</a></li>
<li><a href="https://github.com/cjy13753" target="_blank" rel="noopener noreferrer">@cjy13753</a> made their first contribution in <a href="https://github.com/gluesql/gluesql/pull/1323" target="_blank" rel="noopener noreferrer">https://github.com/gluesql/gluesql/pull/1323</a></li>
<li><a href="https://github.com/TheMan1697" target="_blank" rel="noopener noreferrer">@TheMan1697</a> made their first contribution in <a href="https://github.com/gluesql/gluesql/pull/1312" target="_blank" rel="noopener noreferrer">https://github.com/gluesql/gluesql/pull/1312</a></li>
<li><a href="https://github.com/Kwontaehwon" target="_blank" rel="noopener noreferrer">@Kwontaehwon</a> made their first contribution in <a href="https://github.com/gluesql/gluesql/pull/1340" target="_blank" rel="noopener noreferrer">https://github.com/gluesql/gluesql/pull/1340</a></li>
<li><a href="https://github.com/kite707" target="_blank" rel="noopener noreferrer">@kite707</a> made their first contribution in <a href="https://github.com/gluesql/gluesql/pull/1341" target="_blank" rel="noopener noreferrer">https://github.com/gluesql/gluesql/pull/1341</a></li>
<li><a href="https://github.com/daengdaengLee" target="_blank" rel="noopener noreferrer">@daengdaengLee</a> made their first contribution in <a href="https://github.com/gluesql/gluesql/pull/1259" target="_blank" rel="noopener noreferrer">https://github.com/gluesql/gluesql/pull/1259</a></li>
<li><a href="https://github.com/fregataa" target="_blank" rel="noopener noreferrer">@fregataa</a> made their first contribution in <a href="https://github.com/gluesql/gluesql/pull/1425" target="_blank" rel="noopener noreferrer">https://github.com/gluesql/gluesql/pull/1425</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a href="https://github.com/gluesql/gluesql/compare/v0.14.0...v0.15.0" target="_blank" rel="noopener noreferrer">https://github.com/gluesql/gluesql/compare/v0.14.0...v0.15.0</a></p>]]></content>
        <author>
            <name>Taehoon Moon</name>
            <uri>https://github.com/panarch</uri>
        </author>
        <category label="v0.15" term="v0.15"/>
        <category label="release-note" term="release-note"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[GlueSQL - Revolutionizing Databases by Unifying Query Interfaces]]></title>
        <id>https://gluesql.org/docs/0.19.0/blog/revolutionizing-databases-by-unifying-query-interfaces</id>
        <link href="https://gluesql.org/docs/0.19.0/blog/revolutionizing-databases-by-unifying-query-interfaces"/>
        <updated>2023-05-30T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[GlueSQL - Revolutionizing Databases by Unifying Query Interfaces]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorWithStickyNavbar_LWe7" id="introduction">Introduction<a href="https://gluesql.org/docs/0.19.0/blog/revolutionizing-databases-by-unifying-query-interfaces#introduction" class="hash-link" aria-label="Direct link to Introduction" title="Direct link to Introduction">​</a></h2>
<p>GlueSQL is a versatile database project designed for exceptional portability across a broad range of environments, from embedded systems and servers to web and mobile platforms. The core goal is to support diverse storage environments and manage various data types with a standard SQL approach.</p>
<p>Imagine handling files like CSV, JSONL, and Parquet, or transforming key-value or NoSQL databases such as RocksDB, Redis, and MongoDB into SQL-supporting databases—all feasible with GlueSQL. It can also operate with storages supported in web browsers.</p>
<p>GlueSQL's essential feature is providing a management layer for these diverse storage scenarios without requiring data migration. The broader aim is to facilitate portability of GlueSQL to any environment supporting read or read-write operations. This extends to APIs like GitHub, or messengers like Discord or Slack.</p>
<p>GlueSQL supports both structured and unstructured data and is written in Rust for compatibility with various environments. While portability is its core value, the emphasis is on creating an intuitive, comfortable development environment for easy custom storage implementation.</p>
<p>Ultimately, GlueSQL aims to significantly reduce the cost, time, and complexity of developing new databases. By leveraging GlueSQL for the parser, planner, and execution layer, developers can focus on creating specific storage implementations, leading to a more convenient query interface like SQL for many environments.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-problem-why-reinvent-the-database">The Problem: Why Reinvent the Database?<a href="https://gluesql.org/docs/0.19.0/blog/revolutionizing-databases-by-unifying-query-interfaces#the-problem-why-reinvent-the-database" class="hash-link" aria-label="Direct link to The Problem: Why Reinvent the Database?" title="Direct link to The Problem: Why Reinvent the Database?">​</a></h2>
<p>Despite the numerous database implementations that currently exist, the emergence of new databases continues. The primary reason behind this trend is our need for databases for a broad spectrum of distinct purposes. For instance, new databases are surfacing that are specifically optimized for Large Language Models (LLMs) like ChatGPT. The range is wide and diverse, encompassing embedded databases, OLAP for data analysis, OLTP databases optimized for online transactions, databases specialized for time-series data processing, and many more.</p>
<p>With such varied requirements, we find ourselves in constant need of fresh databases. However, constructing a database from scratch is a monumental task. It necessitates defining a query interface for handling the database and implementing a corresponding parser. Moreover, a separate execution layer for running operations must be built. Also, the planning layer, which is responsible for devising execution strategies, is a vital aspect of this process. Let's not forget about the critical storage layer that physically reads and stores the data. In a nutshell, there's a daunting amount of work involved in developing a new database.</p>
<p>Given these circumstances, it's understandable why numerous emerging databases resort to high pricing structures—they need immediate revenue to offset continuous development costs.</p>
<p>But the story doesn't end here. Query interfaces like SQL are indeed useful for serious tasks, but they also provide excellent utility for handling simple log files such as CSV, JSONL, Parquet, and even for utilizing REST APIs for various applications. The issue arises when a complex query interface needs to be provided even for these lighter storage requirements—it necessitates a development process almost identical to building a sophisticated database. Implementing an entire parser and execution layer just to add SQL support to an existing service can seem like an excessive burden.</p>
<p>Whether it's a simple storage environment or a serious task, the key lies in the storage layer, which involves the actual reading and storing of data. So, what if developers focused on implementing these storage mechanisms while the remaining parts could be handled using existing libraries? This is the role that GlueSQL aspires to play.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-vision-of-gluesql">The Vision of GlueSQL<a href="https://gluesql.org/docs/0.19.0/blog/revolutionizing-databases-by-unifying-query-interfaces#the-vision-of-gluesql" class="hash-link" aria-label="Direct link to The Vision of GlueSQL" title="Direct link to The Vision of GlueSQL">​</a></h2>
<p>The GlueSQL project aims to offer a unified query interface for various environments. The goal is to allow anyone to port and use SQL and GlueSQL's proprietary query builder, the AST Builder, in any desired environment. This could range from key-value databases, serious NoSQL databases, log files, and even REST API services. Essentially, if a service supports reading or read-writing data, regardless of the data type, it can readily support a complex query interface via GlueSQL.</p>
<p>Presently, the GlueSQL project itself directly supports a few storage types as reference storages. These include in-memory storage for non-persistent data handling, sled storage, which is a key-value database written in Rust, JSON storage for handling JSON and JSONL files, and a storage that ports SQL to the web browser's IndexedDB. While the GlueSQL Team is primarily developing these, the aim is to allow anyone to create such custom storages for a wide array of purposes, thus enabling them to assemble the database of their choosing.</p>
<p>Imagine using GlueSQL's SQL and AST Builder everywhere, with the simple method of swapping out storages to operate in diverse settings. It could significantly reduce software development costs. Developers wouldn't need to learn the different usage methods for each database. Instead, they could focus solely on implementing business logic using the same interface.</p>
<p>Our vision is to reduce database development costs by 10 times, or even more than 20 times. We aim to gather diverse database creators under the GlueSQL banner, making it the go-to solution for cost-effective database development.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="benefits-to-database-users-unifying-query-interfaces-streamlining-software-development-and-reducing-costs">Benefits to Database Users: Unifying Query Interfaces, Streamlining Software Development, and Reducing Costs<a href="https://gluesql.org/docs/0.19.0/blog/revolutionizing-databases-by-unifying-query-interfaces#benefits-to-database-users-unifying-query-interfaces-streamlining-software-development-and-reducing-costs" class="hash-link" aria-label="Direct link to Benefits to Database Users: Unifying Query Interfaces, Streamlining Software Development, and Reducing Costs" title="Direct link to Benefits to Database Users: Unifying Query Interfaces, Streamlining Software Development, and Reducing Costs">​</a></h2>
<p>From the perspective of the users who engage with databases, there has always been the burden of learning different interfaces to interact with each database. The approach required to work with Redis is different from that necessary for MongoDB. Likewise, handling SQL databases necessitates using SQL. Although SQL databases generally use a common SQL, the SQL they support can considerably vary when examined in detail.</p>
<p>Naturally, there are legitimate reasons for such differences. Each database focuses on different areas, and to cater to specialized functionalities, they incorporate dedicated interface mechanisms. However, not all application development needs to utilize these database-specific core special functionalities.</p>
<p>Let's look at a couple of examples:</p>
<p>Suppose you're developing a back-end application that uses MySQL as the database and Redis for caching. Due to the vast differences in handling SQL databases and Redis, you would have to develop using different methods when storing data.</p>
<p>Here's another scenario:
Imagine you're implementing a data migration pipeline between various databases and log files. Let's say you're transferring Parquet to Redis or MongoDB. In this case, you would need to convert data using different methods for each, all of which would be a cumbersome process.</p>
<p>In both of the above examples, GlueSQL can directly address and solve the issues. It offers the convenience of a uniform query interface to deal with these matters. In certain scenarios, even the construction of a data pipeline can potentially be solved with a single SQL query, thanks to GlueSQL.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="benefits-to-database-developers-drastically-lowering-development-costs-and-simplifying-the-creation-of-purpose-built-databases">Benefits to Database Developers: Drastically Lowering Development Costs and Simplifying the Creation of Purpose-Built Databases<a href="https://gluesql.org/docs/0.19.0/blog/revolutionizing-databases-by-unifying-query-interfaces#benefits-to-database-developers-drastically-lowering-development-costs-and-simplifying-the-creation-of-purpose-built-databases" class="hash-link" aria-label="Direct link to Benefits to Database Developers: Drastically Lowering Development Costs and Simplifying the Creation of Purpose-Built Databases" title="Direct link to Benefits to Database Developers: Drastically Lowering Development Costs and Simplifying the Creation of Purpose-Built Databases">​</a></h2>
<p>If you want to support SQL in the desired environment, using GlueSQL essentially requires you to implement an interface for Storage. There's no need to support all functionalities from the beginning. You can start lightly, choosing and implementing storage features suitable for the environment you want to create. To facilitate this, GlueSQL also provides a library in the form of a test suite to easily validate the storage you've implemented.</p>
<p>Lowering development costs in this way will enable a broader range of developers to support the GlueSQL query interface. As more developers join, a significant synergy can be generated. Designing a query interface from scratch involves a great deal of work, including planning and supporting the interface for different target programming languages.</p>
<p>However, despite all this hard work, it is not easy to attract database users accustomed to different methods.</p>
<p>Consider that the SQL and AST Builder provided by GlueSQL are already securing numerous users. This eliminates the need for efforts to promote a newly planned query interface. Over the years, many new databases have emphasized compatibility with PostgreSQL or MySQL for similar reasons. As GlueSQL places a strong emphasis on portability in its query interface planning, it allows for more flexible configuration according to the desired situation. Through the AST Builder, it also eliminates the cost of porting to different languages.</p>
<p>For many database developers, using GlueSQL can be an optimal choice, as it can save costs and quickly secure users.</p>
<p>Let me mention one more thing: what's convenient for humans... could be applied to AI as well. Rather than making AI write automation code using different databases, providing a common query interface can be much more efficient.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-future-with-gluesql">The Future with GlueSQL<a href="https://gluesql.org/docs/0.19.0/blog/revolutionizing-databases-by-unifying-query-interfaces#the-future-with-gluesql" class="hash-link" aria-label="Direct link to The Future with GlueSQL" title="Direct link to The Future with GlueSQL">​</a></h2>
<p>GlueSQL has been and will continue to improve and develop new features to enable portability in various environments. Thanks to the schemaless data support added last year, it is now possible to handle both structured data with schema and unstructured data like JSON simultaneously. This has significantly increased the range of storage environments that can be supported.</p>
<p>One of the key features added last year was the AST Builder. This feature allowed us to escape the confines of SQL and provide an interface for comfortably handling data in the programming languages used for development.</p>
<p>Of course, improving existing features is extremely important, and there are many new features to be added. As a major development plan this year, we aim to develop features to effectively attach GlueSQL to NoSQL databases with their own planners and execution layers. The GlueSQL query planner, currently at a basic level, will see significant changes this year. With the expansion of this planner, not only NoSQL databases but also other SQL databases could be supported without sacrificing performance using GlueSQL.</p>
<p>The synergy that arises from the combination of different databases is a significant bonus in this process.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-journey-of-the-gluesql-team">The Journey of the GlueSQL Team<a href="https://gluesql.org/docs/0.19.0/blog/revolutionizing-databases-by-unifying-query-interfaces#the-journey-of-the-gluesql-team" class="hash-link" aria-label="Direct link to The Journey of the GlueSQL Team" title="Direct link to The Journey of the GlueSQL Team">​</a></h2>
<p>The GlueSQL project was first conceived in the fall of 2019, and since then we have been developing it continuously. Personally, I have created various products in a variety of environments, including game development, backend server, and frontend development over the past decade. The experience gained through this process was a major motivation to start the GlueSQL project.</p>
<p>To put it grandly, the inconveniences felt while using different databases in various environments were a major motivation, wouldn't you say?</p>
<p>The start was actually a bit simple. Around 2019, I was mainly doing web front-end development. However, the lack of a structured database for state management and internal data processing made it very uncomfortable, especially since I couldn't use SQL databases and the like. So I started to lightly create an SQL database that could run on a web browser. Also, I wanted to use Rust, but after failing to introduce it at the company I was working for at the time, I decided to use it in my own project.</p>
<p>But as I started developing, my dreams grew significantly. Beyond a SQL database that simply operates on a web browser, I started envisioning a database that fits the name "Glue", one that can easily be ported to various environments, and I continue that journey to this day.</p>
<p>Whether I took the database project too lightly, or because the features I wanted kept increasing, the content to be developed kept expanding. As a result, I ended up investing full time in the GlueSQL project development for over three years. For a year in between, I even juggled full-time software engineering work alongside GlueSQL development. Currently, I'm back to developing the GlueSQL project full time, alongside various part-time contributors.</p>
<p>Now, we're getting very close to the starting point of the picture I wanted to create through GlueSQL, and thankfully, with contributors joining me, I am not alone.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-sustainability-and-business-aspect-of-gluesql">The Sustainability and Business Aspect of GlueSQL<a href="https://gluesql.org/docs/0.19.0/blog/revolutionizing-databases-by-unifying-query-interfaces#the-sustainability-and-business-aspect-of-gluesql" class="hash-link" aria-label="Direct link to The Sustainability and Business Aspect of GlueSQL" title="Direct link to The Sustainability and Business Aspect of GlueSQL">​</a></h2>
<p>I believe that what we create through GlueSQL will make a great contribution to the world and make many software engineers happy. This gives me immense strength to continue developing even in difficult situations. However, we cannot accomplish everything with pure passion alone. As much as the GlueSQL project can make a significant contribution, I also see it as holding great business value.</p>
<p>The business strategy of GlueSQL may be somewhat different from other databases. We distribute the project itself as open source under the Apache-2.0 license, so that anyone can use it fully, and we do not consider pricing methods such as restricting features to the storages we support. In fact, if there is any player who can do it better, there's no way to prevent them from taking the GlueSQL project and making it their own.</p>
<p>But we believe that GlueSQL has great potential in this regard. Anyone can participate and they are free to distribute their own storage in the way they want, whether it's open source, private, or commercial. This eliminates the need to create something to replace the GlueSQL project. We aim to prevent the need to recreate the wheel that we provide using GlueSQL.</p>
<p>Moreover, our GlueSQL team seeks to continually expand our group of developers and companies working with us. During this development process, while they can certainly implement everything on their own, there is also no reason not to collaborate with our GlueSQL Team, especially for databases like NoSQL that have their own planners and execution layers. If you have a REST API and want to enhance convenience through SQL support, you can do it yourself or you can collaborate with us.</p>
<p>In addition, for some storages, we can also participate as players in the same position as other custom storage developers. We plan to expand the GlueSQL ecosystem in various ways, such as technical support and storage development.</p>
<p>We are finally ready to provide GlueSQL to users at the production level. We are accelerating the development of GlueSQL. If you are a company interested in storage development like SQL support, or if you resonate with our vision and want to join us, please contact us at <a href="mailto:taehoon@gluesql.com" target="_blank" rel="noopener noreferrer">taehoon@gluesql.com</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="conclusion">Conclusion<a href="https://gluesql.org/docs/0.19.0/blog/revolutionizing-databases-by-unifying-query-interfaces#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h2>
<p>The continued emergence of new databases is driven by the demand for diverse and specialized databases, such as those optimized for Large Language Models (LLMs) and databases catering to unique requirements, like embedded databases, OLAP, OLTP, and time-series data processing. However, developing a new database from scratch is a significant undertaking, requiring extensive work, which often results in high costs.</p>
<p>GlueSQL presents a solution to this challenge by providing a unified query interface that can be ported across various environments, from key-value databases, NoSQL databases, log files, to REST APIs. It allows anyone to create custom storages, reducing the need for developers to build entirely new databases and to learn different usage methods for each database. Instead, they can focus on implementing their business logic using the same interface.</p>
<p>From a user perspective, GlueSQL offers the convenience of a unified query interface, easing the burden of learning different interfaces for each database. This simplification of interface use can also extend to AI, potentially enhancing the efficiency of AI automation.</p>
<p>GlueSQL's development plan includes significant enhancements to its query planner and aims to enable effective attachment of GlueSQL to NoSQL databases. The synergy of combining different databases is a valuable bonus in this process.</p>
<p>Since its inception in the fall of 2019, the GlueSQL team has continuously developed the project, driven by the desire to mitigate the inconveniences encountered while using different databases in various environments. The journey has been a rewarding one, with the GlueSQL project now at a point where it closely resembles the envisioned product.</p>
<p>GlueSQL, distributed under the Apache-2.0 license, is free for anyone to use and adapt. While the GlueSQL team welcomes collaboration with other developers and companies, they also see significant potential for the project as a business venture. The team is working to expand the GlueSQL ecosystem through a variety of initiatives, including technical support and storage development.</p>
<p>With GlueSQL now sufficiently prepared for practical applications, the team invites companies interested in storage development or those who share their vision to join them in their journey of revolutionizing database development.</p>]]></content>
        <author>
            <name>Taehoon Moon</name>
            <uri>https://github.com/panarch</uri>
        </author>
        <category label="gluesql" term="gluesql"/>
        <category label="query-interface" term="query-interface"/>
        <category label="database" term="database"/>
        <category label="proposal" term="proposal"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Test-Driven Documentation - Automating User Manual Creation in GlueSQL]]></title>
        <id>https://gluesql.org/docs/0.19.0/blog/test-driven-documentation</id>
        <link href="https://gluesql.org/docs/0.19.0/blog/test-driven-documentation"/>
        <updated>2023-05-30T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Test-Driven Documentation - Automating User Manual Creation in GlueSQL]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorWithStickyNavbar_LWe7" id="introduction-gluesql-and-test-driven-documentation">Introduction: GlueSQL and Test-Driven Documentation<a href="https://gluesql.org/docs/0.19.0/blog/test-driven-documentation#introduction-gluesql-and-test-driven-documentation" class="hash-link" aria-label="Direct link to Introduction: GlueSQL and Test-Driven Documentation" title="Direct link to Introduction: GlueSQL and Test-Driven Documentation">​</a></h2>
<p>Recently, the GlueSQL project reached a significant milestone with the release of version 0.14. This new version brings a host of fresh features to the table, yet one of the most notable changes is in the realm of documentation. For the first time, we're proud to announce the launch of our official documentation website. Interested readers can explore the full range of user manuals at <a href="https://gluesql.org/docs" target="_blank" rel="noopener noreferrer">https://gluesql.org/docs</a>.</p>
<p>Prior to this update, the only way to navigate GlueSQL was by manually inspecting the test code within the test suite. With the recent release, however, a comprehensive user manual has been made public to facilitate a more user-friendly experience. We hope that this new addition will prove beneficial to a broad spectrum of users.</p>
<p>The task of compiling an entire database manual in one go was daunting due to the sheer volume of content required. Surprisingly, this process turned out to be smoother than initially anticipated, largely due to the invaluable aid of ChatGPT, which was instrumental in automating much of the document creation. Specifically, around 80% of the SQL Syntax section was generated using this tool.</p>
<p>This remarkable feat was only possible due to the solid foundation of test codes previously established in GlueSQL. In this article, we'll share how we managed to leverage ChatGPT in such a unique way. Based on our recent experience of crafting documents grounded in testing, we've begun to consider the possibility of entirely automating document creation, save for the initial stages.</p>
<p>Along with sharing our journey so far, we will also reveal our plans for future test-based automation of documentation within GlueSQL.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="test-codes-and-documentation">Test Codes and Documentation<a href="https://gluesql.org/docs/0.19.0/blog/test-driven-documentation#test-codes-and-documentation" class="hash-link" aria-label="Direct link to Test Codes and Documentation" title="Direct link to Test Codes and Documentation">​</a></h2>
<p>The GlueSQL project has placed a significant emphasis on writing test codes. This might be a given for a database project; however, the thoroughness of our approach is evident from our line coverage of nearly <strong>99%</strong> for core codes. While we devoted considerable effort to creating these test codes, our primary focus has always been on a different aspect: ensuring that anyone can quickly grasp the content of the tests and easily add new ones.</p>
<p>The intent here is to empower newcomers to GlueSQL to understand the functionality of the software solely by examining integration tests, even in the absence of a user manual.</p>
<p>The integration tests for GlueSQL can be found in the test-suite workspace. For example, here's an excerpt of the test code for the INSERT statement:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token macro property" style="color:#36acaa">test_case!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">insert</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">move</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token macro property" style="color:#36acaa">run!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">CREATE TABLE Test (</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">    id INTEGER DEFAULT 1,</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">    num INTEGER NULL,</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">    name TEXT NOT NULL</span><br></span><span class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">);"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token macro property" style="color:#36acaa">test!</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"basic insert - single item"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        sql</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"INSERT INTO Test (id, num, name) VALUES (1, 2, 'Hi boo');"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        expected</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Ok</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Payload</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Insert</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token macro property" style="color:#36acaa">test!</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        sql</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"INSERT INTO Test VALUES(17, 30, 'Sullivan');"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        expected</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Ok</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Payload</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Insert</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token macro property" style="color:#36acaa">test!</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        sql</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"INSERT INTO Test (num, name) VALUES (28, 'Wazowski');"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        expected</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Ok</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Payload</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">Insert</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token macro property" style="color:#36acaa">test!</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        sql</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"SELECT * FROM Test;"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        expected</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Ok</span><span class="token punctuation" style="color:#393A34">(</span><span class="token macro property" style="color:#36acaa">select!</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            id  </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> num </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> name</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token constant" style="color:#36acaa">I64</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">I64</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token class-name">Str</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token number" style="color:#36acaa">1</span><span class="token plain">     </span><span class="token number" style="color:#36acaa">2</span><span class="token plain">     </span><span class="token string" style="color:#e3116c">"Hi boo"</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">to_owned</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token number" style="color:#36acaa">3</span><span class="token plain">     </span><span class="token number" style="color:#36acaa">9</span><span class="token plain">     </span><span class="token string" style="color:#e3116c">"Kitty!"</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">to_owned</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token number" style="color:#36acaa">2</span><span class="token plain">     </span><span class="token number" style="color:#36acaa">7</span><span class="token plain">     </span><span class="token string" style="color:#e3116c">"Monsters"</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">to_owned</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token number" style="color:#36acaa">17</span><span class="token plain">    </span><span class="token number" style="color:#36acaa">30</span><span class="token plain">    </span><span class="token string" style="color:#e3116c">"Sullivan"</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">to_owned</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token number" style="color:#36acaa">1</span><span class="token plain">     </span><span class="token number" style="color:#36acaa">28</span><span class="token plain">    </span><span class="token string" style="color:#e3116c">"Wazowski"</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">to_owned</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>Despite being written in Rust, these test cases are designed to be comprehensible, even to those unfamiliar with the language. Each test is a complete scenario from start to finish, and the results of each operation are readily observable.</p>
<p>Given that identifying results from SELECT operations in the form of Rust enums and structs can be challenging, we actively utilized macros such as <code>select!</code> and <code>select_with_null!</code>. We've composed the test cases to demonstrate that the INSERT statement can handle a wide range of cases, including specifying all columns, omitting some, or omitting all.</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token macro property" style="color:#36acaa">test!</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    sql</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"INSERT INTO Test (id, num) VALUES (1, 10);"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    expected</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Err</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">InsertError</span><span class="token punctuation" style="color:#393A34">::</span><span class="token class-name">LackOfRequiredColumn</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"name"</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">to_owned</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">into</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>The tests also include scenarios for expected faulty inputs, indicating the error returns in these situations.</p>
<p>By organizing the tests in this manner, we aim to make it easy for anyone to read and write tests. Our goal was for these tests to serve as "documentation" for GlueSQL contributors. At the time we were writing these tests, we didn't anticipate that they could actually become documentation themselves. But we've come to realize that they have extraordinary potential.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="leveraging-chatgpt">Leveraging ChatGPT<a href="https://gluesql.org/docs/0.19.0/blog/test-driven-documentation#leveraging-chatgpt" class="hash-link" aria-label="Direct link to Leveraging ChatGPT" title="Direct link to Leveraging ChatGPT">​</a></h2>
<p>When we first embarked on writing the User Manual, we were overwhelmed by the sheer volume of content we had to generate. Around the same time, ChatGPT was gaining prominence, and we thought it might be worth trying out, if only to lighten our load slightly.</p>
<p>To our surprise, ChatGPT exceeded our expectations. If the test codes were well written, it was capable of automatically crafting an exceptional document based on them, capturing all essential details.</p>
<p>After several trials and errors, we settled on the following prompt for document generation. While it's still a challenge to use the same prompt for all documentation, we made minor modifications to suit different situations:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">I'm creating an SQL database documentation website, and I'd like you to help me with one of the pages that introduces the SQL syntax for GlueSQL.</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">1. Please provide the response content in the "markdown" format, so I can copy and paste it directly. Keep this constraint in mind while writing.  </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">2. Regardless of the language I use, I need the content written in English.  </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">3. I will provide some test case code written in the Rust language, which contains SQL examples. Please write the documentation based on these examples, but feel free to change the table names, column names, and data types as needed. Don't include any Rust related content or text in the response. all the response code example should be in plain SQL. </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">4. GlueSQL does not have the VARCHAR type. If you want to use that, please use TEXT instead. You don't need to mention this in the response. </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">5. Wrap the entire response text using &lt;pre&gt; and &lt;/pre&gt; tags so I can copy all the content easily. </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Now, I'd like you to write the following request:  </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">SQL Statement - "INSERT" </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Here's an example test code you can refer to:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">test_case!(insert, async move {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    run!(...</span><br></span></code></pre></div></div>
<p>Generally, we used the template above, and copied and pasted the test code from our existing test-suite. We leveraged this method to harness our many tests to assist in the creation of the user manual. In the next section, we'll showcase a sample of the documentation generated in this manner. It's quite impressive.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="success-case-automated-user-manual-of-gluesql">Success Case: Automated User Manual of GlueSQL<a href="https://gluesql.org/docs/0.19.0/blog/test-driven-documentation#success-case-automated-user-manual-of-gluesql" class="hash-link" aria-label="Direct link to Success Case: Automated User Manual of GlueSQL" title="Direct link to Success Case: Automated User Manual of GlueSQL">​</a></h2>
<p>Thanks to ChatGPT, the resulting INSERT document page can be viewed at the following link. It's important to note that we used ChatGPT 4 for this task. Version 3.5 wasn't quite up to the task, and using version 4 was the minimum requirement.</p>
<p><a href="https://gluesql.org/docs/dev/sql-syntax/statements/data-manipulation/insert" target="_blank" rel="noopener noreferrer">https://gluesql.org/docs/dev/sql-syntax/statements/data-manipulation/insert</a></p>
<p><img decoding="async" loading="lazy" alt="INSERT Statement" src="https://gluesql.org/docs/0.19.0/assets/images/blog-test-driven-documentation-insert-7dfbb3a9123d4aa47b845b7dede97dc9.jpg" width="2203" height="1739" class="img_ev3q"></p>
<p>The results were quite impressive. ChatGPT neatly categorized the test cases, explained the syntax, outlined constraints, and provided appropriate examples. It didn't stop there; it also skillfully recognized error test cases and incorporated them into the documentation, as shown below.</p>
<p><img decoding="async" loading="lazy" alt="INSERT Statement" src="https://gluesql.org/docs/0.19.0/assets/images/blog-test-driven-documentation-insert-errorcase-1be5ced205cee0d2eeb56af1591440ac.jpg" width="1751" height="353" class="img_ev3q"></p>
<p>Isn't it amazing?</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="future-plans-fully-automating-documentation-generation">Future Plans: Fully Automating Documentation Generation<a href="https://gluesql.org/docs/0.19.0/blog/test-driven-documentation#future-plans-fully-automating-documentation-generation" class="hash-link" aria-label="Direct link to Future Plans: Fully Automating Documentation Generation" title="Direct link to Future Plans: Fully Automating Documentation Generation">​</a></h2>
<p>While the current documentation is far from perfect and there are many aspects that can be improved, we see great potential in this approach. We believe it's entirely possible to automate the process of writing this kind of document, and writing in general.</p>
<p>In the past, documents like user manuals required a great deal of effort to maintain once they were written. If a document contained real code examples, verifying that the code still worked was often a tedious task. With the ability to automatically generate documentation as we have done here, these issues are no longer problematic.</p>
<p>Previously, you would have to write tests and then also document them separately. If you had to support multiple languages, that would be an additional task. With a tool like ChatGPT, you can automate all of this. All a developer has to do is write the tests. This alone can be sufficient. You can generate documents automatically based on the tests. Eventually, we can even support automatically translating these documents into multiple languages.</p>
<p>The GlueSQL project repository is currently hosted on GitHub and makes good use of various GitHub Actions. We envision a GitHub Action that automatically regenerates a document corresponding to a test when a user modifies the test and raises a Pull Request. Another GitHub Action could automatically translate updated documents into supported languages and create new Pull Requests. The possibilities are truly endless.</p>
<p>Not only will this help with document generation, but it will also provide clear guidelines for writing better test code. If we can automatically generate documents based on written tests, the quality of those documents can serve as an indicator of the quality of the tests themselves. This means that a document automation tool can play the role of a good reviewer for tests. It can greatly reduce the time and effort required for painstakingly reviewing the quality of each test. Developers can also write tests without pressure, evaluate their test code by looking at the generated document, and improve it.</p>
<p>Furthermore, multi-language support becomes a breeze. In my personal experience as a software engineer over the past decade, developing various products such as games, web services, and applications, I often needed to support multiple languages. Each time, there was no definite solution. The optimal approach varied depending on the situation, and there were many things to consider when entrusting translations, such as effectively communicating the context of the target service to the translator. Moreover, regularly updating content and having it retranslated into various languages was a very tedious process. While I tried to automate as much as possible by creating various tools, I was never fully satisfied. I believe ChatGPT can completely solve these issues. If there is a need to provide project-specific context, all you need to do is prepare a prompt in advance. Instead of having to rely on and wait for professional translators, we can now entrust this task to ChatGPT, and we only need a few people to review the translated content.</p>
<p>We are nearing a world where documentation is no longer a burden for developers.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="conclusion-the-value-of-test-driven-documentation">Conclusion: The Value of Test-Driven Documentation<a href="https://gluesql.org/docs/0.19.0/blog/test-driven-documentation#conclusion-the-value-of-test-driven-documentation" class="hash-link" aria-label="Direct link to Conclusion: The Value of Test-Driven Documentation" title="Direct link to Conclusion: The Value of Test-Driven Documentation">​</a></h2>
<p>The use of ChatGPT to generate documentation has proven a significant step forward in the GlueSQL user manual creation process. Through test-driven documentation, we've managed to automate a substantial part of the manual creation process, saving time and effort, and increasing accuracy.</p>
<p>Moreover, this process has unveiled a new potential for documentation: the possibility of fully automating document generation. We've seen that quality tests can become quality documentation with the help of AI, leading to more efficient workflows and possibly better test code as a result.</p>
<p>The journey doesn't stop here. We envision leveraging this capability further to auto-translate our documents into multiple languages, making our product more accessible to a global audience.</p>
<p>As we progress, we hope that our experience can inspire other developers to explore and embrace the benefits of AI-generated, test-driven documentation. It's not just about saving time—it's about improving the way we work, communicate, and share knowledge.</p>]]></content>
        <author>
            <name>Taehoon Moon</name>
            <uri>https://github.com/panarch</uri>
        </author>
        <category label="ChatGPT" term="ChatGPT"/>
        <category label="Test-Driven-Documentation" term="Test-Driven-Documentation"/>
        <category label="TDD" term="TDD"/>
        <category label="Database" term="Database"/>
        <category label="Documentation" term="Documentation"/>
        <category label="Automation" term="Automation"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Breaking the Boundary between SQL and NoSQL Databases]]></title>
        <id>https://gluesql.org/docs/0.19.0/blog/breaking-the-boundary-between-sql-and-nosql</id>
        <link href="https://gluesql.org/docs/0.19.0/blog/breaking-the-boundary-between-sql-and-nosql"/>
        <updated>2023-05-29T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Breaking the Boundary between SQL and NoSQL Databases]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorWithStickyNavbar_LWe7" id="introduction">Introduction<a href="https://gluesql.org/docs/0.19.0/blog/breaking-the-boundary-between-sql-and-nosql#introduction" class="hash-link" aria-label="Direct link to Introduction" title="Direct link to Introduction">​</a></h2>
<p>The divide between SQL and NoSQL databases has often presented challenges in database management. GlueSQL, a unique database maker library, aims to blur this boundary, providing a versatile tool for handling these two distinct types of databases.</p>
<p>In this article, we explore how GlueSQL navigates the features of SQL and NoSQL databases, offering an integrated solution that promotes flexibility and efficiency. With its ability to unify disparate database types, GlueSQL heralds a new age of adaptable database creation and management.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-interface-perspective-sql--ast-builder">The Interface Perspective: SQL &amp; AST Builder<a href="https://gluesql.org/docs/0.19.0/blog/breaking-the-boundary-between-sql-and-nosql#the-interface-perspective-sql--ast-builder" class="hash-link" aria-label="Direct link to The Interface Perspective: SQL &amp; AST Builder" title="Direct link to The Interface Perspective: SQL &amp; AST Builder">​</a></h2>
<p>When we talk about SQL databases, it's almost a given that they support SQL - the standard query language. Although there are slight variations between databases, the convenience of using a similar SQL language across multiple databases cannot be overstated. However, from a software engineer's perspective, there's room for improvement. In most software development scenarios, a specific programming language is used. SQL is a separate language, which can cause friction when integrating it into your software. As a result, rather than using raw SQL, many developers employ query builders or ORMs to manipulate SQL conveniently using their preferred programming language. Although it's not efficient to generate SQL using a query builder and then parse it again in the database, it's a practical and effective choice.</p>
<p>On the other hand, NoSQL databases offer different mechanisms. Some of them have their own language similar to SQL, but most provide an interface library developed specifically for each programming language. While SQL databases rely on external query builder libraries to provide an interface for each programming language, NoSQL databases mostly develop and offer these libraries themselves. If we discount the convenience of SQL language, this is one of the major factors that make NoSQL databases more comfortable to use. Since query builder libraries supporting SQL databases often cater to multiple SQL databases, they are limited in fully supporting unique features of each database. NoSQL databases, on the other hand, can freely manage their interface libraries without these restrictions.</p>
<p>Providing a query interface for each programming language is not a fundamental difference between SQL and NoSQL, but we generally accept it implicitly.</p>
<p>Let's see what happens if we break down this boundary, using GlueSQL as an example. As you can see from the SQL postfix, GlueSQL supports SQL and can be classified as an SQL database.</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">TABLE</span><span class="token plain"> Glue </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">id </span><span class="token keyword" style="color:#00009f">INTEGER</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> name </span><span class="token keyword" style="color:#00009f">TEXT</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">INSERT</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">INTO</span><span class="token plain"> Glue </span><span class="token keyword" style="color:#00009f">VALUES</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"hello"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"gluesql"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">SELECT</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">FROM</span><span class="token plain"> Glue </span><span class="token keyword" style="color:#00009f">WHERE</span><span class="token plain"> id </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>However, GlueSQL also supports its own query builder, like a NoSQL database.
(Currently, only Rust is supported, but we're working on adding support for other languages.)</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">table</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Glue"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">create_table</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">add_column</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"id INTEGER"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">add_column</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"name TEXT"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">execute</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">glue</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">table</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Glue"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">insert</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">values</span><span class="token punctuation" style="color:#393A34">(</span><span class="token macro property" style="color:#36acaa">vec!</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token macro property" style="color:#36acaa">vec!</span><span class="token punctuation" style="color:#393A34">[</span><span class="token function" style="color:#d73a49">num</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"hello"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token macro property" style="color:#36acaa">vec!</span><span class="token punctuation" style="color:#393A34">[</span><span class="token function" style="color:#d73a49">num</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"gluesql"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">execute</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">glue</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword" style="color:#00009f">await</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">table</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Glue"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">select</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">filter</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">col</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"id"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">eq</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">execute</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">glue</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword" style="color:#00009f">await</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>Let's reconsider the implicit distinction between SQL and NoSQL. GlueSQL indeed supports SQL, but it also officially develops and offers its own query builder. This query builder is not a secondary tool for SQL. While most SQL query builder libraries ultimately generate SQL strings, GlueSQL's builder directly creates an AST (Abstract Structure Tree) that is used for execution within GlueSQL. Hence, we call it the AST Builder. This means SQL and the AST Builder are two equally supported interfaces in GlueSQL.</p>
<p>This also offers an additional advantage:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">table</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Glue"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">select</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 1.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">filter</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">col</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"id"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">eq</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// 2.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">filter</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"id = 1"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">execute</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">glue</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword" style="color:#00009f">await</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>Because GlueSQL already supports SQL, not only can you use the custom interface in the AST Builder, but you can also use familiar SQL syntax in part. Whether you use <code>col("id").eq(1)</code> or <code>"id = 1"</code>, you can use it in the way you prefer. The AST Builder interface, although initially unfamiliar, allows a gradual migration similar to writing SQL for your convenience.</p>
<p>Thus, we've dismantled one of the implicit distinctions between SQL and NoSQL. However, it's more of an implicit differentiation than a fundamental one. There are more significant design differences that we'll explore next.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="structured--unstructured-data">Structured &amp; Unstructured Data<a href="https://gluesql.org/docs/0.19.0/blog/breaking-the-boundary-between-sql-and-nosql#structured--unstructured-data" class="hash-link" aria-label="Direct link to Structured &amp; Unstructured Data" title="Direct link to Structured &amp; Unstructured Data">​</a></h2>
<p>In this section, we'll discuss how SQL and NoSQL handle data. SQL generally deals with structured data, and recently, it's been made to support semi-structured data as well. On the other hand, NoSQL supports schemaless, unstructured data. Then, we'll explain in detail how GlueSQL handles these two types of data. The last part of this section will provide a segue into the next section where we'll discuss the decomposition of database functions.</p>
<p>When talking about SQL databases, one aspect is usually considered together: SQL databases have a defined schema.</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">TABLE</span><span class="token plain"> Foo </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    id </span><span class="token keyword" style="color:#00009f">INTEGER</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    name </span><span class="token keyword" style="color:#00009f">TEXT</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    rate </span><span class="token keyword" style="color:#00009f">FLOAT</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">NULL</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>However, these days, SQL databases tend to support semi-structured data types, such as LIST or JSON. But, supporting completely schemaless, unstructured data is a different matter. SQL databases typically require a minimum schema.</p>
<p>What about NoSQL databases? As NoSQL databases vary significantly, we can't make definitive statements. But let's consider a typical document database like MongoDB. Unlike SQL databases, it doesn't enforce a schema. Essentially, you can insert any form of data directly. Often, NoSQL databases support schemaless data, but they lack features that enforce a schema like SQL. They generally support structure via validation methods, rather than structured access.</p>
<p>Is there no choice but to distinguish between structured data and unstructured, schemaless data so clearly? GlueSQL is being developed with the goal of being adaptable in various environments. Being forced to choose regarding this schema constraint was quite inconvenient. We started pondering if we couldn't benefit from both aspects - supporting both schema and schemaless data simultaneously, and we eventually found the answer. Let's look at how GlueSQL currently solves this issue through familiar SQL examples.</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">TABLE</span><span class="token plain"> Names </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">id </span><span class="token keyword" style="color:#00009f">INTEGER</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> name </span><span class="token keyword" style="color:#00009f">TEXT</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">INSERT</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">INTO</span><span class="token plain"> Names </span><span class="token keyword" style="color:#00009f">VALUES</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'glue'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'sql'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>You can create a regular table with a schema like this. But GlueSQL's choice for creating a schemaless table is as follows:</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">TABLE</span><span class="token plain"> Logs</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">INSERT</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">INTO</span><span class="token plain"> Logs </span><span class="token keyword" style="color:#00009f">VALUES</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'{ "id": 1, "value": 30 }'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'{ "id": 2, "rate": 3.0, "list": [1, 2, 3] }'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'{ "id": 3, "rate": 5.0, "value": 100 }'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>It creates a table without column definitions! If you do this, GlueSQL recognizes the table as schemaless and processes it internally.</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">SELECT</span><span class="token plain"> id</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> rate</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> list</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">FROM</span><span class="token plain"> Logs </span><span class="token keyword" style="color:#00009f">WHERE</span><span class="token plain"> id </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>Although the way to create the table was a bit special, using it isn't much different from the regular SQL SELECT statement. Not only can you differentiate between schema and schemaless when creating tables, but you can also use them interchangeably!</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">SELECT</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">FROM</span><span class="token plain"> Names </span><span class="token keyword" style="color:#00009f">JOIN</span><span class="token plain"> Logs </span><span class="token keyword" style="color:#00009f">ON</span><span class="token plain"> Names</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">id </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> Logs</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">id</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">/*</span><br></span><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">| id | list    | name | rate | value |</span><br></span><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">|----|---------|------|------|-------|</span><br></span><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">| 1  |         | glue |      | 30    |</span><br></span><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">| 2  |[1, 2, 3]| sql  | 3    |       |</span><br></span><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">*/</span><br></span></code></pre></div></div>
<p>Here's an example of querying data by INNER JOINing the Names table, which has a schema, and the Logs table, which is schemaless. GlueSQL has resolved this problem by allowing the internal execution layer to handle both vector-type data, for cases where each row has a defined schema, and map-type data for schemaless cases.</p>
<p>Thanks to this, the variety of storage that can be supported through GlueSQL has expanded significantly. If there were previously limitations to supporting NoSQL databases that support schemaless data, that is no longer the case. The reference storage where you can directly experience this schemaless data support is JSON Storage. It offers features that allow you to deal directly with unstructured data like JSON using GlueSQL.</p>
<p>If GlueSQL starts from the perspective of an SQL database and expands, by providing the AST Builder directly, it once blurs the boundary, and by supporting unstructured data simultaneously, it knocks down the boundary once more. How do you like it?</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="decomposing-database-functionality-breaking-down-sql-and-nosql-features">Decomposing Database Functionality: Breaking Down SQL and NoSQL Features<a href="https://gluesql.org/docs/0.19.0/blog/breaking-the-boundary-between-sql-and-nosql#decomposing-database-functionality-breaking-down-sql-and-nosql-features" class="hash-link" aria-label="Direct link to Decomposing Database Functionality: Breaking Down SQL and NoSQL Features" title="Direct link to Decomposing Database Functionality: Breaking Down SQL and NoSQL Features">​</a></h2>
<p>The distinction between SQL and NoSQL is not just about whether they support unstructured data. Of course, there are examples like unstructured data, which is mainly supported only in NoSQL, but in many cases, SQL databases tend to support more diverse and complex queries. NoSQL often gains other advantages in exchange for reducing the range of query support provided by SQL databases.</p>
<p>GlueSQL is ambitious. It has devised a rather interesting method to support all of this through SQL and the AST Builder, with the same interface. When we usually say SQL database, it implicitly assumes that a lot of features have been fully implemented. Create tables by specifying a schema, modify schemas with "alter table", support both clustered and non-clustered indexes, and support transactions. And there's so much more. But the functionality that is naturally supported in SQL databases may not be natural in other environments.</p>
<p>Let's think about JSON Storage. GlueSQL's JSON Storage allows you to handle JSON, JSONL files using SQL and the AST Builder. This JSON Storage does not support atomic operations or transactions. Of course, it would be great if it did, but implementing and executing them would be a significant performance burden. In most cases, when you want to simply browse and handle JSONL files, the overhead caused by transactions can be an unnecessary burden. In this case, you want to handle JSON, JSONL files using SQL, but you don't necessarily need transactions.</p>
<p>To meet the requirements of these diverse environments, GlueSQL has separated the functionality of what we usually call an SQL database into multiple independent interfaces.
<code>Store</code>, <code>StoreMut</code>, <code>AlterTable</code>, <code>Transaction</code>, ..
These are just a few of the various storage interfaces that GlueSQL currently supports.
The way it works can be summarized like this:
If you implement <code>Store</code>, you can use <code>SELECT</code>.
And if you implement both <code>Store</code> and <code>StoreMut</code>, you can support quite a number of basic SQL statements including <code>SELECT</code>.
You can manage tables with <code>CREATE TABLE</code>, <code>DROP TABLE</code>, and handle data using <code>INSERT</code>, <code>UPDATE</code>, <code>DELETE</code> statements.
If you only need to retrieve data, you only need to implement <code>Store</code>.
If you want to support the <code>ALTER TABLE</code> statement, you can additionally implement the <code>AlterTable</code> interface.
The Transaction interface works the same way.
The interesting part is that, except for Store and StoreMut, all other storage interfaces can be implemented independently. GlueSQL allows you to choose and implement only the features you need.
And it's not just about providing interfaces. It also provides integration tests suitable for each situation to verify what you have implemented. You just need to implement the interface and import the corresponding test case for verification.</p>
<p>In addition to supporting both structured and unstructured data simultaneously, GlueSQL provides the ability to divide the functionality of a database into multiple independent features and selectively implement them. This allows GlueSQL to be ported to a wide variety of environments without any burden.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="conclusion">Conclusion<a href="https://gluesql.org/docs/0.19.0/blog/breaking-the-boundary-between-sql-and-nosql#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h2>
<p>GlueSQL, while serving as a database that provides its own reference storage, is fundamentally a library designed to simplify the creation of databases. One of the substantial challenges GlueSQL had to overcome in order to support a diverse array of environments was to address the distinctive features that separate conventional SQL databases from NoSQL databases. GlueSQL achieved this through several innovative approaches, managing to support both categories simultaneously despite their significantly different characteristics.</p>
<p>It offers support for SQL alongside an AST Builder, and accommodates both structured and unstructured data. Additionally, it decomposes database functionalities into multiple independent features, allowing each environment to selectively implement the functionalities it requires.</p>
<p>These unique attributes enable GlueSQL to live up to its 'Glue' prefix by facilitating effortless porting across various environments. While we have been developing it for several years, there is still much ground to cover. However, the fact that we are now able to introduce it publicly attests to our successful technological validation and completion of a demonstrable level of implementation.</p>
<p>Through GlueSQL, we hope to provide developers with a unified query interface that can be customized according to their needs, thereby enabling them to produce efficient products more effortlessly. There's a promising future ahead for GlueSQL, and we look forward to its contributions to the technology community.</p>]]></content>
        <author>
            <name>Taehoon Moon</name>
            <uri>https://github.com/panarch</uri>
        </author>
        <category label="sql" term="sql"/>
        <category label="database" term="database"/>
        <category label="nosql" term="nosql"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Release v0.14]]></title>
        <id>https://gluesql.org/docs/0.19.0/blog/release-v0.14</id>
        <link href="https://gluesql.org/docs/0.19.0/blog/release-v0.14"/>
        <updated>2023-05-27T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Release Note - v0.14]]></summary>
        <content type="html"><![CDATA[<p>We now provide an official documentation website at <strong><a href="https://gluesql.org/docs" target="_blank" rel="noopener noreferrer">https://gluesql.org/docs</a></strong></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="-features">🚀 Features<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.14#-features" class="hash-link" aria-label="Direct link to 🚀 Features" title="Direct link to 🚀 Features">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="-schemaless-data-support">🍀 Schemaless data support<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.14#-schemaless-data-support" class="hash-link" aria-label="Direct link to 🍀 Schemaless data support" title="Direct link to 🍀 Schemaless data support">​</a></h3>
<p>GlueSQL now supports creating tables without a schema, allowing for both structured and unstructured data to be stored in the same table.
To create a schemaless table, simply run CREATE TABLE without specifying any columns. For more information on querying schemaless data, please refer to the following link: <strong><a href="https://gluesql.org/docs/dev/sql-syntax/statements/querying/schemaless" target="_blank" rel="noopener noreferrer">querying schemaless data</a></strong></p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">TABLE</span><span class="token plain"> Bar</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>To insert values,</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">INSERT</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">INTO</span><span class="token plain"> Bar </span><span class="token keyword" style="color:#00009f">VALUES</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'{ "name": "ast", "value": 30 }'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'{ "name": "glue", "rate": 3.0, "list": [1, 2, 3] }'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><br></span></code></pre></div></div>
<p>Then, selecting values from schemaless table is simple.</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">SELECT</span><span class="token plain"> name</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> rate</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> list</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">FROM</span><span class="token plain"> Bar </span><span class="token keyword" style="color:#00009f">WHERE</span><span class="token plain"> name </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'glue'</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>e.g.</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">TABLE</span><span class="token plain"> Names </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">id </span><span class="token keyword" style="color:#00009f">INTEGER</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> name </span><span class="token keyword" style="color:#00009f">TEXT</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">INSERT</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">INTO</span><span class="token plain"> Names </span><span class="token keyword" style="color:#00009f">VALUES</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'glue'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'sql'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">TABLE</span><span class="token plain"> Logs</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">INSERT</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">INTO</span><span class="token plain"> Logs </span><span class="token keyword" style="color:#00009f">VALUES</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'{ "id": 1, "value": 30 }'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'{ "id": 2, "rate": 3.0, "list": [1, 2, 3] }'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'{ "id": 3, "rate": 5.0, "value": 100 }'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">SELECT</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">FROM</span><span class="token plain"> Names </span><span class="token keyword" style="color:#00009f">JOIN</span><span class="token plain"> Logs </span><span class="token keyword" style="color:#00009f">ON</span><span class="token plain"> Names</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">id </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> Logs</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">id</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">/*</span><br></span><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">| id | list    | name | rate | value |</span><br></span><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">|----|---------|------|------|-------|</span><br></span><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">| 1  |         | glue |      | 30    |</span><br></span><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">| 2  |[1, 2, 3]| sql  | 3    |       |</span><br></span><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">*/</span><br></span></code></pre></div></div>
<ul>
<li>Schemaless data support <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1046" target="_blank" rel="noopener noreferrer">#1046</a>)</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="-indexeddb--webstorage-supports-in-javascript-package">🍀 IndexedDB &amp; WebStorage supports in JavaScript package<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.14#-indexeddb--webstorage-supports-in-javascript-package" class="hash-link" aria-label="Direct link to 🍀 IndexedDB &amp; WebStorage supports in JavaScript package" title="Direct link to 🍀 IndexedDB &amp; WebStorage supports in JavaScript package">​</a></h3>
<p>GlueSQL supports handling in-memory, localStorage, sessionStorage, and even IndexedDB using the same SQL syntax. All you need to know is how to specify the <code>ENGINE</code> when creating a table.</p>
<p>e.g.</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">TABLE</span><span class="token plain"> Mem </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">mid </span><span class="token keyword" style="color:#00009f">INTEGER</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">ENGINE</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> memory</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">TABLE</span><span class="token plain"> Loc </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">lid </span><span class="token keyword" style="color:#00009f">INTEGER</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">ENGINE</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> localStorage</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">TABLE</span><span class="token plain"> Ses </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">sid </span><span class="token keyword" style="color:#00009f">INTEGER</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">ENGINE</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> sessionStorage</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">TABLE</span><span class="token plain"> Idb </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">iid </span><span class="token keyword" style="color:#00009f">INTEGER</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">ENGINE</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> indexedDB</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">SELECT</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    mid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> lid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> sid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> iid </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">FROM</span><span class="token plain"> Mem</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">JOIN</span><span class="token plain"> Loc</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">JOIN</span><span class="token plain"> Ses</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">JOIN</span><span class="token plain"> Idb</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<ul>
<li>Apply CompositeStorage to JS package <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1084" target="_blank" rel="noopener noreferrer">#1084</a>)</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="-data-types---uint32-uint64-uint128-point-and-float32">🍀 Data Types - <code>UINT32</code>, <code>UINT64</code>, <code>UINT128</code>, <code>POINT</code> and <code>FLOAT32</code><a href="https://gluesql.org/docs/0.19.0/blog/release-v0.14#-data-types---uint32-uint64-uint128-point-and-float32" class="hash-link" aria-label="Direct link to -data-types---uint32-uint64-uint128-point-and-float32" title="Direct link to -data-types---uint32-uint64-uint128-point-and-float32">​</a></h3>
<ul>
<li>implement f32 data type <a href="https://github.com/pythonbrad" target="_blank" rel="noopener noreferrer">@pythonbrad</a> (<a href="https://github.com/gluesql/gluesql/pull/1145" target="_blank" rel="noopener noreferrer">#1145</a>)</li>
<li>Implement geometric <code>POINT</code> Type and geometric functions <a href="https://github.com/seonghun-dev" target="_blank" rel="noopener noreferrer">@seonghun-dev</a> (<a href="https://github.com/gluesql/gluesql/pull/1048" target="_blank" rel="noopener noreferrer">#1048</a>)</li>
<li>Add <code>UINT32</code>, <code>UINT64</code> and <code>UINT128</code> data types <a href="https://github.com/ChobobDev" target="_blank" rel="noopener noreferrer">@ChobobDev</a> (<a href="https://github.com/gluesql/gluesql/pull/1019" target="_blank" rel="noopener noreferrer">#1019</a>)</li>
<li>Add inet datatype <a href="https://github.com/pythonbrad" target="_blank" rel="noopener noreferrer">@pythonbrad</a> (<a href="https://github.com/gluesql/gluesql/pull/1080" target="_blank" rel="noopener noreferrer">#1080</a>)</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="-functions---append-prepend-rand-find_idx-initcap-and-calc_distance">🍀 Functions - <code>APPEND</code>, <code>PREPEND</code>, <code>RAND</code>, <code>FIND_IDX</code>, <code>INITCAP</code> and <code>CALC_DISTANCE</code><a href="https://gluesql.org/docs/0.19.0/blog/release-v0.14#-functions---append-prepend-rand-find_idx-initcap-and-calc_distance" class="hash-link" aria-label="Direct link to -functions---append-prepend-rand-find_idx-initcap-and-calc_distance" title="Direct link to -functions---append-prepend-rand-find_idx-initcap-and-calc_distance">​</a></h3>
<ul>
<li>Feat : add calc_distance function <a href="https://github.com/seonghun-dev" target="_blank" rel="noopener noreferrer">@seonghun-dev</a> (<a href="https://github.com/gluesql/gluesql/pull/1153" target="_blank" rel="noopener noreferrer">#1153</a>)</li>
<li>Add <code>PREPEND</code> function for <code>LIST</code> data type <a href="https://github.com/seonghun-dev" target="_blank" rel="noopener noreferrer">@seonghun-dev</a> (<a href="https://github.com/gluesql/gluesql/pull/1149" target="_blank" rel="noopener noreferrer">#1149</a>)</li>
<li>add initcap function <a href="https://github.com/pythonbrad" target="_blank" rel="noopener noreferrer">@pythonbrad</a> (<a href="https://github.com/gluesql/gluesql/pull/1064" target="_blank" rel="noopener noreferrer">#1064</a>)</li>
<li>Implement <code>FIND_IDX</code> function <a href="https://github.com/zmrdltl" target="_blank" rel="noopener noreferrer">@zmrdltl</a> (<a href="https://github.com/gluesql/gluesql/pull/1100" target="_blank" rel="noopener noreferrer">#1100</a>)</li>
<li>Implement Rand function <a href="https://github.com/pythonbrad" target="_blank" rel="noopener noreferrer">@pythonbrad</a> (<a href="https://github.com/gluesql/gluesql/pull/1063" target="_blank" rel="noopener noreferrer">#1063</a>)</li>
<li>Add Append Function to LIST DataType <a href="https://github.com/seonghun-dev" target="_blank" rel="noopener noreferrer">@seonghun-dev</a> (<a href="https://github.com/gluesql/gluesql/pull/1047" target="_blank" rel="noopener noreferrer">#1047</a>)</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="-store-traits">🍀 Store traits<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.14#-store-traits" class="hash-link" aria-label="Direct link to 🍀 Store traits" title="Direct link to 🍀 Store traits">​</a></h3>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="user-level-custom-function">User-level custom function<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.14#user-level-custom-function" class="hash-link" aria-label="Direct link to User-level custom function" title="Direct link to User-level custom function">​</a></h4>
<p>By implementing both the CustomFunction and CustomFunctionMut traits, users can create, use, and delete user-level custom functions. Although GlueSQL plans to continuously add various functions, users may still find them insufficient. In such cases, users can create their own user-level custom functions to supplement the built-in functions. Additionally, if there are repetitive business logic codes, they can be stored as custom functions.
e.g.</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">FUNCTION</span><span class="token plain"> ADD_ONE </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">n </span><span class="token keyword" style="color:#00009f">INT</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> x </span><span class="token keyword" style="color:#00009f">INT</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">DEFAULT</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">RETURN</span><span class="token plain"> n </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> x</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">SELECT</span><span class="token plain"> ADD_ONE</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">AS</span><span class="token plain"> test</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">DROP</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">FUNCTION</span><span class="token plain"> ADD_ONE</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<ul>
<li>Support user level sql function <a href="https://github.com/pythonbrad" target="_blank" rel="noopener noreferrer">@pythonbrad</a> (<a href="https://github.com/gluesql/gluesql/pull/1095" target="_blank" rel="noopener noreferrer">#1095</a>)</li>
</ul>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="metadata">Metadata<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.14#metadata" class="hash-link" aria-label="Direct link to Metadata" title="Direct link to Metadata">​</a></h4>
<p>The Metadata trait is an optional implementation for providing additional metadata support in GlueSQL. GlueSQL does not enforce any specific metadata implementation, allowing custom storage developers to decide which type of metadata, such as create time, modify time, etc., they want to provide.</p>
<ul>
<li>Support Metadata trait <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1096" target="_blank" rel="noopener noreferrer">#1096</a>)</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="-storages">🍀 Storages<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.14#-storages" class="hash-link" aria-label="Direct link to 🍀 Storages" title="Direct link to 🍀 Storages">​</a></h3>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="json-storage">JSON Storage<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.14#json-storage" class="hash-link" aria-label="Direct link to JSON Storage" title="Direct link to JSON Storage">​</a></h4>
<ul>
<li>Add JsonStorage support to CLI <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1135" target="_blank" rel="noopener noreferrer">#1135</a>)</li>
<li>Rename <code>Jsonl</code>Storage to <code>Json</code>Storage <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1128" target="_blank" rel="noopener noreferrer">#1128</a>)</li>
<li>Support <code>JSON</code> format in <code>JSONL storage</code> <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1123" target="_blank" rel="noopener noreferrer">#1123</a>)</li>
<li>Support <code>Jsonl</code> Storage <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1053" target="_blank" rel="noopener noreferrer">#1053</a>)</li>
</ul>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="composite-storage">Composite Storage<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.14#composite-storage" class="hash-link" aria-label="Direct link to Composite Storage" title="Direct link to Composite Storage">​</a></h4>
<ul>
<li>Add CompositeStorage which bundles multiple storages <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1068" target="_blank" rel="noopener noreferrer">#1068</a>)</li>
</ul>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="indexeddb-storage">IndexedDB Storage<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.14#indexeddb-storage" class="hash-link" aria-label="Direct link to IndexedDB Storage" title="Direct link to IndexedDB Storage">​</a></h4>
<ul>
<li>Add IndexedDB storage support <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1067" target="_blank" rel="noopener noreferrer">#1067</a>)</li>
</ul>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="web-storage">Web Storage<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.14#web-storage" class="hash-link" aria-label="Direct link to Web Storage" title="Direct link to Web Storage">​</a></h4>
<ul>
<li>Add WebStorage - support localStorage &amp; sessionStorage for web browsers <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1050" target="_blank" rel="noopener noreferrer">#1050</a>)</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="-other-new-features">🍀 Other new features<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.14#-other-new-features" class="hash-link" aria-label="Direct link to 🍀 Other new features" title="Direct link to 🍀 Other new features">​</a></h3>
<ul>
<li>Wrap identifiers with double quote (<code>"</code>) at <code>to_sql</code> <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1130" target="_blank" rel="noopener noreferrer">#1130</a>)</li>
<li>Support Values Query at ASTBuilder <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1041" target="_blank" rel="noopener noreferrer">#1041</a>)</li>
<li>Support <code>Schema::from_ddl(ddl: &amp;str) -&gt; String</code> <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1089" target="_blank" rel="noopener noreferrer">#1089</a>)</li>
<li>Support column alias for Table, Derived Table <a href="https://github.com/ding-young" target="_blank" rel="noopener noreferrer">@ding-young</a> (<a href="https://github.com/gluesql/gluesql/pull/1065" target="_blank" rel="noopener noreferrer">#1065</a>)</li>
<li>Support <code>TableFactor::{Derived, Dictionary, Series}</code> in AstBuilder <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1007" target="_blank" rel="noopener noreferrer">#1007</a>)</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="-interface-changes">🌊 Interface Changes<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.14#-interface-changes" class="hash-link" aria-label="Direct link to 🌊 Interface Changes" title="Direct link to 🌊 Interface Changes">​</a></h2>
<ul>
<li>Remove Store trait related cfg features, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1091" target="_blank" rel="noopener noreferrer">#1091</a>)</li>
<li>Refactor CreateTable.columns from <code>Vec&lt;ColumnDef&gt;</code> to <code>Option&lt;Vec&lt;ColumnDef&gt;&gt;</code> <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1086" target="_blank" rel="noopener noreferrer">#1086</a>)</li>
<li>Remove <code>MutResult</code> <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1073" target="_blank" rel="noopener noreferrer">#1073</a>)</li>
<li>Update all store mut trait methods to take &amp;mut self <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1072" target="_blank" rel="noopener noreferrer">#1072</a>)</li>
<li>Change StoreMut interface to use &amp;mut self, not to take ownership <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1071" target="_blank" rel="noopener noreferrer">#1071</a>)</li>
<li>Modify default ColumnOption from NOT NULL to NULL <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/997" target="_blank" rel="noopener noreferrer">#997</a>)</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="-improvements">🌟 Improvements<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.14#-improvements" class="hash-link" aria-label="Direct link to 🌟 Improvements" title="Direct link to 🌟 Improvements">​</a></h2>
<ul>
<li>Add a case for insert with source <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1211" target="_blank" rel="noopener noreferrer">#1211</a>)</li>
<li>Apply workspace inheritance to remaining Cargo.toml in storages/, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1181" target="_blank" rel="noopener noreferrer">#1181</a>)</li>
<li>Add nullable, key, default to <code>GLUE_TABLE_COLUMNS</code> <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1177" target="_blank" rel="noopener noreferrer">#1177</a>)</li>
<li>Update core to bundle all errors using error module, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1178" target="_blank" rel="noopener noreferrer">#1178</a>)</li>
<li>Update global Error enum to display with error module prefix <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1175" target="_blank" rel="noopener noreferrer">#1175</a>)</li>
<li>fix: typo <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1161" target="_blank" rel="noopener noreferrer">#1161</a>)</li>
<li>Move the SCHEMA_PREFIX const into an impl in SledStorage <a href="https://github.com/garypen" target="_blank" rel="noopener noreferrer">@garypen</a> (<a href="https://github.com/gluesql/gluesql/pull/1151" target="_blank" rel="noopener noreferrer">#1151</a>)</li>
<li>Merge evaluate_stateless into evaluate, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1132" target="_blank" rel="noopener noreferrer">#1132</a>)</li>
<li>Remove memory-storage dep from JsonStorage/ Cargo.toml <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1131" target="_blank" rel="noopener noreferrer">#1131</a>)</li>
<li>Simplify JsonlStorage codes <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1126" target="_blank" rel="noopener noreferrer">#1126</a>)</li>
<li>Bump rust version to 1.68 <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1125" target="_blank" rel="noopener noreferrer">#1125</a>)</li>
<li>Keep <code>Cargo.lock</code> <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1121" target="_blank" rel="noopener noreferrer">#1121</a>)</li>
<li>Replace closure to variable in <code>data/interval</code> module <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1118" target="_blank" rel="noopener noreferrer">#1118</a>)</li>
<li>Add <code>f64</code> support to <code>data::Key</code> <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1114" target="_blank" rel="noopener noreferrer">#1114</a>)</li>
<li>Add Ord impl for Key, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1110" target="_blank" rel="noopener noreferrer">#1110</a>)</li>
<li>join_expr when in_subquery, exists expr in join constraint <a href="https://github.com/ding-young" target="_blank" rel="noopener noreferrer">@ding-young</a> (<a href="https://github.com/gluesql/gluesql/pull/1112" target="_blank" rel="noopener noreferrer">#1112</a>)</li>
<li>Split JS related GitHub action, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1109" target="_blank" rel="noopener noreferrer">#1109</a>)</li>
<li>Fix error handling for <code>ilike</code> function on <code>Literal</code> being treated as… <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1107" target="_blank" rel="noopener noreferrer">#1107</a>)</li>
<li>Remove <code>Rc</code> in <code>validate.rs</code> <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1106" target="_blank" rel="noopener noreferrer">#1106</a>)</li>
<li>Remove <code>Error::Storage</code> variant <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1105" target="_blank" rel="noopener noreferrer">#1105</a>)</li>
<li>Replace <code>Box::pin</code> to <code>futures_enum::Stream</code> <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1103" target="_blank" rel="noopener noreferrer">#1103</a>)</li>
<li>Remove stream unneeded map ok uses <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1104" target="_blank" rel="noopener noreferrer">#1104</a>)</li>
<li>Replace <code>TryStream</code> to <code>Stream</code> <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1102" target="_blank" rel="noopener noreferrer">#1102</a>)</li>
<li>Remove <code>Rc</code> from <code>ColumnValidation</code> <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1101" target="_blank" rel="noopener noreferrer">#1101</a>)</li>
<li>Remove unneeded Rc uses in fetch_labels <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1098" target="_blank" rel="noopener noreferrer">#1098</a>)</li>
<li>Simplify TryStreamExt using codes in join executor, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1097" target="_blank" rel="noopener noreferrer">#1097</a>)</li>
<li>Fix typo in plan/validate.rs <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1093" target="_blank" rel="noopener noreferrer">#1093</a>)</li>
<li>Update IdbStorage to use Schema::{to_ddl, from_ddl} to manage schema … <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1090" target="_blank" rel="noopener noreferrer">#1090</a>)</li>
<li>Update Cargo.toml files to inherit workspace level configs, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1088" target="_blank" rel="noopener noreferrer">#1088</a>)</li>
<li>Add Error enum to core::prelude <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1087" target="_blank" rel="noopener noreferrer">#1087</a>)</li>
<li>Update <code>StringExt</code> implementation to use <code>str</code> <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1082" target="_blank" rel="noopener noreferrer">#1082</a>)</li>
<li>Add enum <code>StrSlice</code> under enum <code>Evaluated</code> <a href="https://github.com/zmrdltl" target="_blank" rel="noopener noreferrer">@zmrdltl</a> (<a href="https://github.com/gluesql/gluesql/pull/999" target="_blank" rel="noopener noreferrer">#999</a>)</li>
<li>refactor plan::validate::Context.labels from String to str <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1079" target="_blank" rel="noopener noreferrer">#1079</a>)</li>
<li>Replace <code>dyn object</code> to generic <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1075" target="_blank" rel="noopener noreferrer">#1075</a>)</li>
<li>Implement ValidationContext(schema_map + alias) to enhance validation of ambiguous columns <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/883" target="_blank" rel="noopener noreferrer">#883</a>)</li>
<li>Remove <code>clone</code> in <code>check_table_factor</code> <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1058" target="_blank" rel="noopener noreferrer">#1058</a>)</li>
<li>Bump rust-toolchain version to <code>1.66</code> <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1057" target="_blank" rel="noopener noreferrer">#1057</a>)</li>
<li>Bump <code>sqlparser</code> version to <code>0.30</code> <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1056" target="_blank" rel="noopener noreferrer">#1056</a>)</li>
<li>Replace <code>Box::pin</code> to <code>futures_enum</code> in aggregate module <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1055" target="_blank" rel="noopener noreferrer">#1055</a>)</li>
<li>Update js/ Cargo.toml to use gloo-utils for serde handling <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1049" target="_blank" rel="noopener noreferrer">#1049</a>)</li>
<li>Remove ast::ColumnOption and merge UNIQUE option to ColumnDef <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1044" target="_blank" rel="noopener noreferrer">#1044</a>)</li>
<li>Rewrite &amp; simplify plan/context.rs codes, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1045" target="_blank" rel="noopener noreferrer">#1045</a>)</li>
<li>Move ast::ColumnOption::Default variant to ColumnDef <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1042" target="_blank" rel="noopener noreferrer">#1042</a>)</li>
<li>[AST-Builder] Remove unused prebuild nodes  <a href="https://github.com/ding-young" target="_blank" rel="noopener noreferrer">@ding-young</a> (<a href="https://github.com/gluesql/gluesql/pull/1043" target="_blank" rel="noopener noreferrer">#1043</a>)</li>
<li>Remove data::RowError, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1040" target="_blank" rel="noopener noreferrer">#1040</a>)</li>
<li>Reorder project in ASTBuilder (project -&gt; ordery_by -&gt; limit,offset) <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1039" target="_blank" rel="noopener noreferrer">#1039</a>)</li>
<li>Remove unused LimitOffsetNode in AST builder <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1038" target="_blank" rel="noopener noreferrer">#1038</a>)</li>
<li>Rename executor/ blend.rs module to project.rs <a href="https://github.com/SaumyaBhushan" target="_blank" rel="noopener noreferrer">@SaumyaBhushan</a> (<a href="https://github.com/gluesql/gluesql/pull/1036" target="_blank" rel="noopener noreferrer">#1036</a>)</li>
<li>Add Debug to AST builder nodes <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1022" target="_blank" rel="noopener noreferrer">#1022</a>)</li>
<li>Bump rust toolchain version to 1.65 <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1035" target="_blank" rel="noopener noreferrer">#1035</a>)</li>
<li>Remove <code>Content::Shared</code> variant in executor/ <code>RowContext</code> <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1032" target="_blank" rel="noopener noreferrer">#1032</a>)</li>
<li>Merge insert logics in row.rs &amp; execute.rs into executor/insert.rs <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1031" target="_blank" rel="noopener noreferrer">#1031</a>)</li>
<li>Merge FilterContext and BlendContext into RowContext <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1029" target="_blank" rel="noopener noreferrer">#1029</a>)</li>
<li>Update <code>data::Row</code> to contain columns <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1026" target="_blank" rel="noopener noreferrer">#1026</a>)</li>
<li>Add LIST type support in CONCAT function <a href="https://github.com/seonghun-dev" target="_blank" rel="noopener noreferrer">@seonghun-dev</a> (<a href="https://github.com/gluesql/gluesql/pull/1021" target="_blank" rel="noopener noreferrer">#1021</a>)</li>
<li>Remove LimitOffsetNode in AST builder <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1023" target="_blank" rel="noopener noreferrer">#1023</a>)</li>
<li>Fix typo <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1020" target="_blank" rel="noopener noreferrer">#1020</a>)</li>
<li>Add NumericNode to handle numeric value inputs in AST builder <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1017" target="_blank" rel="noopener noreferrer">#1017</a>)</li>
<li>Update ValueError::InvalidJsonString error to show input text <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1018" target="_blank" rel="noopener noreferrer">#1018</a>)</li>
<li>Add null() func which makes NULL value in AST builder <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1016" target="_blank" rel="noopener noreferrer">#1016</a>)</li>
<li>Add --all-targets option to cargo clippy rust gh-action <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1015" target="_blank" rel="noopener noreferrer">#1015</a>)</li>
<li>Move import <code>ColumnOption</code> used only by <code>alter-table</code> feature in ast-builder <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1014" target="_blank" rel="noopener noreferrer">#1014</a>)</li>
<li>Add value/ binary_op <code>Parital{Ord,Cmp}</code> impl macro <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1013" target="_blank" rel="noopener noreferrer">#1013</a>)</li>
<li>Change to use internal chrono errors in parsing datetime <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1010" target="_blank" rel="noopener noreferrer">#1010</a>)</li>
<li>Resolve unreachable branch of <code>Value::position</code> <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1012" target="_blank" rel="noopener noreferrer">#1012</a>)</li>
<li>Apply binary_op macros to existing data types <a href="https://github.com/ChobobDev" target="_blank" rel="noopener noreferrer">@ChobobDev</a> (<a href="https://github.com/gluesql/gluesql/pull/987" target="_blank" rel="noopener noreferrer">#987</a>)</li>
<li>chore: Use rust-cache action to cache dependencies <a href="https://github.com/jongwooo" target="_blank" rel="noopener noreferrer">@jongwooo</a> (<a href="https://github.com/gluesql/gluesql/pull/1006" target="_blank" rel="noopener noreferrer">#1006</a>)</li>
<li>Group the import statements <a href="https://github.com/yugeeklab" target="_blank" rel="noopener noreferrer">@yugeeklab</a> (<a href="https://github.com/gluesql/gluesql/pull/1005" target="_blank" rel="noopener noreferrer">#1005</a>)</li>
<li>Make Tester::new async <a href="https://github.com/ShaddyDC" target="_blank" rel="noopener noreferrer">@ShaddyDC</a> (<a href="https://github.com/gluesql/gluesql/pull/1004" target="_blank" rel="noopener noreferrer">#1004</a>)</li>
<li>Make MemoryStorage Store trait features optional, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1003" target="_blank" rel="noopener noreferrer">#1003</a>)</li>
<li>Replace <code>double quotes</code> to <code>identifier</code> <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1001" target="_blank" rel="noopener noreferrer">#1001</a>)</li>
<li>Change chrono <code>from_*</code> methods to <code>from_*_opt</code> <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1000" target="_blank" rel="noopener noreferrer">#1000</a>)</li>
<li>Improve duplicate column names validation <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/995" target="_blank" rel="noopener noreferrer">#995</a>)</li>
<li>Register <code>lock</code> when <code>fetch_all_schemas</code> face <code>idle</code> <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/996" target="_blank" rel="noopener noreferrer">#996</a>)</li>
<li>Merge ColumnOption::{Null, NotNull} into a single option <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/986" target="_blank" rel="noopener noreferrer">#986</a>)</li>
<li>Update rust.yml github action to test examples/ <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/994" target="_blank" rel="noopener noreferrer">#994</a>)</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="-documentation">🌳 Documentation<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.14#-documentation" class="hash-link" aria-label="Direct link to 🌳 Documentation" title="Direct link to 🌳 Documentation">​</a></h2>
<p><strong>We now provide an official documentation website at <a href="https://gluesql.org/docs" target="_blank" rel="noopener noreferrer">https://gluesql.org/docs</a></strong></p>
<ul>
<li>Add documentation for CLI <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1183" target="_blank" rel="noopener noreferrer">#1183</a>)</li>
<li>Add ast_builder null handling doc <a href="https://github.com/LEE026" target="_blank" rel="noopener noreferrer">@LEE026</a> (<a href="https://github.com/gluesql/gluesql/pull/1209" target="_blank" rel="noopener noreferrer">#1209</a>)</li>
<li>Add document of datetime current date and time for ast-builder <a href="https://github.com/heewoneha" target="_blank" rel="noopener noreferrer">@heewoneha</a> (<a href="https://github.com/gluesql/gluesql/pull/1208" target="_blank" rel="noopener noreferrer">#1208</a>)</li>
<li>docs: write position and indexing docs <a href="https://github.com/Bangseungjae" target="_blank" rel="noopener noreferrer">@Bangseungjae</a> (<a href="https://github.com/gluesql/gluesql/pull/1206" target="_blank" rel="noopener noreferrer">#1206</a>)</li>
<li>Add docs/formatting for ast_builder <a href="https://github.com/sooyeonyim-t" target="_blank" rel="noopener noreferrer">@sooyeonyim-t</a> (<a href="https://github.com/gluesql/gluesql/pull/1200" target="_blank" rel="noopener noreferrer">#1200</a>)</li>
<li>Update math basic arithmetic docs for ast_builder <a href="https://github.com/changi1122" target="_blank" rel="noopener noreferrer">@changi1122</a> (<a href="https://github.com/gluesql/gluesql/pull/1202" target="_blank" rel="noopener noreferrer">#1202</a>)</li>
<li>Add pattern-matching doc for ast_builder <a href="https://github.com/LEE026" target="_blank" rel="noopener noreferrer">@LEE026</a> (<a href="https://github.com/gluesql/gluesql/pull/1199" target="_blank" rel="noopener noreferrer">#1199</a>)</li>
<li>Add ast builder Trimming function docs <a href="https://github.com/Bangseungjae" target="_blank" rel="noopener noreferrer">@Bangseungjae</a> (<a href="https://github.com/gluesql/gluesql/pull/1197" target="_blank" rel="noopener noreferrer">#1197</a>)</li>
<li>Add doc about the function Date &amp; Time Conversion <a href="https://github.com/heewoneha" target="_blank" rel="noopener noreferrer">@heewoneha</a> (<a href="https://github.com/gluesql/gluesql/pull/1196" target="_blank" rel="noopener noreferrer">#1196</a>)</li>
<li>add Docs/case conversion(upper, lower, InitCap) in ast builder <a href="https://github.com/sooyeonyim-t" target="_blank" rel="noopener noreferrer">@sooyeonyim-t</a> (<a href="https://github.com/gluesql/gluesql/pull/1195" target="_blank" rel="noopener noreferrer">#1195</a>)</li>
<li>Add math conversion docs for ast_builder <a href="https://github.com/changi1122" target="_blank" rel="noopener noreferrer">@changi1122</a> (<a href="https://github.com/gluesql/gluesql/pull/1192" target="_blank" rel="noopener noreferrer">#1192</a>)</li>
<li>Added documentation for the round, ceil, and floor functions in ast-builder <a href="https://github.com/LEE026" target="_blank" rel="noopener noreferrer">@LEE026</a> (<a href="https://github.com/gluesql/gluesql/pull/1191" target="_blank" rel="noopener noreferrer">#1191</a>)</li>
<li>Add  documentation layout for AstBuilder <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1184" target="_blank" rel="noopener noreferrer">#1184</a>)</li>
<li>Add documentation for Json Storage <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1170" target="_blank" rel="noopener noreferrer">#1170</a>)</li>
<li>Add documentation for math functions <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1173" target="_blank" rel="noopener noreferrer">#1173</a>)</li>
<li>Add doc for datetime, geometry, list &amp; map and other functions, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1172" target="_blank" rel="noopener noreferrer">#1172</a>)</li>
<li>Add documentation for text functions in SQL <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1167" target="_blank" rel="noopener noreferrer">#1167</a>)</li>
<li>Write docs/ Supported Storages section contents, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1165" target="_blank" rel="noopener noreferrer">#1165</a>)</li>
<li>Add SQL function list with categories to docs/ <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1166" target="_blank" rel="noopener noreferrer">#1166</a>)</li>
<li>Write docs/getting-started/javascript-web.md <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1159" target="_blank" rel="noopener noreferrer">#1159</a>)</li>
<li>Write docs/ Developing Custom Storages contents <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1155" target="_blank" rel="noopener noreferrer">#1155</a>)</li>
<li>docs: add newly added data type into README.md <a href="https://github.com/ChobobDev" target="_blank" rel="noopener noreferrer">@ChobobDev</a> (<a href="https://github.com/gluesql/gluesql/pull/1137" target="_blank" rel="noopener noreferrer">#1137</a>)</li>
<li>docs(readme): add discord icon to chat badge <a href="https://github.com/LeoDog896" target="_blank" rel="noopener noreferrer">@LeoDog896</a> (<a href="https://github.com/gluesql/gluesql/pull/1122" target="_blank" rel="noopener noreferrer">#1122</a>)</li>
<li>docs(javascript): update examples link <a href="https://github.com/LeoDog896" target="_blank" rel="noopener noreferrer">@LeoDog896</a> (<a href="https://github.com/gluesql/gluesql/pull/1108" target="_blank" rel="noopener noreferrer">#1108</a>)</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="docs---setup">Docs - setup<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.14#docs---setup" class="hash-link" aria-label="Direct link to Docs - setup" title="Direct link to Docs - setup">​</a></h3>
<ul>
<li>Add gh-action for docs build - runs on both push &amp; pr <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1215" target="_blank" rel="noopener noreferrer">#1215</a>)</li>
<li>Setup blog based on docusaurus, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1212" target="_blank" rel="noopener noreferrer">#1212</a>)</li>
<li>Remove mdbook which is replaced by docs/ (docusaurus based) <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1164" target="_blank" rel="noopener noreferrer">#1164</a>)</li>
<li>Add docusaurus deployment github action setup <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1163" target="_blank" rel="noopener noreferrer">#1163</a>)</li>
<li>Update coverage, javascript and rust gh action to ignore <code>docs/**</code> pa… <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1168" target="_blank" rel="noopener noreferrer">#1168</a>)</li>
<li>Update docs/ global styles, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1156" target="_blank" rel="noopener noreferrer">#1156</a>)</li>
<li>Setup new documentation based on docusaurus <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1136" target="_blank" rel="noopener noreferrer">#1136</a>)</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="-tests">📋 Tests<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.14#-tests" class="hash-link" aria-label="Direct link to 📋 Tests" title="Direct link to 📋 Tests">​</a></h2>
<ul>
<li>Add ifnull test suite for ast_builder <a href="https://github.com/LEE026" target="_blank" rel="noopener noreferrer">@LEE026</a> (<a href="https://github.com/gluesql/gluesql/pull/1207" target="_blank" rel="noopener noreferrer">#1207</a>)</li>
<li>Add datetime current date and time test case for ast builder <a href="https://github.com/heewoneha" target="_blank" rel="noopener noreferrer">@heewoneha</a> (<a href="https://github.com/gluesql/gluesql/pull/1205" target="_blank" rel="noopener noreferrer">#1205</a>)</li>
<li>Add Position and Indexing test code <a href="https://github.com/Bangseungjae" target="_blank" rel="noopener noreferrer">@Bangseungjae</a> (<a href="https://github.com/gluesql/gluesql/pull/1203" target="_blank" rel="noopener noreferrer">#1203</a>)</li>
<li>Add math basic arithmetic test case for ast_builder <a href="https://github.com/changi1122" target="_blank" rel="noopener noreferrer">@changi1122</a> (<a href="https://github.com/gluesql/gluesql/pull/1201" target="_blank" rel="noopener noreferrer">#1201</a>)</li>
<li>Add testcase/formatting for ast_builder <a href="https://github.com/sooyeonyim-t" target="_blank" rel="noopener noreferrer">@sooyeonyim-t</a> (<a href="https://github.com/gluesql/gluesql/pull/1198" target="_blank" rel="noopener noreferrer">#1198</a>)</li>
<li>Add pattern_matching test cases for ast_builder <a href="https://github.com/LEE026" target="_blank" rel="noopener noreferrer">@LEE026</a> (<a href="https://github.com/gluesql/gluesql/pull/1194" target="_blank" rel="noopener noreferrer">#1194</a>)</li>
<li>Add test code function / text / trimming <a href="https://github.com/Bangseungjae" target="_blank" rel="noopener noreferrer">@Bangseungjae</a> (<a href="https://github.com/gluesql/gluesql/pull/1190" target="_blank" rel="noopener noreferrer">#1190</a>)</li>
<li>Add Testcase/case conversion <a href="https://github.com/sooyeonyim-t" target="_blank" rel="noopener noreferrer">@sooyeonyim-t</a> (<a href="https://github.com/gluesql/gluesql/pull/1193" target="_blank" rel="noopener noreferrer">#1193</a>)</li>
<li>Add datetime conversion test cases for ast_builder <a href="https://github.com/heewoneha" target="_blank" rel="noopener noreferrer">@heewoneha</a> (<a href="https://github.com/gluesql/gluesql/pull/1187" target="_blank" rel="noopener noreferrer">#1187</a>)</li>
<li>Add math conversion test case for ast_builder <a href="https://github.com/changi1122" target="_blank" rel="noopener noreferrer">@changi1122</a> (<a href="https://github.com/gluesql/gluesql/pull/1189" target="_blank" rel="noopener noreferrer">#1189</a>)</li>
<li>Add rounding test cases for ast_builder <a href="https://github.com/LEE026" target="_blank" rel="noopener noreferrer">@LEE026</a> (<a href="https://github.com/gluesql/gluesql/pull/1186" target="_blank" rel="noopener noreferrer">#1186</a>)</li>
<li>Update delete and insert tests in test-suite/, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1180" target="_blank" rel="noopener noreferrer">#1180</a>)</li>
<li>Remove gen-_transaction_dictionary_tests! in test-suite, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1179" target="_blank" rel="noopener noreferrer">#1179</a>)</li>
<li>Refactor geometry function tests in test-suite, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1176" target="_blank" rel="noopener noreferrer">#1176</a>)</li>
<li>Refactor SQL function tests in test-suite, <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1174" target="_blank" rel="noopener noreferrer">#1174</a>)</li>
<li>fix : fix missing intg test for new data type <a href="https://github.com/ChobobDev" target="_blank" rel="noopener noreferrer">@ChobobDev</a> (<a href="https://github.com/gluesql/gluesql/pull/1143" target="_blank" rel="noopener noreferrer">#1143</a>)</li>
<li>Add unit tests for <code>TryFrom&lt;&amp;Value&gt; for Decimal</code> <a href="https://github.com/ChobobDev" target="_blank" rel="noopener noreferrer">@ChobobDev</a> (<a href="https://github.com/gluesql/gluesql/pull/1139" target="_blank" rel="noopener noreferrer">#1139</a>)</li>
<li>Add "cli" unittest <a href="https://github.com/pythonbrad" target="_blank" rel="noopener noreferrer">@pythonbrad</a> (<a href="https://github.com/gluesql/gluesql/pull/1094" target="_blank" rel="noopener noreferrer">#1094</a>)</li>
<li>Add <code>core/data</code> module unit tests <a href="https://github.com/pythonbrad" target="_blank" rel="noopener noreferrer">@pythonbrad</a> (<a href="https://github.com/gluesql/gluesql/pull/1092" target="_blank" rel="noopener noreferrer">#1092</a>)</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="-bug-fixes">🐛 Bug Fixes<a href="https://gluesql.org/docs/0.19.0/blog/release-v0.14#-bug-fixes" class="hash-link" aria-label="Direct link to 🐛 Bug Fixes" title="Direct link to 🐛 Bug Fixes">​</a></h2>
<ul>
<li>Fix docusaurus pages/index broken link <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1214" target="_blank" rel="noopener noreferrer">#1214</a>)</li>
<li>Fix docs/ Discord GlueSQL channel invite link address <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1213" target="_blank" rel="noopener noreferrer">#1213</a>)</li>
<li>Fix InvalidJsonString error message replacing payload to fileName <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1185" target="_blank" rel="noopener noreferrer">#1185</a>)</li>
<li>Fix TryFrom <code>Value::Str</code> to <code>u128</code> not to use <code>parse_uuid</code> <a href="https://github.com/ChobobDev" target="_blank" rel="noopener noreferrer">@ChobobDev</a> (<a href="https://github.com/gluesql/gluesql/pull/1134" target="_blank" rel="noopener noreferrer">#1134</a>)</li>
<li>Fix column alias with identifer for <code>TableFactor::Derived</code> <a href="https://github.com/ding-young" target="_blank" rel="noopener noreferrer">@ding-young</a> (<a href="https://github.com/gluesql/gluesql/pull/1119" target="_blank" rel="noopener noreferrer">#1119</a>)</li>
<li>Pass data even when <code>deleted_by</code> is not present <a href="https://github.com/ever0de" target="_blank" rel="noopener noreferrer">@ever0de</a> (<a href="https://github.com/gluesql/gluesql/pull/1117" target="_blank" rel="noopener noreferrer">#1117</a>)</li>
<li>Fix MemoryStorage &amp; WebStorage primary key support <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1115" target="_blank" rel="noopener noreferrer">#1115</a>)</li>
<li>Fix <code>plan::validate</code> to handle <code>CTAS</code> and <code>ITAS</code> adding unit test <a href="https://github.com/devgony" target="_blank" rel="noopener noreferrer">@devgony</a> (<a href="https://github.com/gluesql/gluesql/pull/1074" target="_blank" rel="noopener noreferrer">#1074</a>)</li>
<li>Fix test-suite tester functions to show (found, expected) shape <a href="https://github.com/panarch" target="_blank" rel="noopener noreferrer">@panarch</a> (<a href="https://github.com/gluesql/gluesql/pull/1028" target="_blank" rel="noopener noreferrer">#1028</a>)</li>
</ul>]]></content>
        <author>
            <name>Taehoon Moon</name>
            <uri>https://github.com/panarch</uri>
        </author>
        <category label="v0.14" term="v0.14"/>
        <category label="release-note" term="release-note"/>
    </entry>
</feed>