Migrate to tree-sitter-sequel (#905)

For #891.
pull/906/head
Antonin Delpeuch 2025-10-15 09:52:40 +07:00 committed by GitHub
parent aca32ba1ac
commit 2a65dd7e02
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
63 changed files with 41 additions and 950679 deletions

11
Cargo.lock generated

@ -315,6 +315,7 @@ dependencies = [
"tree-sitter-rust-orchard",
"tree-sitter-scala",
"tree-sitter-scheme",
"tree-sitter-sequel",
"tree-sitter-sfapex",
"tree-sitter-solidity",
"tree-sitter-swift",
@ -1433,6 +1434,16 @@ dependencies = [
"tree-sitter-language",
]
[[package]]
name = "tree-sitter-sequel"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d198ad3c319c02e43c21efa1ec796b837afcb96ffaef1a40c1978fbdcec7d17"
dependencies = [
"cc",
"tree-sitter-language",
]
[[package]]
name = "tree-sitter-sfapex"
version = "2.4.0"

@ -115,6 +115,7 @@ tree-sitter-ruby = "0.23.1"
tree-sitter-rust-orchard = "0.13.0"
tree-sitter-scala = "0.23.3"
tree-sitter-scheme = "0.24.7"
tree-sitter-sequel = "0.3.11"
tree-sitter-sfapex = "2.4.0"
tree-sitter-solidity = "1.2.13"
tree-sitter-swift = "0.7.0"

@ -132,11 +132,6 @@ fn main() {
src_dir: "vendored_parsers/tree-sitter-smali-src",
extra_files: vec!["scanner.c"],
},
TreeSitterParser {
name: "tree-sitter-sql",
src_dir: "vendored_parsers/tree-sitter-sql-src",
extra_files: vec!["scanner.cc"],
},
TreeSitterParser {
name: "tree-sitter-vhdl",
src_dir: "vendored_parsers/tree-sitter-vhdl-src",

@ -53,7 +53,7 @@ with `difft --list-languages`.
| Scheme | [6cdh/tree-sitter-scheme](https://github.com/6cdh/tree-sitter-scheme) |
| Smali | [amaanq/tree-sitter-smali](https://github.com/amaanq/tree-sitter-smali) |
| Solidity | [JoranHonig/tree-sitter-solidity](https://github.com/JoranHonig/tree-sitter-solidity) |
| SQL | [m-novikov/tree-sitter-sql](https://github.com/m-novikov/tree-sitter-sql) |
| SQL | [derekstride/tree-sitter-sql](https://github.com/derekstride/tree-sitter-sql) |
| Swift | [alex-pinkus/tree-sitter-swift](https://github.com/alex-pinkus/tree-sitter-swift) |
| TypeScript, TSX | [tree-sitter/tree-sitter-typescript](https://github.com/tree-sitter/tree-sitter-typescript) |
| Verilog | [tree-sitter/tree-sitter-verilog](https://github.com/tree-sitter/tree-sitter-verilog) |

@ -253,6 +253,9 @@ sample_files/slow_1.rs sample_files/slow_2.rs
sample_files/small_1.js sample_files/small_2.js
86b1132b6c17fcc2cbec65b1c248baa9 -
sample_files/sql_1.sql sample_files/sql_2.sql
ee54ee3f974aa54c8bdfc2b9075824f2 -
sample_files/string_subwords_1.el sample_files/string_subwords_2.el
b66e960672189960c2d35ef68b47a195 -

@ -0,0 +1,10 @@
-- A comment
create table apples (
variety varchar primary key not null,
ancestor varchar references apples (path));
create table pears (
name varchar primary key not null,
origin varchar not null,
ancestor varchar references pears (path) not null);

@ -0,0 +1,11 @@
-- A comment
create table apples (
variety varchar primary key not null,
ancestor varchar not null);
create table pears (
name varchar primary key not null,
origin varchar not null,
price float,
ancestor varchar references pears (path) not null);

@ -82,7 +82,6 @@ extern "C" {
fn tree_sitter_qmljs() -> ts::Language;
fn tree_sitter_smali() -> ts::Language;
fn tree_sitter_scss() -> ts::Language;
fn tree_sitter_sql() -> ts::Language;
fn tree_sitter_vhdl() -> ts::Language;
}
@ -1005,16 +1004,14 @@ pub(crate) fn from_language(language: guess::Language) -> TreeSitterConfig {
}
}
Sql => {
let language = unsafe { tree_sitter_sql() };
let language_fn = tree_sitter_sequel::LANGUAGE;
let language = tree_sitter::Language::new(language_fn);
TreeSitterConfig {
language: language.clone(),
atom_nodes: ["string", "identifier"].into_iter().collect(),
delimiter_tokens: vec![("(", ")")],
highlight_query: ts::Query::new(
&language,
include_str!("../../vendored_parsers/highlights/sql.scm"),
)
.unwrap(),
highlight_query: ts::Query::new(&language, tree_sitter_sequel::HIGHLIGHTS_QUERY)
.unwrap(),
sub_languages: vec![],
}
}

@ -1 +0,0 @@
../tree-sitter-sql/queries/highlights.scm

@ -1 +0,0 @@
tree-sitter-sql/src

@ -1,9 +0,0 @@
root = true
[*.{js,html,txt}]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

@ -1,3 +0,0 @@
/src/** linguist-vendored
/examples/* linguist-vendored
* text=auto eof=lf

@ -1,60 +0,0 @@
name: Node.js CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-2019, macos-latest]
node-version: [14.x, 16.x, 18.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm run build --if-present
- run: npx prettier --check .
- run: npm run gen
- name: Verify generated code
if: runner.os == 'Linux'
run: |
if ! git diff --quiet --ignore-submodules -- src/
then
echo >&2 "Generated files in src/ differ, please run 'npm run gen' to update generated code"
git diff-index --name-status -r --ignore-submodules HEAD src/ >&2
exit 1
fi
- run: npm test
- name: Parse real world examples (ignoring errors for now)
continue-on-error: true
run: npm acceptance
compile:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
compiler: [gcc, clang++]
name: compile
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- if: matrix.os == 'windows-latest' && matrix.compiler == 'gcc'
uses: egor-tensin/setup-mingw@v2
- name: build
run: ${{ matrix.compiler }} -o scanner.o -I./src -c src/scanner.cc -Werror

@ -1,22 +0,0 @@
name: Rust
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
env:
CARGO_TERM_COLOR: always
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build
run: cargo build --verbose
- name: Run tests
run: cargo test --verbose

@ -1,6 +0,0 @@
node_modules/
tree-sitter-sql.wasm
target/
build/
venv/
yarn.lock

@ -1,5 +0,0 @@
repos:
- repo: https://github.com/pre-commit/mirrors-prettier
rev: "v2.7.1"
hooks:
- id: prettier

@ -1,6 +0,0 @@
README.md
.github/
bindings/
target/
src/
docs/vendor/

@ -1,5 +0,0 @@
{
"arrowParens": "avoid",
"trailingComma": "all",
"endOfLine": "auto"
}

@ -1,57 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "aho-corasick"
version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
dependencies = [
"memchr",
]
[[package]]
name = "cc"
version = "1.0.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "regex"
version = "1.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
[[package]]
name = "tree-sitter"
version = "0.19.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad726ec26496bf4c083fff0f43d4eb3a2ad1bba305323af5ff91383c0b6ecac0"
dependencies = [
"cc",
"regex",
]
[[package]]
name = "tree-sitter-sql"
version = "0.0.2"
dependencies = [
"cc",
"tree-sitter",
]

@ -1,27 +0,0 @@
[package]
name = "tree-sitter-sql"
description = "SQL grammar for the tree-sitter parsing library"
authors = ["Maksim Novikov <mnovikov.work@gmail.com>"]
version = "0.0.2"
keywords = ["incremental", "parsing", "sql"]
categories = ["parsing", "text-editors"]
repository = "https://github.com/m-novikov/tree-sitter-sql"
edition = "2018"
license = "MIT"
build = "bindings/rust/build.rs"
include = [
"bindings/rust/*",
"grammar.js",
"queries/*",
"src/*",
]
[lib]
path = "bindings/rust/lib.rs"
[dependencies]
tree-sitter = "0.19.3"
[build-dependencies]
cc = "1.0"

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2021 Maksim Novikov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -1,49 +0,0 @@
[![Node.js CI](https://github.com/m-novikov/tree-sitter-sql/actions/workflows/node.js.yml/badge.svg)](https://github.com/m-novikov/tree-sitter-sql/actions/workflows/node.js.yml)
# SQL syntax for tree-sitter
This project initially focuses on PostgreSQL flavor of SQL
## Try it out
You can try out the parser here: [Tree Sitter SQL Playground](https://m-novikov.github.io/tree-sitter-sql/)
## Development
Install [pre-commit](https://pre-commit.com/#install) and run `pre-commit install` in the root of this repo. This will ensure
that code follows code style of this repo.
File describing grammar is [grammar.js](./grammar.js)
Every time the grammar file changes code generation needs to be run by invoking `npm run gen`
`npm test` command automatically performs code generation
Tests files are located in [test/corpus](./test/corpus)
[Here](https://tree-sitter.github.io/tree-sitter/creating-parsers#command-test) is the documentation on test file syntax
### Running tests
```
npm install --also=dev
npm test
```
### Debbuging
* `npm run parse <file.sql>` outputs a syntax tree
* `npm run extract-error <file.sql>` shows first offending line
### Goals
This parser is supposed to be used in text editors. As a result:
* it's very lax in what it considers valid SQL parse
* adding extra nodes to have convenient selection anchors is okay
### Other projects
* https://github.com/DerekStride/tree-sitter-sql
* https://github.com/dhcmrlchtdj/tree-sitter-sqlite
*

@ -1,19 +0,0 @@
{
"targets": [
{
"target_name": "tree_sitter_sql_binding",
"include_dirs": [
"<!(node -e \"require('nan')\")",
"src"
],
"sources": [
"bindings/node/binding.cc",
"src/parser.c",
"src/scanner.cc"
],
"cflags_c": [
"-std=c99",
]
}
]
}

@ -1,28 +0,0 @@
#include "tree_sitter/parser.h"
#include <node.h>
#include "nan.h"
using namespace v8;
extern "C" TSLanguage * tree_sitter_sql();
namespace {
NAN_METHOD(New) {}
void Init(Local<Object> exports, Local<Object> module) {
Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
tpl->SetClassName(Nan::New("Language").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1);
Local<Function> constructor = Nan::GetFunction(tpl).ToLocalChecked();
Local<Object> instance = constructor->NewInstance(Nan::GetCurrentContext()).ToLocalChecked();
Nan::SetInternalFieldPointer(instance, 0, tree_sitter_sql());
Nan::Set(instance, Nan::New("name").ToLocalChecked(), Nan::New("sql").ToLocalChecked());
Nan::Set(module, Nan::New("exports").ToLocalChecked(), instance);
}
NODE_MODULE(tree_sitter_sql_binding, Init)
} // namespace

@ -1,19 +0,0 @@
try {
module.exports = require("../../build/Release/tree_sitter_sql_binding");
} catch (error1) {
if (error1.code !== 'MODULE_NOT_FOUND') {
throw error1;
}
try {
module.exports = require("../../build/Debug/tree_sitter_sql_binding");
} catch (error2) {
if (error2.code !== 'MODULE_NOT_FOUND') {
throw error2;
}
throw error1
}
}
try {
module.exports.nodeTypeInfo = require("../../src/node-types.json");
} catch (_) {}

@ -1,29 +0,0 @@
fn main() {
let src_dir = std::path::Path::new("src");
let mut c_config = cc::Build::new();
c_config.include(&src_dir);
c_config
.flag_if_supported("-Wno-unused-parameter")
.flag_if_supported("-Wno-unused-but-set-variable")
.flag_if_supported("-Wno-trigraphs");
let parser_path = src_dir.join("parser.c");
c_config.file(&parser_path);
c_config.compile("parser");
println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap());
// If your language uses an external scanner written in C++,
// then include this block of code:
let mut cpp_config = cc::Build::new();
cpp_config.cpp(true);
cpp_config.include(&src_dir);
cpp_config
.flag_if_supported("-Wno-unused-parameter")
.flag_if_supported("-Wno-unused-but-set-variable");
let scanner_path = src_dir.join("scanner.cc");
cpp_config.file(&scanner_path);
cpp_config.compile("scanner");
println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
}

@ -1,52 +0,0 @@
//! This crate provides SQL language support for the [tree-sitter][] parsing library.
//!
//! Typically, you will use the [language][language func] function to add this language to a
//! tree-sitter [Parser][], and then use the parser to parse some code:
//!
//! ```
//! let code = "";
//! let mut parser = tree_sitter::Parser::new();
//! parser.set_language(tree_sitter_sql::language()).expect("Error loading SQL grammar");
//! let tree = parser.parse(code, None).unwrap();
//! ```
//!
//! [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
//! [language func]: fn.language.html
//! [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html
//! [tree-sitter]: https://tree-sitter.github.io/
use tree_sitter::Language;
extern "C" {
fn tree_sitter_sql() -> Language;
}
/// Get the tree-sitter [Language][] for this grammar.
///
/// [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
pub fn language() -> Language {
unsafe { tree_sitter_sql() }
}
/// The content of the [`node-types.json`][] file for this grammar.
///
/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types
pub const NODE_TYPES: &'static str = include_str!("../../src/node-types.json");
// Uncomment these to include any queries that this grammar contains
// pub const HIGHLIGHTS_QUERY: &'static str = include_str!("../../queries/highlights.scm");
// pub const INJECTIONS_QUERY: &'static str = include_str!("../../queries/injections.scm");
// pub const LOCALS_QUERY: &'static str = include_str!("../../queries/locals.scm");
// pub const TAGS_QUERY: &'static str = include_str!("../../queries/tags.scm");
#[cfg(test)]
mod tests {
#[test]
fn test_can_load_grammar() {
let mut parser = tree_sitter::Parser::new();
parser
.set_language(super::language())
.expect("Error loading SQL language");
}
}

@ -1,84 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Tree Sitter SQL Playground</title>
<style>
#playground-container {
max-width: 640px;
margin-left: auto;
margin-right: auto;
}
#playground-container .CodeMirror {
border: 1px solid;
}
#create-issue-btn {
padding: 0.2em;
float: right;
font-size: 1.5em;
}
#checkboxes {
padding-bottom: 1em;
}
#output-container {
border: 1px solid;
}
.highlight {
background-color: #f8f8f8;
}
</style>
</head>
<body>
<!--
This file is licensed under MIT license
Copyright (c) 2018 Max Brunsfeld
Taken from https://github.com/tree-sitter/tree-sitter/docs/section-7-playground.html
-->
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.45.0/codemirror.min.css"
/>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/clusterize.js/0.18.0/clusterize.min.css"
/>
<div id="playground-container">
<h1>Tree Sitter SQL Playground</h1>
<h4>Code</h4>
<div id="checkboxes">
<input id="logging-checkbox" type="checkbox" />
<label for="logging-checkbox">Log</label>
<input id="query-checkbox" type="checkbox" />
<label for="query-checkbox">Query</label>
</div>
<textarea id="code-input">
SELECT a, b
FROM foo
WHERE a &gt; b
GROUP BY b;</textarea
>
<div id="query-container" style="visibility: hidden; position: absolute">
<h4>Query</h4>
<textarea id="query-input"></textarea>
</div>
<h4>Tree</h4>
<span id="update-time"></span>
<div id="output-container-scroll">
<pre id="output-container" class="highlight"></pre>
</div>
<button id="create-issue-btn" type="button">Create Issue</button>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.45.0/codemirror.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/clusterize.js/0.18.0/clusterize.min.js"></script>
<script src="./vendor/tree-sitter.js"></script>
<script id="playground-script" src="./playground.js?v=3"></script>
</body>
</html>

@ -1,497 +0,0 @@
// This file is licensed under MIT license
// Copyright (c) 2018 Max Brunsfeld
// Taken from https://github.com/tree-sitter/tree-sitter/docs/assets/playground.js
let tree;
(async () => {
const CAPTURE_REGEX = /@\s*([\w\._-]+)/g;
const COLORS_BY_INDEX = [
"blue",
"chocolate",
"darkblue",
"darkcyan",
"darkgreen",
"darkred",
"darkslategray",
"dimgray",
"green",
"indigo",
"navy",
"red",
"sienna",
];
const scriptURL = document.getElementById("playground-script").src;
const codeInput = document.getElementById("code-input");
const loggingCheckbox = document.getElementById("logging-checkbox");
const outputContainer = document.getElementById("output-container");
const outputContainerScroll = document.getElementById(
"output-container-scroll",
);
const playgroundContainer = document.getElementById("playground-container");
const queryCheckbox = document.getElementById("query-checkbox");
const createIssueBtn = document.getElementById("create-issue-btn");
const queryContainer = document.getElementById("query-container");
const queryInput = document.getElementById("query-input");
const updateTimeSpan = document.getElementById("update-time");
loadState();
await TreeSitter.init();
const parser = new TreeSitter();
const codeEditor = CodeMirror.fromTextArea(codeInput, {
lineNumbers: true,
showCursorWhenSelecting: true,
});
const queryEditor = CodeMirror.fromTextArea(queryInput, {
lineNumbers: true,
showCursorWhenSelecting: true,
});
const cluster = new Clusterize({
rows: [],
noDataText: null,
contentElem: outputContainer,
scrollElem: outputContainerScroll,
});
const renderTreeOnCodeChange = debounce(renderTree, 50);
const saveStateOnChange = debounce(saveState, 2000);
const runTreeQueryOnChange = debounce(runTreeQuery, 50);
let languageName = "sql";
let treeRows = null;
let treeRowHighlightedIndex = -1;
let parseCount = 0;
let isRendering = 0;
let query;
codeEditor.on("changes", handleCodeChange);
codeEditor.on("viewportChange", runTreeQueryOnChange);
codeEditor.on("cursorActivity", debounce(handleCursorMovement, 150));
queryEditor.on("changes", debounce(handleQueryChange, 150));
loggingCheckbox.addEventListener("change", handleLoggingChange);
queryCheckbox.addEventListener("change", handleQueryEnableChange);
outputContainer.addEventListener("click", handleTreeClick);
createIssueBtn.addEventListener("click", handleCreateIssue);
handleQueryEnableChange();
await loadLanguage();
playgroundContainer.style.visibility = "visible";
async function loadLanguage() {
const query = new URL(scriptURL).search;
const url = `tree-sitter-sql.wasm${query}`;
const language = await TreeSitter.Language.load(url);
tree = null;
parser.setLanguage(language);
handleCodeChange();
handleQueryChange();
}
async function handleCodeChange(editor, changes) {
const newText = codeEditor.getValue() + "\n";
const edits = tree && changes && changes.map(treeEditForEditorChange);
const start = performance.now();
if (edits) {
for (const edit of edits) {
tree.edit(edit);
}
}
const newTree = parser.parse(newText, tree);
const duration = (performance.now() - start).toFixed(1);
updateTimeSpan.innerText = `${duration} ms`;
if (tree) tree.delete();
tree = newTree;
parseCount++;
renderTreeOnCodeChange();
runTreeQueryOnChange();
saveStateOnChange();
}
async function renderTree() {
isRendering++;
const cursor = tree.walk();
let currentRenderCount = parseCount;
let row = "";
let rows = [];
let finishedRow = false;
let visitedChildren = false;
let indentLevel = 0;
for (let i = 0; ; i++) {
if (i > 0 && i % 10000 === 0) {
await new Promise(r => setTimeout(r, 0));
if (parseCount !== currentRenderCount) {
cursor.delete();
isRendering--;
return;
}
}
let displayName;
if (cursor.nodeIsMissing) {
displayName = `MISSING ${cursor.nodeType}`;
} else if (cursor.nodeIsNamed) {
displayName = cursor.nodeType;
}
if (visitedChildren) {
if (displayName) {
finishedRow = true;
}
if (cursor.gotoNextSibling()) {
visitedChildren = false;
} else if (cursor.gotoParent()) {
visitedChildren = true;
indentLevel--;
} else {
break;
}
} else {
if (displayName) {
if (finishedRow) {
row += "</div>";
rows.push(row);
finishedRow = false;
}
const start = cursor.startPosition;
const end = cursor.endPosition;
const id = cursor.nodeId;
let fieldName = cursor.currentFieldName();
if (fieldName) {
fieldName += ": ";
} else {
fieldName = "";
}
row = `<div>${" ".repeat(
indentLevel,
)}${fieldName}<a class='plain' href="#" data-id=${id} data-range="${
start.row
},${start.column},${end.row},${end.column}">${displayName}</a> [${
start.row
}, ${start.column}] - [${end.row}, ${end.column}])`;
finishedRow = true;
}
if (cursor.gotoFirstChild()) {
visitedChildren = false;
indentLevel++;
} else {
visitedChildren = true;
}
}
}
if (finishedRow) {
row += "</div>";
rows.push(row);
}
cursor.delete();
cluster.update(rows);
treeRows = rows;
isRendering--;
handleCursorMovement();
}
function runTreeQuery(_, startRow, endRow) {
if (endRow == null) {
const viewport = codeEditor.getViewport();
startRow = viewport.from;
endRow = viewport.to;
}
codeEditor.operation(() => {
const marks = codeEditor.getAllMarks();
marks.forEach(m => m.clear());
if (tree && query) {
const captures = query.captures(
tree.rootNode,
{ row: startRow, column: 0 },
{ row: endRow, column: 0 },
);
let lastNodeId;
for (const { name, node } of captures) {
if (node.id === lastNodeId) continue;
lastNodeId = node.id;
const { startPosition, endPosition } = node;
codeEditor.markText(
{ line: startPosition.row, ch: startPosition.column },
{ line: endPosition.row, ch: endPosition.column },
{
inclusiveLeft: true,
inclusiveRight: true,
css: `color: ${colorForCaptureName(name)}`,
},
);
}
}
});
}
function handleQueryChange() {
if (query) {
query.delete();
query.deleted = true;
query = null;
}
queryEditor.operation(() => {
queryEditor.getAllMarks().forEach(m => m.clear());
if (!queryCheckbox.checked) return;
const queryText = queryEditor.getValue();
try {
query = parser.getLanguage().query(queryText);
let match;
let row = 0;
queryEditor.eachLine(line => {
while ((match = CAPTURE_REGEX.exec(line.text))) {
queryEditor.markText(
{ line: row, ch: match.index },
{ line: row, ch: match.index + match[0].length },
{
inclusiveLeft: true,
inclusiveRight: true,
css: `color: ${colorForCaptureName(match[1])}`,
},
);
}
row++;
});
} catch (error) {
const startPosition = queryEditor.posFromIndex(error.index);
const endPosition = {
line: startPosition.line,
ch: startPosition.ch + (error.length || Infinity),
};
if (error.index === queryText.length) {
if (startPosition.ch > 0) {
startPosition.ch--;
} else if (startPosition.row > 0) {
startPosition.row--;
startPosition.column = Infinity;
}
}
queryEditor.markText(startPosition, endPosition, {
className: "query-error",
inclusiveLeft: true,
inclusiveRight: true,
attributes: { title: error.message },
});
}
});
runTreeQuery();
saveQueryState();
}
function handleCursorMovement() {
if (isRendering) return;
const selection = codeEditor.getDoc().listSelections()[0];
let start = { row: selection.anchor.line, column: selection.anchor.ch };
let end = { row: selection.head.line, column: selection.head.ch };
if (
start.row > end.row ||
(start.row === end.row && start.column > end.column)
) {
let swap = end;
end = start;
start = swap;
}
const node = tree.rootNode.namedDescendantForPosition(start, end);
if (treeRows) {
if (treeRowHighlightedIndex !== -1) {
const row = treeRows[treeRowHighlightedIndex];
if (row)
treeRows[treeRowHighlightedIndex] = row.replace(
"highlighted",
"plain",
);
}
treeRowHighlightedIndex = treeRows.findIndex(row =>
row.includes(`data-id=${node.id}`),
);
if (treeRowHighlightedIndex !== -1) {
const row = treeRows[treeRowHighlightedIndex];
if (row)
treeRows[treeRowHighlightedIndex] = row.replace(
"plain",
"highlighted",
);
}
cluster.update(treeRows);
const lineHeight = cluster.options.item_height;
const scrollTop = outputContainerScroll.scrollTop;
const containerHeight = outputContainerScroll.clientHeight;
const offset = treeRowHighlightedIndex * lineHeight;
if (scrollTop > offset - 20) {
$(outputContainerScroll).animate({ scrollTop: offset - 20 }, 150);
} else if (scrollTop < offset + lineHeight + 40 - containerHeight) {
$(outputContainerScroll).animate(
{ scrollTop: offset - containerHeight + 40 },
150,
);
}
}
}
function handleCreateIssue() {
const queryText = codeEditor.getValue();
const outputText = outputContainer.innerText;
const title = `Error parsing SQL`;
const body = `Error when parsing the following SQL:
\`\`\`
${queryText}
\`\`\`
Error:
\`\`\`
${outputText}
\`\`\``;
const queryParams = `title=${encodeURIComponent(
title,
)}&body=${encodeURIComponent(body)}`;
const url = `https://github.com/m-novikov/tree-sitter-sql/issues/new?${queryParams}`;
window.open(url);
}
function handleTreeClick(event) {
if (event.target.tagName === "A") {
event.preventDefault();
const [startRow, startColumn, endRow, endColumn] =
event.target.dataset.range.split(",").map(n => parseInt(n));
codeEditor.focus();
codeEditor.setSelection(
{ line: startRow, ch: startColumn },
{ line: endRow, ch: endColumn },
);
}
}
function handleLoggingChange() {
if (loggingCheckbox.checked) {
parser.setLogger((message, lexing) => {
if (lexing) {
console.log(" ", message);
} else {
console.log(message);
}
});
} else {
parser.setLogger(null);
}
}
function handleQueryEnableChange() {
if (queryCheckbox.checked) {
queryContainer.style.visibility = "";
queryContainer.style.position = "";
} else {
queryContainer.style.visibility = "hidden";
queryContainer.style.position = "absolute";
}
handleQueryChange();
}
function treeEditForEditorChange(change) {
const oldLineCount = change.removed.length;
const newLineCount = change.text.length;
const lastLineLength = change.text[newLineCount - 1].length;
const startPosition = { row: change.from.line, column: change.from.ch };
const oldEndPosition = { row: change.to.line, column: change.to.ch };
const newEndPosition = {
row: startPosition.row + newLineCount - 1,
column:
newLineCount === 1
? startPosition.column + lastLineLength
: lastLineLength,
};
const startIndex = codeEditor.indexFromPos(change.from);
let newEndIndex = startIndex + newLineCount - 1;
let oldEndIndex = startIndex + oldLineCount - 1;
for (let i = 0; i < newLineCount; i++) newEndIndex += change.text[i].length;
for (let i = 0; i < oldLineCount; i++)
oldEndIndex += change.removed[i].length;
return {
startIndex,
oldEndIndex,
newEndIndex,
startPosition,
oldEndPosition,
newEndPosition,
};
}
function colorForCaptureName(capture) {
const id = query.captureNames.indexOf(capture);
return COLORS_BY_INDEX[id % COLORS_BY_INDEX.length];
}
function storageGetItem(lookupKey) {
try {
return localStorage.getItem(lookupKey);
} catch {
return null;
}
}
function storageSetItem(lookupKey, value) {
try {
return localStorage.setIem(lookupKey, value);
} catch {}
}
function loadState() {
const language = storageGetItem("language");
const sourceCode = storageGetItem("sourceCode");
const query = storageGetItem("query");
const queryEnabled = storageGetItem("queryEnabled");
if (language != null && sourceCode != null && query != null) {
queryInput.value = query;
codeInput.value = sourceCode;
queryCheckbox.checked = queryEnabled === "true";
}
}
function saveState() {
storageSetItem("sourceCode", codeEditor.getValue());
saveQueryState();
}
function saveQueryState() {
storageSetItem("queryEnabled", queryCheckbox.checked);
storageSetItem("query", queryEditor.getValue());
}
function debounce(func, wait, immediate) {
var timeout;
return function () {
var context = this,
args = arguments;
var later = function () {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
})();

File diff suppressed because one or more lines are too long

@ -1,3 +0,0 @@
CREATE FUNCTION add(integer, integer) RETURNS integer
AS 'select $1 + $2;'
LANGUAGE SQL;

@ -1,9 +0,0 @@
-- Example select query
SELECT foo, bar, t.col1 AS baz
FROM table1, table2 AS t
WHERE foo > t.col1
GROUP BY lower(foo);
-- Example nested select query
SELECT t.a, (SELECT 1) AS baz, (SELECT 2)
FROM table1, (SELECT a FROM foo WHERE b > 100) AS t;

@ -1,4 +0,0 @@
SELECT 1 + 2, NULL, col1::INT, a <> b, TRUE, false WHERE a = b;
CREATE TABLE foo(a TEXT DEFAULT 'foo');
CREATE TYPE foo AS (a TEXT, b TEXT);
CREATE DOMAIN foo AS TEXT;

File diff suppressed because it is too large Load Diff

@ -1,69 +0,0 @@
{
"name": "tree-sitter-sql",
"version": "0.1.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "tree-sitter-sql",
"version": "0.1.0",
"license": "MIT",
"dependencies": {
"nan": "^2.14.2"
},
"devDependencies": {
"prettier": "^2.4.1",
"tree-sitter-cli": "^0.20.6"
}
},
"node_modules/nan": {
"version": "2.16.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz",
"integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA=="
},
"node_modules/prettier": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz",
"integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==",
"dev": true,
"bin": {
"prettier": "bin-prettier.js"
},
"engines": {
"node": ">=10.13.0"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/tree-sitter-cli": {
"version": "0.20.6",
"resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.20.6.tgz",
"integrity": "sha512-tjbAeuGSMhco/EnsThjWkQbDIYMDmdkWsTPsa/NJAW7bjaki9P7oM9TkLxfdlnm4LXd1wR5wVSM2/RTLtZbm6A==",
"dev": true,
"hasInstallScript": true,
"bin": {
"tree-sitter": "cli.js"
}
}
},
"dependencies": {
"nan": {
"version": "2.16.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz",
"integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA=="
},
"prettier": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz",
"integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==",
"dev": true
},
"tree-sitter-cli": {
"version": "0.20.6",
"resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.20.6.tgz",
"integrity": "sha512-tjbAeuGSMhco/EnsThjWkQbDIYMDmdkWsTPsa/NJAW7bjaki9P7oM9TkLxfdlnm4LXd1wR5wVSM2/RTLtZbm6A==",
"dev": true
}
}
}

@ -1,41 +0,0 @@
{
"name": "tree-sitter-sql",
"version": "0.1.0",
"description": "SQL grammar fom tree-sitter",
"main": "bindings/node",
"scripts": {
"test": "tree-sitter generate && tree-sitter test",
"acceptance": "tree-sitter generate && tree-sitter parse --quiet --stat examples/real_world_stuff/*/*.sql",
"gen": "tree-sitter generate",
"hl": "tree-sitter highlight",
"parse": "tree-sitter parse",
"prettier": "prettier --write .",
"build-wasm": "tree-sitter build-wasm",
"update-playground": "rm -f tree-sitter-sql.wasm && npm run gen && tree-sitter build-wasm",
"playground": "npm run update-playground && tree-sitter playground",
"extract-error": "node ./scripts/extract_error.js"
},
"keywords": [
"parser",
"lexer",
"sql"
],
"repository": "https://github.com/m-novikov/tree-sitter-sql",
"author": "Maksim Novikov <mnovikov.work@gmail.com>",
"license": "MIT",
"dependencies": {
"nan": "^2.14.2"
},
"devDependencies": {
"prettier": "^2.4.1",
"tree-sitter-cli": "^0.20.6"
},
"tree-sitter": [
{
"scope": "source.sql",
"file-types": [
"sql"
]
}
]
}

@ -1,114 +0,0 @@
(string) @string
(number) @number
(comment) @comment
(function_call
function: (identifier) @function)
[
(NULL)
(TRUE)
(FALSE)
] @constant.builtin
([
(type_cast
(type (identifier) @type.builtin))
(create_function_statement
(type (identifier) @type.builtin))
(create_function_statement
(create_function_parameters
(create_function_parameter (type (identifier) @type.builtin))))
(create_type_statement
(type_spec_composite (type (identifier) @type.builtin)))
(create_table_statement
(table_parameters
(table_column (type (identifier) @type.builtin))))
]
(#match?
@type.builtin
"^(bigint|BIGINT|int8|INT8|bigserial|BIGSERIAL|serial8|SERIAL8|bit|BIT|varbit|VARBIT|boolean|BOOLEAN|bool|BOOL|box|BOX|bytea|BYTEA|character|CHARACTER|char|CHAR|varchar|VARCHAR|cidr|CIDR|circle|CIRCLE|date|DATE|float8|FLOAT8|inet|INET|integer|INTEGER|int|INT|int4|INT4|interval|INTERVAL|json|JSON|jsonb|JSONB|line|LINE|lseg|LSEG|macaddr|MACADDR|money|MONEY|numeric|NUMERIC|decimal|DECIMAL|path|PATH|pg_lsn|PG_LSN|point|POINT|polygon|POLYGON|real|REAL|float4|FLOAT4|smallint|SMALLINT|int2|INT2|smallserial|SMALLSERIAL|serial2|SERIAL2|serial|SERIAL|serial4|SERIAL4|text|TEXT|time|TIME|time|TIME|timestamp|TIMESTAMP|tsquery|TSQUERY|tsvector|TSVECTOR|txid_snapshot|TXID_SNAPSHOT|enum|ENUM|range|RANGE)$"))
(identifier) @variable
[
"::"
"<"
"<="
"<>"
"="
">"
">="
] @operator
[
"("
")"
"["
"]"
] @punctuation.bracket
[
";"
"."
] @punctuation.delimiter
[
(type)
(array_type)
] @type
[
(primary_key_constraint)
(unique_constraint)
(null_constraint)
] @keyword
[
"AND"
"AS"
"AUTO_INCREMENT"
"CREATE"
"CREATE_DOMAIN"
"CREATE_OR_REPLACE_FUNCTION"
"CREATE_SCHEMA"
"TABLE"
"TEMPORARY"
"CREATE_TYPE"
"DATABASE"
"FROM"
"GRANT"
"GROUP_BY"
"IF_NOT_EXISTS"
"INDEX"
"INNER"
"INSERT"
"INTO"
"IN"
"JOIN"
"LANGUAGE"
"LEFT"
"LOCAL"
"NOT"
"ON"
"OR"
"ORDER_BY"
"OUTER"
"PRIMARY_KEY"
"PUBLIC"
"RETURNS"
"SCHEMA"
"SELECT"
"SESSION"
"SET"
"TABLE"
"TIME_ZONE"
"TO"
"UNIQUE"
"UPDATE"
"USAGE"
"VALUES"
"WHERE"
"WITH"
"WITHOUT"
] @keyword

@ -1,42 +0,0 @@
const { spawn } = require("child_process");
const args = process.argv.slice(2);
const filename = args[0];
const parser = spawn("tree-sitter", ["parse", filename]);
const fs = require("fs");
let output = "";
parser.stdout.on("data", data => {
output = output + data;
});
parser.on("close", code => {
console.log("Parse exited code: ", code);
if (code == 0) return;
const arr = output.split("\n");
const test = "(ERROR [32, 29] - [32, 63])";
const error = output.match(
/\(ERROR \[(?<start>\d+, \d+)\] - \[(?<end>\d+, \d+)\]\)/,
);
const { start, end } = error.groups;
const [startRow, startCol] = start.split(", ").map(val => parseInt(val, 10));
const [endRow, endCol] = end.split(", ").map(val => parseInt(val, 10));
fs.readFile(filename, "utf8", (err, data) => {
if (err) {
console.error(err);
return;
}
const offendingLines = data.split("\n").slice(startRow, endRow + 1);
console.log("Offending lines:");
for (let line of offendingLines) {
console.log(line);
let hlLine = "";
// TODO: Fix multiline presenation
for (let i = 0; i < line.length; i++) {
hlLine += i < startCol ? " " : "^";
}
console.log(hlLine);
}
});
});

File diff suppressed because it is too large Load Diff

@ -1,560 +0,0 @@
diff a/src/grammar.json b/src/grammar.json (rejected hunks)
@@ -20,7 +20,19 @@
},
{
"type": "SYMBOL",
- "name": "dml_statement"
+ "name": "select_statement"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "update_statement"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "insert_statement"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "delete_statement"
},
{
"type": "SYMBOL",
@@ -90,62 +102,29 @@
}
]
},
- "dml_statement": {
+ "_ctes": {
"type": "SEQ",
"members": [
+ {
+ "type": "ALIAS",
+ "content": {
+ "type": "PATTERN",
+ "value": "[wW][iI][tT][hH]"
+ },
+ "named": false,
+ "value": "WITH"
+ },
{
"type": "CHOICE",
"members": [
{
- "type": "SEQ",
- "members": [
- {
- "type": "ALIAS",
- "content": {
- "type": "PATTERN",
- "value": "[wW][iI][tT][hH]"
- },
- "named": false,
- "value": "WITH"
- },
- {
- "type": "CHOICE",
- "members": [
- {
- "type": "ALIAS",
- "content": {
- "type": "PATTERN",
- "value": "[rR][eE][cC][uU][rR][sS][iI][vV][eE]"
- },
- "named": false,
- "value": "RECURSIVE"
- },
- {
- "type": "BLANK"
- }
- ]
- },
- {
- "type": "SYMBOL",
- "name": "cte"
- },
- {
- "type": "REPEAT",
- "content": {
- "type": "SEQ",
- "members": [
- {
- "type": "STRING",
- "value": ","
- },
- {
- "type": "SYMBOL",
- "name": "cte"
- }
- ]
- }
- }
- ]
+ "type": "ALIAS",
+ "content": {
+ "type": "PATTERN",
+ "value": "[rR][eE][cC][uU][rR][sS][iI][vV][eE]"
+ },
+ "named": false,
+ "value": "RECURSIVE"
},
{
"type": "BLANK"
@@ -153,23 +132,27 @@
]
},
{
- "type": "CHOICE",
+ "type": "SEQ",
"members": [
{
"type": "SYMBOL",
- "name": "select_statement"
- },
- {
- "type": "SYMBOL",
- "name": "delete_statement"
- },
- {
- "type": "SYMBOL",
- "name": "insert_statement"
+ "name": "cte"
},
{
- "type": "SYMBOL",
- "name": "update_statement"
+ "type": "REPEAT",
+ "content": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": ","
+ },
+ {
+ "type": "SYMBOL",
+ "name": "cte"
+ }
+ ]
+ }
}
]
}
@@ -2258,10 +2325,6 @@
{
"type": "SYMBOL",
"name": "auto_increment_constraint"
- },
- {
- "type": "SYMBOL",
- "name": "time_zone_constraint"
}
]
}
@@ -3732,7 +3772,7 @@
]
}
},
- "update_statement": {
+ "_update_statement": {
"type": "SEQ",
"members": [
{
@@ -3925,7 +3965,7 @@
}
]
},
- "delete_statement": {
+ "_delete_statement": {
"type": "SEQ",
"members": [
{
@@ -4662,8 +4735,8 @@
]
},
"at_time_zone_expression": {
- "type": "PREC_RIGHT",
- "value": 0,
+ "type": "PREC_LEFT",
+ "value": 8,
"content": {
"type": "SEQ",
"members": [
@@ -4823,7 +4896,7 @@
},
"_identifier": {
"type": "PREC_LEFT",
- "value": 2,
+ "value": 8,
"content": {
"type": "CHOICE",
"members": [
@@ -4842,40 +4915,6 @@
]
}
},
- "type": {
- "type": "SEQ",
- "members": [
- {
- "type": "SYMBOL",
- "name": "_identifier"
- },
- {
- "type": "CHOICE",
- "members": [
- {
- "type": "SEQ",
- "members": [
- {
- "type": "STRING",
- "value": "("
- },
- {
- "type": "SYMBOL",
- "name": "number"
- },
- {
- "type": "STRING",
- "value": ")"
- }
- ]
- },
- {
- "type": "BLANK"
- }
- ]
- }
- ]
- },
"string": {
"type": "CHOICE",
"members": [
@@ -5002,98 +5041,248 @@
}
]
},
- "array_type": {
- "type": "SEQ",
- "members": [
- {
- "type": "SYMBOL",
- "name": "_type"
- },
- {
- "type": "STRING",
- "value": "["
- },
- {
- "type": "STRING",
- "value": "]"
- }
- ]
- },
- "_type": {
- "type": "CHOICE",
- "members": [
- {
- "type": "SYMBOL",
- "name": "type"
- },
- {
- "type": "SYMBOL",
- "name": "array_type"
- }
- ]
- },
- "type_cast": {
- "type": "SEQ",
- "members": [
- {
- "type": "CHOICE",
- "members": [
- {
- "type": "SYMBOL",
- "name": "_parenthesized_expression"
- },
- {
- "type": "SYMBOL",
- "name": "string"
- },
- {
- "type": "SYMBOL",
- "name": "_identifier"
- },
- {
- "type": "SYMBOL",
- "name": "function_call"
- }
- ]
- },
- {
- "type": "STRING",
- "value": "::"
- },
- {
- "type": "FIELD",
- "name": "type",
- "content": {
- "type": "SYMBOL",
- "name": "_type"
- }
- }
- ]
- },
- "comment": {
- "type": "TOKEN",
+ "type": {
+ "type": "PREC_RIGHT",
+ "value": 0,
"content": {
- "type": "CHOICE",
+ "type": "SEQ",
"members": [
{
- "type": "SEQ",
+ "type": "SYMBOL",
+ "name": "_identifier"
+ },
+ {
+ "type": "CHOICE",
"members": [
{
- "type": "STRING",
- "value": "--"
+ "type": "ALIAS",
+ "content": {
+ "type": "PATTERN",
+ "value": "[vV][aA][rR][yY][iI][nN][gG]"
+ },
+ "named": false,
+ "value": "VARYING"
},
{
- "type": "PATTERN",
- "value": ".*"
+ "type": "BLANK"
}
]
},
{
- "type": "SEQ",
+ "type": "CHOICE",
"members": [
{
- "type": "STRING",
- "value": "/*"
+ "type": "ALIAS",
+ "content": {
+ "type": "PATTERN",
+ "value": "[pP][rR][eE][cC][iI][sS][iI][oO][nN]"
+ },
+ "named": false,
+ "value": "PRECISION"
+ },
+ {
+ "type": "BLANK"
+ }
+ ]
+ },
+ {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "("
+ },
+ {
+ "type": "SYMBOL",
+ "name": "number"
+ },
+ {
+ "type": "STRING",
+ "value": ")"
+ }
+ ]
+ },
+ {
+ "type": "BLANK"
+ }
+ ]
+ },
+ {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "ALIAS",
+ "content": {
+ "type": "PATTERN",
+ "value": "[wW][iI][tT][hH]"
+ },
+ "named": false,
+ "value": "WITH"
+ },
+ {
+ "type": "ALIAS",
+ "content": {
+ "type": "PATTERN",
+ "value": "[wW][iI][tT][hH][oO][uU][tT]"
+ },
+ "named": false,
+ "value": "WITHOUT"
+ }
+ ]
+ },
+ {
+ "type": "ALIAS",
+ "content": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "PATTERN",
+ "value": "[tT][iI][mM][eE]"
+ },
+ {
+ "type": "PATTERN",
+ "value": "[zZ][oO][nN][eE]"
+ }
+ ]
+ },
+ "named": false,
+ "value": "TIME_ZONE"
+ }
+ ]
+ },
+ {
+ "type": "BLANK"
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "array_type": {
+ "type": "PREC_RIGHT",
+ "value": 0,
+ "content": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "_type"
+ },
+ {
+ "type": "REPEAT1",
+ "content": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "["
+ },
+ {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "number"
+ },
+ {
+ "type": "BLANK"
+ }
+ ]
+ },
+ {
+ "type": "STRING",
+ "value": "]"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ "_type": {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "type"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "array_type"
+ }
+ ]
+ },
+ "type_cast": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "_parenthesized_expression"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "string"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "_identifier"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "function_call"
+ }
+ ]
+ },
+ {
+ "type": "STRING",
+ "value": "::"
+ },
+ {
+ "type": "FIELD",
+ "name": "type",
+ "content": {
+ "type": "SYMBOL",
+ "name": "_type"
+ }
+ }
+ ]
+ },
+ "comment": {
+ "type": "TOKEN",
+ "content": {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "--"
+ },
+ {
+ "type": "PATTERN",
+ "value": ".*"
+ }
+ ]
+ },
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "/*"
},
{
"type": "PATTERN",

File diff suppressed because it is too large Load Diff

@ -1,819 +0,0 @@
diff a/src/node-types.json b/src/node-types.json (rejected hunks)
@@ -701,17 +721,342 @@
{
"type": "type_cast",
"named": true
+ },
+ {
+ "type": "unary_expression",
+ "named": true
}
]
}
},
{
- "type": "auto_increment_constraint",
+ "type": "auto_increment_constraint",
+ "named": true,
+ "fields": {}
+ },
+ {
+ "type": "binary_expression",
+ "named": true,
+ "fields": {
+ "left": {
+ "multiple": true,
+ "required": true,
+ "types": [
+ {
+ "type": "\"",
+ "named": false
+ },
+ {
+ "type": "(",
+ "named": false
+ },
+ {
+ "type": ")",
+ "named": false
+ },
+ {
+ "type": "FALSE",
+ "named": true
+ },
+ {
+ "type": "NULL",
+ "named": true
+ },
+ {
+ "type": "TRUE",
+ "named": true
+ },
+ {
+ "type": "`",
+ "named": false
+ },
+ {
+ "type": "argument_reference",
+ "named": true
+ },
+ {
+ "type": "array_element_access",
+ "named": true
+ },
+ {
+ "type": "asterisk_expression",
+ "named": true
+ },
+ {
+ "type": "at_time_zone_expression",
+ "named": true
+ },
+ {
+ "type": "binary_expression",
+ "named": true
+ },
+ {
+ "type": "boolean_expression",
+ "named": true
+ },
+ {
+ "type": "conditional_expression",
+ "named": true
+ },
+ {
+ "type": "dotted_name",
+ "named": true
+ },
+ {
+ "type": "function_call",
+ "named": true
+ },
+ {
+ "type": "identifier",
+ "named": true
+ },
+ {
+ "type": "in_expression",
+ "named": true
+ },
+ {
+ "type": "interval_expression",
+ "named": true
+ },
+ {
+ "type": "is_expression",
+ "named": true
+ },
+ {
+ "type": "json_access",
+ "named": true
+ },
+ {
+ "type": "number",
+ "named": true
+ },
+ {
+ "type": "select_subexpression",
+ "named": true
+ },
+ {
+ "type": "string",
+ "named": true
+ },
+ {
+ "type": "type_cast",
+ "named": true
+ },
+ {
+ "type": "unary_expression",
+ "named": true
+ }
+ ]
+ },
+ "operator": {
+ "multiple": false,
+ "required": true,
+ "types": [
+ {
+ "type": "!~",
+ "named": false
+ },
+ {
+ "type": "!~*",
+ "named": false
+ },
+ {
+ "type": "#",
+ "named": false
+ },
+ {
+ "type": "%",
+ "named": false
+ },
+ {
+ "type": "&",
+ "named": false
+ },
+ {
+ "type": "*",
+ "named": false
+ },
+ {
+ "type": "+",
+ "named": false
+ },
+ {
+ "type": "-",
+ "named": false
+ },
+ {
+ "type": "/",
+ "named": false
+ },
+ {
+ "type": "<",
+ "named": false
+ },
+ {
+ "type": "<<",
+ "named": false
+ },
+ {
+ "type": "<=",
+ "named": false
+ },
+ {
+ "type": "<>",
+ "named": false
+ },
+ {
+ "type": "=",
+ "named": false
+ },
+ {
+ "type": ">",
+ "named": false
+ },
+ {
+ "type": ">=",
+ "named": false
+ },
+ {
+ "type": ">>",
+ "named": false
+ },
+ {
+ "type": "^",
+ "named": false
+ },
+ {
+ "type": "|",
+ "named": false
+ },
+ {
+ "type": "~",
+ "named": false
+ },
+ {
+ "type": "~*",
+ "named": false
+ }
+ ]
+ },
+ "right": {
+ "multiple": true,
+ "required": true,
+ "types": [
+ {
+ "type": "\"",
+ "named": false
+ },
+ {
+ "type": "(",
+ "named": false
+ },
+ {
+ "type": ")",
+ "named": false
+ },
+ {
+ "type": "FALSE",
+ "named": true
+ },
+ {
+ "type": "NULL",
+ "named": true
+ },
+ {
+ "type": "TRUE",
+ "named": true
+ },
+ {
+ "type": "`",
+ "named": false
+ },
+ {
+ "type": "argument_reference",
+ "named": true
+ },
+ {
+ "type": "array_element_access",
+ "named": true
+ },
+ {
+ "type": "asterisk_expression",
+ "named": true
+ },
+ {
+ "type": "at_time_zone_expression",
+ "named": true
+ },
+ {
+ "type": "binary_expression",
+ "named": true
+ },
+ {
+ "type": "boolean_expression",
+ "named": true
+ },
+ {
+ "type": "conditional_expression",
+ "named": true
+ },
+ {
+ "type": "dotted_name",
+ "named": true
+ },
+ {
+ "type": "function_call",
+ "named": true
+ },
+ {
+ "type": "identifier",
+ "named": true
+ },
+ {
+ "type": "in_expression",
+ "named": true
+ },
+ {
+ "type": "interval_expression",
+ "named": true
+ },
+ {
+ "type": "is_expression",
+ "named": true
+ },
+ {
+ "type": "json_access",
+ "named": true
+ },
+ {
+ "type": "number",
+ "named": true
+ },
+ {
+ "type": "select_subexpression",
+ "named": true
+ },
+ {
+ "type": "string",
+ "named": true
+ },
+ {
+ "type": "type_cast",
+ "named": true
+ },
+ {
+ "type": "unary_expression",
+ "named": true
+ }
+ ]
+ }
+ }
+ },
+ {
+ "type": "binary_operator",
"named": true,
"fields": {}
},
{
- "type": "binary_expression",
+ "type": "boolean_expression",
"named": true,
"fields": {},
"children": {
@@ -801,105 +1146,9 @@
{
"type": "type_cast",
"named": true
- }
- ]
- }
- },
- {
- "type": "binary_operator",
- "named": true,
- "fields": {}
- },
- {
- "type": "boolean_expression",
- "named": true,
- "fields": {},
- "children": {
- "multiple": true,
- "required": false,
- "types": [
- {
- "type": "FALSE",
- "named": true
- },
- {
- "type": "NULL",
- "named": true
- },
- {
- "type": "TRUE",
- "named": true
- },
- {
- "type": "argument_reference",
- "named": true
- },
- {
- "type": "array_element_access",
- "named": true
- },
- {
- "type": "asterisk_expression",
- "named": true
- },
- {
- "type": "at_time_zone_expression",
- "named": true
- },
- {
- "type": "binary_expression",
- "named": true
- },
- {
- "type": "boolean_expression",
- "named": true
- },
- {
- "type": "comparison_operator",
- "named": true
- },
- {
- "type": "dotted_name",
- "named": true
- },
- {
- "type": "function_call",
- "named": true
- },
- {
- "type": "identifier",
- "named": true
- },
- {
- "type": "in_expression",
- "named": true
},
{
- "type": "interval_expression",
- "named": true
- },
- {
- "type": "is_expression",
- "named": true
- },
- {
- "type": "json_access",
- "named": true
- },
- {
- "type": "number",
- "named": true
- },
- {
- "type": "select_subexpression",
- "named": true
- },
- {
- "type": "string",
- "named": true
- },
- {
- "type": "type_cast",
+ "type": "unary_expression",
"named": true
}
]
@@ -1186,45 +1443,18 @@
{
"type": "type_cast",
"named": true
+ },
+ {
+ "type": "unary_expression",
+ "named": true
}
]
}
},
{
- "type": "comparison_operator",
+ "type": "conditional_expression",
"named": true,
- "fields": {
- "operator": {
- "multiple": false,
- "required": true,
- "types": [
- {
- "type": "<",
- "named": false
- },
- {
- "type": "<=",
- "named": false
- },
- {
- "type": "<>",
- "named": false
- },
- {
- "type": "=",
- "named": false
- },
- {
- "type": ">",
- "named": false
- },
- {
- "type": ">=",
- "named": false
- }
- ]
- }
- },
+ "fields": {},
"children": {
"multiple": true,
"required": false,
@@ -1927,36 +2185,9 @@
{
"type": "type_cast",
"named": true
- }
- ]
- }
- },
- {
- "type": "dml_statement",
- "named": true,
- "fields": {},
- "children": {
- "multiple": true,
- "required": true,
- "types": [
- {
- "type": "cte",
- "named": true
- },
- {
- "type": "delete_statement",
- "named": true
- },
- {
- "type": "insert_statement",
- "named": true
- },
- {
- "type": "select_statement",
- "named": true
},
{
- "type": "update_statement",
+ "type": "unary_expression",
"named": true
}
]
@@ -3577,6 +3856,10 @@
"multiple": true,
"required": true,
"types": [
+ {
+ "type": "cte",
+ "named": true
+ },
{
"type": "from_clause",
"named": true
@@ -3835,7 +4122,7 @@
"named": true
},
{
- "type": "dml_statement",
+ "type": "delete_statement",
"named": true
},
{
@@ -3846,13 +4133,25 @@
"type": "grant_statement",
"named": true
},
+ {
+ "type": "insert_statement",
+ "named": true
+ },
{
"type": "pg_command",
"named": true
},
+ {
+ "type": "select_statement",
+ "named": true
+ },
{
"type": "set_statement",
"named": true
+ },
+ {
+ "type": "update_statement",
+ "named": true
}
]
}
@@ -4266,10 +4560,168 @@
{
"type": "type_cast",
"named": true
+ },
+ {
+ "type": "unary_expression",
+ "named": true
}
]
}
},
+ {
+ "type": "unary_expression",
+ "named": true,
+ "fields": {
+ "operand": {
+ "multiple": true,
+ "required": true,
+ "types": [
+ {
+ "type": "\"",
+ "named": false
+ },
+ {
+ "type": "(",
+ "named": false
+ },
+ {
+ "type": ")",
+ "named": false
+ },
+ {
+ "type": "FALSE",
+ "named": true
+ },
+ {
+ "type": "NULL",
+ "named": true
+ },
+ {
+ "type": "TRUE",
+ "named": true
+ },
+ {
+ "type": "`",
+ "named": false
+ },
+ {
+ "type": "argument_reference",
+ "named": true
+ },
+ {
+ "type": "array_element_access",
+ "named": true
+ },
+ {
+ "type": "asterisk_expression",
+ "named": true
+ },
+ {
+ "type": "at_time_zone_expression",
+ "named": true
+ },
+ {
+ "type": "binary_expression",
+ "named": true
+ },
+ {
+ "type": "boolean_expression",
+ "named": true
+ },
+ {
+ "type": "conditional_expression",
+ "named": true
+ },
+ {
+ "type": "dotted_name",
+ "named": true
+ },
+ {
+ "type": "function_call",
+ "named": true
+ },
+ {
+ "type": "identifier",
+ "named": true
+ },
+ {
+ "type": "in_expression",
+ "named": true
+ },
+ {
+ "type": "interval_expression",
+ "named": true
+ },
+ {
+ "type": "is_expression",
+ "named": true
+ },
+ {
+ "type": "json_access",
+ "named": true
+ },
+ {
+ "type": "number",
+ "named": true
+ },
+ {
+ "type": "select_subexpression",
+ "named": true
+ },
+ {
+ "type": "string",
+ "named": true
+ },
+ {
+ "type": "type_cast",
+ "named": true
+ },
+ {
+ "type": "unary_expression",
+ "named": true
+ }
+ ]
+ },
+ "operator": {
+ "multiple": false,
+ "required": true,
+ "types": [
+ {
+ "type": "!",
+ "named": false
+ },
+ {
+ "type": "!!",
+ "named": false
+ },
+ {
+ "type": "+",
+ "named": false
+ },
+ {
+ "type": "-",
+ "named": false
+ },
+ {
+ "type": "@",
+ "named": false
+ },
+ {
+ "type": "|/",
+ "named": false
+ },
+ {
+ "type": "||/",
+ "named": false
+ },
+ {
+ "type": "~",
+ "named": false
+ }
+ ]
+ }
+ }
+ },
{
"type": "unique",
"named": true,
@@ -4302,6 +4754,10 @@
"multiple": true,
"required": true,
"types": [
+ {
+ "type": "cte",
+ "named": true
+ },
{
"type": "from_clause",
"named": true
@@ -4538,14 +4998,38 @@
{
"type": "type_cast",
"named": true
+ },
+ {
+ "type": "unary_expression",
+ "named": true
}
]
}
},
+ {
+ "type": "!",
+ "named": false
+ },
+ {
+ "type": "!!",
+ "named": false
+ },
+ {
+ "type": "!~",
+ "named": false
+ },
+ {
+ "type": "!~*",
+ "named": false
+ },
{
"type": "\"",
"named": false
},
+ {
+ "type": "#",
+ "named": false
+ },
{
"type": "#>",
"named": false
@@ -4590,6 +5082,10 @@
"type": ",",
"named": false
},
+ {
+ "type": "-",
+ "named": false
+ },
{
"type": "->",
"named": false

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,159 +0,0 @@
#include <tree_sitter/parser.h>
#include <string>
#include <cwctype>
namespace {
using std::string;
enum TokenType {
DOLLAR_QUOTED_STRING_TAG,
DOLLAR_QUOTED_STRING_CONTENT,
DOLLAR_QUOTED_STRING_END_TAG,
};
struct Scanner {
string dollar_quoted_string_tag;
string current_leading_word;
bool dollar_quoted_string_started;
void skip(TSLexer *lexer) {
lexer->advance(lexer, true);
}
void advance(TSLexer *lexer) {
lexer->advance(lexer, false);
}
unsigned serialize(char *buffer) {
if (dollar_quoted_string_tag.length() + 1>= TREE_SITTER_SERIALIZATION_BUFFER_SIZE) return 0;
buffer[0] = dollar_quoted_string_started;
dollar_quoted_string_tag.copy(&buffer[1], dollar_quoted_string_tag.length());
return dollar_quoted_string_tag.length() + 1;
}
void deserialize(const char *buffer, unsigned length) {
if (length == 0) {
dollar_quoted_string_started = false;
dollar_quoted_string_tag.clear();
} else {
dollar_quoted_string_started = buffer[0];
dollar_quoted_string_tag.assign(&buffer[1], &buffer[length]);
}
}
bool scan_dollar_quoted_string_content(TSLexer *lexer) {
unsigned long int pos = 0;
lexer->result_symbol = DOLLAR_QUOTED_STRING_CONTENT;
lexer->mark_end(lexer);
for (;;) {
if (lexer->lookahead == '\0') {
return false;
} else if (lexer->lookahead == dollar_quoted_string_tag[pos]) {
if (pos == dollar_quoted_string_tag.length() - 1) {
return true;
} else if (pos == 0) {
lexer->result_symbol = DOLLAR_QUOTED_STRING_CONTENT;
lexer->mark_end(lexer);
}
pos++;
advance(lexer);
} else if (pos != 0) {
pos = 0;
} else {
advance(lexer);
}
}
}
bool scan_dollar_quoted_string_tag(TSLexer *lexer) {
while (iswspace(lexer->lookahead)) skip(lexer);
dollar_quoted_string_tag.clear();
if (lexer->lookahead == '$') {
dollar_quoted_string_tag += lexer->lookahead;
advance(lexer);
} else {
return false;
}
while (iswalpha(lexer->lookahead)) {
dollar_quoted_string_tag += lexer->lookahead;
advance(lexer);
}
if (lexer->lookahead == '$') {
dollar_quoted_string_tag += lexer->lookahead;
advance(lexer);
dollar_quoted_string_started = true;
return true;
}
return false;
}
bool scan_dollar_quoted_string_end_tag(TSLexer *lexer) {
current_leading_word.clear();
while (
lexer->lookahead != '\0' &&
current_leading_word.length() < dollar_quoted_string_tag.length()
) {
current_leading_word += lexer->lookahead;
advance(lexer);
}
return current_leading_word == dollar_quoted_string_tag;
}
bool scan(TSLexer *lexer, const bool *valid_symbols) {
if (valid_symbols[DOLLAR_QUOTED_STRING_TAG] && !dollar_quoted_string_started) {
return scan_dollar_quoted_string_tag(lexer);
}
if (valid_symbols[DOLLAR_QUOTED_STRING_CONTENT] && dollar_quoted_string_started) {
return scan_dollar_quoted_string_content(lexer);
}
if (valid_symbols[DOLLAR_QUOTED_STRING_END_TAG] && dollar_quoted_string_started) {
if (scan_dollar_quoted_string_end_tag(lexer)) {
dollar_quoted_string_started = false;
lexer->result_symbol = DOLLAR_QUOTED_STRING_END_TAG;
return true;
};
}
return false;
}
};
}
extern "C" {
void *tree_sitter_sql_external_scanner_create() {
return new Scanner();
}
bool tree_sitter_sql_external_scanner_scan(void *payload, TSLexer *lexer,
const bool *valid_symbols) {
Scanner *scanner = static_cast<Scanner *>(payload);
return scanner->scan(lexer, valid_symbols);
}
unsigned tree_sitter_sql_external_scanner_serialize(void *payload, char *state) {
Scanner *scanner = static_cast<Scanner *>(payload);
return scanner->serialize(state);
}
void tree_sitter_sql_external_scanner_deserialize(void *payload, const char *state, unsigned length) {
Scanner *scanner = static_cast<Scanner *>(payload);
scanner->deserialize(state, length);
}
void tree_sitter_sql_external_scanner_destroy(void *payload) {
Scanner *scanner = static_cast<Scanner *>(payload);
delete scanner;
}
}

@ -1,224 +0,0 @@
#ifndef TREE_SITTER_PARSER_H_
#define TREE_SITTER_PARSER_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#define ts_builtin_sym_error ((TSSymbol)-1)
#define ts_builtin_sym_end 0
#define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024
typedef uint16_t TSStateId;
#ifndef TREE_SITTER_API_H_
typedef uint16_t TSSymbol;
typedef uint16_t TSFieldId;
typedef struct TSLanguage TSLanguage;
#endif
typedef struct {
TSFieldId field_id;
uint8_t child_index;
bool inherited;
} TSFieldMapEntry;
typedef struct {
uint16_t index;
uint16_t length;
} TSFieldMapSlice;
typedef struct {
bool visible;
bool named;
bool supertype;
} TSSymbolMetadata;
typedef struct TSLexer TSLexer;
struct TSLexer {
int32_t lookahead;
TSSymbol result_symbol;
void (*advance)(TSLexer *, bool);
void (*mark_end)(TSLexer *);
uint32_t (*get_column)(TSLexer *);
bool (*is_at_included_range_start)(const TSLexer *);
bool (*eof)(const TSLexer *);
};
typedef enum {
TSParseActionTypeShift,
TSParseActionTypeReduce,
TSParseActionTypeAccept,
TSParseActionTypeRecover,
} TSParseActionType;
typedef union {
struct {
uint8_t type;
TSStateId state;
bool extra;
bool repetition;
} shift;
struct {
uint8_t type;
uint8_t child_count;
TSSymbol symbol;
int16_t dynamic_precedence;
uint16_t production_id;
} reduce;
uint8_t type;
} TSParseAction;
typedef struct {
uint16_t lex_state;
uint16_t external_lex_state;
} TSLexMode;
typedef union {
TSParseAction action;
struct {
uint8_t count;
bool reusable;
} entry;
} TSParseActionEntry;
struct TSLanguage {
uint32_t version;
uint32_t symbol_count;
uint32_t alias_count;
uint32_t token_count;
uint32_t external_token_count;
uint32_t state_count;
uint32_t large_state_count;
uint32_t production_id_count;
uint32_t field_count;
uint16_t max_alias_sequence_length;
const uint16_t *parse_table;
const uint16_t *small_parse_table;
const uint32_t *small_parse_table_map;
const TSParseActionEntry *parse_actions;
const char * const *symbol_names;
const char * const *field_names;
const TSFieldMapSlice *field_map_slices;
const TSFieldMapEntry *field_map_entries;
const TSSymbolMetadata *symbol_metadata;
const TSSymbol *public_symbol_map;
const uint16_t *alias_map;
const TSSymbol *alias_sequences;
const TSLexMode *lex_modes;
bool (*lex_fn)(TSLexer *, TSStateId);
bool (*keyword_lex_fn)(TSLexer *, TSStateId);
TSSymbol keyword_capture_token;
struct {
const bool *states;
const TSSymbol *symbol_map;
void *(*create)(void);
void (*destroy)(void *);
bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist);
unsigned (*serialize)(void *, char *);
void (*deserialize)(void *, const char *, unsigned);
} external_scanner;
const TSStateId *primary_state_ids;
};
/*
* Lexer Macros
*/
#define START_LEXER() \
bool result = false; \
bool skip = false; \
bool eof = false; \
int32_t lookahead; \
goto start; \
next_state: \
lexer->advance(lexer, skip); \
start: \
skip = false; \
lookahead = lexer->lookahead;
#define ADVANCE(state_value) \
{ \
state = state_value; \
goto next_state; \
}
#define SKIP(state_value) \
{ \
skip = true; \
state = state_value; \
goto next_state; \
}
#define ACCEPT_TOKEN(symbol_value) \
result = true; \
lexer->result_symbol = symbol_value; \
lexer->mark_end(lexer);
#define END_STATE() return result;
/*
* Parse Table Macros
*/
#define SMALL_STATE(id) id - LARGE_STATE_COUNT
#define STATE(id) id
#define ACTIONS(id) id
#define SHIFT(state_value) \
{{ \
.shift = { \
.type = TSParseActionTypeShift, \
.state = state_value \
} \
}}
#define SHIFT_REPEAT(state_value) \
{{ \
.shift = { \
.type = TSParseActionTypeShift, \
.state = state_value, \
.repetition = true \
} \
}}
#define SHIFT_EXTRA() \
{{ \
.shift = { \
.type = TSParseActionTypeShift, \
.extra = true \
} \
}}
#define REDUCE(symbol_val, child_count_val, ...) \
{{ \
.reduce = { \
.type = TSParseActionTypeReduce, \
.symbol = symbol_val, \
.child_count = child_count_val, \
__VA_ARGS__ \
}, \
}}
#define RECOVER() \
{{ \
.type = TSParseActionTypeRecover \
}}
#define ACCEPT_INPUT() \
{{ \
.type = TSParseActionTypeAccept \
}}
#ifdef __cplusplus
}
#endif
#endif // TREE_SITTER_PARSER_H_

