Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
sql-parser-cst
Advanced tools
SQL Parser which produces a Concrete Syntax Tree (CST).
Unlike a more usual parser which produces an Abstract Syntax Tree (AST), this parser preserves all the syntax elements present in the parsed source code, with the goal of being able to re-create the exact original source code.
For now it supports the following SQL dialects:
Note: This software is still in very active development. The syntax tree structure is constantly evolving and changing even between patch versions.
import { parse, show, sqlite, cstVisitor } from "sql-parser-cst";
const cst = parse("select * from my_table", {
dialect: sqlite,
// These are optional:
preserveSpaces: true, // Adds spaces/tabs
preserveNewlines: true, // Adds newlines
preserveComments: true, // Adds comments
includeRange: true, // Adds source code location data
});
// convert all keywords to uppercase
const toUpper = cstVisitor({
keyword: (kw) => {
kw.text = kw.text.toUpperCase();
},
});
toUpper(cst);
// Serialize back to SQL
show(cst); // --> SELECT * FROM my_table
For example, given the following SQL:
/* My query */
SELECT ("first_name" || ' jr.') as fname
-- use important table
FROM persons
An AST-parser might parse this to the following abstract syntax tree:
{
"type": "select_stmt",
"columns": [
{
"type": "alias",
"expr": {
"type": "binary_expr",
"left": { "type": "column_ref", "column": "first_name" },
"operator": "||",
"right": { "type": "string", "value": " jr." }
},
"alias": "fname"
}
],
"from": [{ "type": "table_ref", "table": "persons" }]
}
Note that the above AST is missing the following information:
AS
or as
was written)In contrast, this CST parser produces the following concrete syntax tree, which preserves all of this information:
{
"type": "select_stmt",
"clauses": [
{
"type": "select_clause",
"selectKw": { "type": "keyword", "text": "SELECT" },
"columns": [
{
"type": "alias",
"expr": {
"type": "paren_expr",
"expr": {
"type": "binary_expr",
"left": {
"type": "column_ref",
"column": { "type": "identifier", "text": "\"first_name\"" }
},
"operator": "||",
"right": { "type": "string", "text": "' jr.'" }
}
},
"asKw": { "type": "keyword", "text": "as" },
"alias": { "type": "identifier", "text": "fname" }
}
]
},
{
"type": "from_clause",
"fromKw": { "type": "keyword", "text": "FROM" },
"tables": [
{
"type": "table_ref",
"table": { "type": "keyword", "text": "persons" }
}
],
"leading": [
{ "type": "newline", "text": "\n" },
{ "type": "line_comment", "text": "-- use important table" },
{ "type": "newline", "text": "\n" }
]
}
],
"leading": [
{ "type": "block_comment", "text": "/* My query */" },
{ "type": "newline", "text": "\n" }
]
}
Note the following conventions:
type: keyword
nodes, which are usually
stored in fields named like someNameKw
.type: paren_expr
node.text
fields.leading
and trailing
fields,
which store comments and newlines immediately before or after that node.
These fields will also contain information about regular spaces/tabs
(e.g. {"type": "space", "text": " \t"}
). This has been left out from this
example for the sake of simplicity.yarn generate
will generate parser for each supported dialect.
You can also target a specific dialect, like yarn generate sqlite
.
The testsuite contains two kinds of tests:
When running the testsuite one always needs to pick a dialect.
For example yarn test:sqlite
or yarn test:mysql
.
Running one of these commands will run the testsuite against the parser
of that dialect. It will execute all the generic tests plus tests
applicable for that dialect.
yarn test
will execute the testsuite for each supported dialect,
covering all the possible combinations.
Start the parser-generator watch process in one terminal:
yarn watch:generate
and the tests watch process in another terminal:
yarn test:sqlite --watch
Note that yarn test --watch
doesn't work.
A separate watch process needs to be started manually for each dialect.
This started as a fork of node-sql-parser, which is based on @flora/sql-parser, which in turn was extracted from Alibaba's nquery module.
There's very little left of the original code though.
FAQs
Parses SQL into Concrete Syntax Tree (CST)
The npm package sql-parser-cst receives a total of 5,382 weekly downloads. As such, sql-parser-cst popularity was classified as popular.
We found that sql-parser-cst demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.