File diff suppressed because it is too large Load Diff

@ -1,46 +0,0 @@
================================================================================
DELETE statement
================================================================================
DELETE FROM foo;
DELETE FROM foo WHERE name = 'bar';
--------------------------------------------------------------------------------
(source_file
(delete_statement
(from_clause
(identifier)))
(delete_statement
(from_clause
(identifier))
(where_clause
(binary_expression
(identifier)
(string
(content))))))
================================================================================
DELETE with CTE
================================================================================
WITH t AS (
SELECT * FROM foo
)
DELETE FROM bar;
--------------------------------------------------------------------------------
(source_file
(delete_statement
(with_clause
(cte
(identifier)
(select_statement
(select_clause
(select_clause_body
(asterisk_expression)))
(from_clause
(identifier)))))
(from_clause
(identifier))))

@ -1,320 +0,0 @@
================================================================================
INSERT statement
================================================================================
INSERT INTO table1 VALUES (1, 'test')
INSERT INTO table1 (col1) VALUES (1)
INSERT INTO table1 ("Foo 1") VALUES (1)
INSERT INTO table1 ("Foo 1", bar) VALUES (1, 2)
INSERT INTO table2 SELECT * FROM generate_series(1, 100, 1);
--------------------------------------------------------------------------------
(source_file
(insert_statement
(identifier)
(values_clause
(values_clause_item
(number)
(string
(content)))))
(insert_statement
(identifier)
(identifier)
(values_clause
(values_clause_item
(number))))
(insert_statement
(identifier)
(identifier)
(values_clause
(values_clause_item
(number))))
(insert_statement
(identifier)
(identifier)
(identifier)
(values_clause
(values_clause_item
(number)
(number))))
(insert_statement
(identifier)
(select_statement
(select_clause
(select_clause_body
(asterisk_expression)))
(from_clause
(function_call
(identifier)
(number)
(number)
(number))))))
================================================================================
INSERT statement values with multiple items
================================================================================
INSERT INTO table1 VALUES (1, 'a'), (2, 'b');
--------------------------------------------------------------------------------
(source_file
(insert_statement
(identifier)
(values_clause
(values_clause_item
(number)
(string
(content)))
(values_clause_item
(number)
(string
(content))))))
================================================================================
INSERT statement values with order
================================================================================
INSERT INTO table1(c1, c2) VALUES (1, 'a'), (2, 'b') ORDER BY c1, c2 DESC;
--------------------------------------------------------------------------------
(source_file
(insert_statement
(identifier)
(identifier)
(identifier)
(values_clause
(values_clause_item
(number)
(string
(content)))
(values_clause_item
(number)
(string
(content)))
(order_by_clause
(order_expression
(identifier))
(order_expression
(identifier))))))
================================================================================
INSERT statement values with limit
================================================================================
INSERT INTO table1 VALUES (1, 'a'), (2, 'b') LIMIT 1;
INSERT INTO table1 VALUES (1, 'a'), (2, 'b') LIMIT ALL;
INSERT INTO table1 VALUES (1, 'a'), (2, 'b') LIMIT 1, 1;
--------------------------------------------------------------------------------
(source_file
(insert_statement
(identifier)
(values_clause
(values_clause_item
(number)
(string
(content)))
(values_clause_item
(number)
(string
(content)))
(limit_clause
(number))))
(insert_statement
(identifier)
(values_clause
(values_clause_item
(number)
(string
(content)))
(values_clause_item
(number)
(string
(content)))
(limit_clause)))
(insert_statement
(identifier)
(values_clause
(values_clause_item
(number)
(string
(content)))
(values_clause_item
(number)
(string
(content)))
(limit_clause
(number)
(number)))))
================================================================================
INSERT statement values with offset
================================================================================
INSERT INTO table1 VALUES (1, 'a'), (2, 'b') OFFSET 1;
INSERT INTO table1 VALUES (1, 'a'), (2, 'b') OFFSET 1 ROW;
INSERT INTO table1 VALUES (1, 'a'), (2, 'b') OFFSET 1 ROWS;
--------------------------------------------------------------------------------
(source_file
(insert_statement
(identifier)
(values_clause
(values_clause_item
(number)
(string
(content)))
(values_clause_item
(number)
(string
(content)))
(offset_clause
(number))))
(insert_statement
(identifier)
(values_clause
(values_clause_item
(number)
(string
(content)))
(values_clause_item
(number)
(string
(content)))
(offset_clause
(number))))
(insert_statement
(identifier)
(values_clause
(values_clause_item
(number)
(string
(content)))
(values_clause_item
(number)
(string
(content)))
(offset_clause
(number)))))
================================================================================
INSERT statement values with fetch
================================================================================
INSERT INTO table1 VALUES (1, 'a'), (2, 'b') FETCH FIRST ROW ONLY;
INSERT INTO table1 VALUES (1, 'a'), (2, 'b') FETCH FIRST ROWS ONLY;
INSERT INTO table1 VALUES (1, 'a'), (2, 'b') FETCH NEXT ROW ONLY;
INSERT INTO table1 VALUES (1, 'a'), (2, 'b') FETCH NEXT ROWS ONLY;
INSERT INTO table1 VALUES (1, 'a'), (2, 'b') FETCH FIRST 1 ROW ONLY;
INSERT INTO table1 VALUES (1, 'a'), (2, 'b') FETCH FIRST 1 ROWS ONLY;
INSERT INTO table1 VALUES (1, 'a'), (2, 'b') FETCH NEXT 1 ROW ONLY;
INSERT INTO table1 VALUES (1, 'a'), (2, 'b') FETCH NEXT 1 ROWS ONLY;
--------------------------------------------------------------------------------
(source_file
(insert_statement
(identifier)
(values_clause
(values_clause_item
(number)
(string
(content)))
(values_clause_item
(number)
(string
(content)))
(fetch_clause)))
(insert_statement
(identifier)
(values_clause
(values_clause_item
(number)
(string
(content)))
(values_clause_item
(number)
(string
(content)))
(fetch_clause)))
(insert_statement
(identifier)
(values_clause
(values_clause_item
(number)
(string
(content)))
(values_clause_item
(number)
(string
(content)))
(fetch_clause)))
(insert_statement
(identifier)
(values_clause
(values_clause_item
(number)
(string
(content)))
(values_clause_item
(number)
(string
(content)))
(fetch_clause)))
(insert_statement
(identifier)
(values_clause
(values_clause_item
(number)
(string
(content)))
(values_clause_item
(number)
(string
(content)))
(fetch_clause
(number))))
(insert_statement
(identifier)
(values_clause
(values_clause_item
(number)
(string
(content)))
(values_clause_item
(number)
(string
(content)))
(fetch_clause
(number))))
(insert_statement
(identifier)
(values_clause
(values_clause_item
(number)
(string
(content)))
(values_clause_item
(number)
(string
(content)))
(fetch_clause
(number))))
(insert_statement
(identifier)
(values_clause
(values_clause_item
(number)
(string
(content)))
(values_clause_item
(number)
(string
(content)))
(fetch_clause
(number)))))

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,102 +0,0 @@
================================================================================
UPDATE statement
================================================================================
UPDATE table1 SET col1 = 3, col2 = 4
--------------------------------------------------------------------------------
(source_file
(update_statement
(identifier)
(set_clause
(set_clause_body
(assigment_expression
(identifier)
(number))
(assigment_expression
(identifier)
(number))))))
================================================================================
UPDATE statement with WHERE clause
================================================================================
UPDATE table1 SET col1 = 3, col2 = 4 WHERE col1 > col2
--------------------------------------------------------------------------------
(source_file
(update_statement
(identifier)
(set_clause
(set_clause_body
(assigment_expression
(identifier)
(number))
(assigment_expression
(identifier)
(number))))
(where_clause
(binary_expression
(identifier)
(identifier)))))
================================================================================
UPDATE statement with FROM clause
================================================================================
UPDATE foo SET col1 = 1 FROM bar WHERE foo.id = bar.foo_id;
--------------------------------------------------------------------------------
(source_file
(update_statement
(identifier)
(set_clause
(set_clause_body
(assigment_expression
(identifier)
(number))))
(from_clause
(identifier))
(where_clause
(binary_expression
(dotted_name
(identifier)
(identifier))
(dotted_name
(identifier)
(identifier))))))
================================================================================
UPDATE with CTE
================================================================================
WITH t AS (
SELECT * FROM foo
)
UPDATE bar SET col1 = 3, col2 = 4;
--------------------------------------------------------------------------------
(source_file
(update_statement
(with_clause
(cte
(identifier)
(select_statement
(select_clause
(select_clause_body
(asterisk_expression)))
(from_clause
(identifier)))))
(identifier)
(set_clause
(set_clause_body
(assigment_expression
(identifier)
(number))
(assigment_expression
(identifier)
(number))))))

@ -1,99 +0,0 @@
SELECT
a00 :: bigint,
-- ^ type.builtin
a01 :: int8,
-- ^ type.builtin
a02 :: bigserial,
-- ^ type.builtin
a03 :: serial8,
-- ^ type.builtin
a04 :: bit,
-- ^ type.builtin
a05 :: varbit,
-- ^ type.builtin
a06 :: boolean,
-- ^ type.builtin
a07 :: bool,
-- ^ type.builtin
a08 :: box,
-- ^ type.builtin
a09 :: bytea,
-- ^ type.builtin
a10 :: character,
-- ^ type.builtin
a11 :: char,
-- ^ type.builtin
a12 :: varchar,
-- ^ type.builtin
a13 :: cidr,
-- ^ type.builtin
a14 :: circle,
-- ^ type.builtin
a15 :: date,
-- ^ type.builtin
a16 :: float8,
-- ^ type.builtin
a17 :: inet,
-- ^ type.builtin
a18 :: integer,
-- ^ type.builtin
a19 :: int,
-- ^ type.builtin
a20 :: int4,
-- ^ type.builtin
a21 :: interval,
-- ^ type.builtin
a22 :: json,
-- ^ type.builtin
a23 :: jsonb,
-- ^ type.builtin
a24 :: line,
-- ^ type.builtin
a25 :: lseg,
-- ^ type.builtin
a26 :: macaddr,
-- ^ type.builtin
a27 :: money,
-- ^ type.builtin
a28 :: numeric,
-- ^ type.builtin
a29 :: decimal,
-- ^ type.builtin
a30 :: path,
-- ^ type.builtin
a31 :: pg_lsn,
-- ^ type.builtin
a32 :: point,
-- ^ type.builtin
a33 :: polygon,
-- ^ type.builtin
a34 :: real,
-- ^ type.builtin
a35 :: float4,
-- ^ type.builtin
a36 :: smallint,
-- ^ type.builtin
a37 :: int2,
-- ^ type.builtin
a38 :: smallserial,
-- ^ type.builtin
a39 :: serial2,
-- ^ type.builtin
a40 :: serial,
-- ^ type.builtin
a41 :: serial4,
-- ^ type.builtin
a42 :: text,
-- ^ type.builtin
a43 :: time,
-- ^ type.builtin
a44 :: time,
-- ^ type.builtin
a45 :: timestamp,
-- ^ type.builtin
a46 :: tsquery,
-- ^ type.builtin
a47 :: tsvector,
-- ^ type.builtin
a48 :: txid_snapshot,
-- ^ type.builtin

@ -1,23 +0,0 @@
CREATE FUNCTION add(integer, integer) RETURNS integer
-- <- keyword
-- ^ keyword
-- ^ type.builtin
-- ^ type.builtin
-- ^ keyword
-- ^ type.builtin
AS 'select $1 + $2;'
-- <- keyword
LANGUAGE SQL;
-- <- keyword
CREATE OR REPLACE FUNCTION add(integer, integer) RETURNS integer
-- <- keyword
-- ^ keyword
-- ^ keyword
-- ^ type.builtin
-- ^ keyword
-- ^ type.builtin
AS 'select $1 + $2;'
-- <- keyword
LANGUAGE SQL;
-- <- keyword

@ -1,7 +0,0 @@
INSERT INTO table1 VALUES (1, 'test')
-- <- keyword
-- ^ keyword
-- ^ variable
-- ^ keyword
-- ^ number
-- ^ string

@ -1,11 +0,0 @@
WHERE a > b OR b = a AND c > d;
-- <- keyword
-- ^ keyword
-- ^ keyword
WHERE NOT a AND b NOT IN c AND c IN d
-- <- keyword
-- ^ keyword
-- ^ keyword
-- ^ keyword
-- ^ keyword
-- ^ keyword

@ -1,3 +0,0 @@
SELECT foo.bar;
-- ^ punctuation.delimiter
-- ^ punctuation.delimiter

@ -1,69 +0,0 @@
SELECT a, b::INT;
-- <- keyword
-- ^ operator
-- ^ type.builtin
SELECT a, b :: INT;
-- ^ operator
-- ^ type.builtin
-- ^ variable
SELECT foo(a)
-- <- keyword
-- ^ function
FROM table1
-- <- keyword
LEFT JOIN table2 ON table1.a = table2.a
-- <- keyword
-- ^ keyword
-- ^ keyword
WHERE a = b
-- <- keyword
-- ^ operator
GROUP BY a, b
-- <- keyword
-- ^ keyword
ORDER BY lower(a), b
-- <- keyword
-- ^ keyword
-- ^ function
select a, b::int;
-- <- keyword
-- ^ type.builtin
from table1
-- <- keyword
where a = b
-- <- keyword
group by a, b
-- <- keyword
-- ^ keyword
order by lower(a), b;
-- <- keyword
-- ^ keyword
SELECT (SELECT 1), a
-- <- keyword
-- ^ keyword
-- ^ number
FROM (SELECT a FROM table) AS b;
-- <- keyword
-- ^ keyword
-- ^ keyword
-- ^ keyword
SELECT a, b
FROM a
ORDER by a, b
-- <- keyword
-- ^ keyword
GrOUP
-- <- keyword
By a, b
-- <- keyword
SELECT $$a$$, $a$baz$a$, $a$$$$a$, $a$b$$a$;
-- <- keyword
-- ^ string
-- ^ string
-- ^ string
-- ^ string

@ -1,30 +0,0 @@
CREATE SCHEMA information_schema;
-- <- keyword
-- ^ keyword
-- ^ variable
CREATE SCHEMA IF NOT EXISTS information_schema;
-- <- keyword
-- ^ keyword
-- ^ keyword
-- ^ keyword
-- ^ keyword
GRANT USAGE ON SCHEMA information_schema TO PUBLIC;
-- <- keyword
-- ^ keyword
-- ^ keyword
-- ^ keyword
-- ^ variable
-- ^ keyword
-- ^ keyword
SET LOCAL search_path TO 'test';
-- <- keyword
-- ^ keyword
-- ^ variable
-- ^ keyword
-- ^ string
SET SESSION search_path TO 'test';
-- <- keyword
-- ^ keyword
-- ^ variable
-- ^ keyword
-- ^ string

@ -1,43 +0,0 @@
CREATE TABLE accounts (
-- <- keyword
--- ^ keyword
--- ^ variable
user_id serial PRIMARY KEY,
-- <- variable
-- ^ type.builtin
-- ^ keyword
-- ^ keyword
username VARCHAR UNIQUE NOT NULL,
-- <- variable
-- ^ type.builtin
-- ^ keyword
-- ^ keyword
-- ^ constant.builtin
password VARCHAR NOT NULL,
-- <- variable
-- ^ type.builtin
-- ^ keyword
-- ^ constant.builtin
email VARCHAR UNIQUE NOT NULL,
-- <- variable
-- ^ type.builtin
-- ^ keyword
-- ^ keyword
-- ^ constant.builtin
created_on TIMESTAMP NOT NULL,
-- <- variable
-- ^ type.builtin
-- ^ keyword
-- ^ constant.builtin
last_login TIMESTAMP,
-- <- variable
-- ^ type.builtin
created_at TIMESTAMP WITH TIME ZONE,
-- ^ keyword
-- ^ keyword
-- ^ keyword
updated_at TIMESTAMP WITHOUT TIME ZONE
-- ^ keyword
-- ^ keyword
-- ^ keyword
);

@ -1,6 +0,0 @@
CREATE TYPE foo AS (a TEXT, b TEXT);
-- <- keyword
-- ^ keyword
-- ^ keyword
-- ^ type.builtin
-- ^ type.builtin

@ -1,12 +0,0 @@
UPDATE table1 SET foo = 1
-- <- keyword
-- ^ variable
-- ^ keyword
-- ^ variable
-- ^ operator
-- ^ number
WHERE foo > t.col1;
-- <- keyword
-- ^ variable
-- ^ operator
-- ^ variable