Nodejs SQL Parser
Parse simple SQL statements into an abstract syntax tree (AST) with the visited tableList, columnList and convert it back to SQL.
:star: Features
- support multiple sql statement seperate by semicolon
- support select, delete, update and insert type
- support drop, truncate and rename command
- output the table and column list that the sql visited with the corresponding authority
- support various databases engine
:tada: Install
npm install node-sql-parser --save
or
yarn add node-sql-parser
From Browser
Import the JS file in your page:
<script src="https://unpkg.com/node-sql-parser/umd/index.umd.js"></script>
<script src="https://unpkg.com/node-sql-parser/umd/mysql.umd.js"></script>
<script src="https://unpkg.com/node-sql-parser/umd/postgresql.umd.js"></script>
NodeSQLParser
object is on window
<!DOCTYPE html>
<html lang="en" >
<head>
<title>node-sql-parser</title>
<meta charset="utf-8" />
</head>
<body>
<p><em>Check console to see the output</em></p>
<script src="https://unpkg.com/node-sql-parser/umd/mysql.umd.js"></script>
<script>
window.onload = function () {
const parser = new NodeSQLParser.Parser()
const ast = parser.astify("select id, name from students where age < 18")
console.log(ast)
const sql = parser.sqlify(ast)
console.log(sql)
}
</script>
</body>
</html>
:rocket: Usage
Supported Database SQL Syntax
- Athena
- BigQuery
- DB2
- Hive
- MariaDB
- MySQL
- PostgresQL
- Redshift
- Sqlite
- TransactSQL
- FlinkSQL
- Snowflake(alpha)
- Noql
- New issue could be made for other new database.
Create AST for SQL statement
const { Parser } = require('node-sql-parser');
const parser = new Parser();
const ast = parser.astify('SELECT * FROM t');
console.log(ast);
{
"with": null,
"type": "select",
"options": null,
"distinct": null,
"columns": "*",
"from": [
{
"db": null,
"table": "t",
"as": null
}
],
"where": null,
"groupby": null,
"having": null,
"orderby": null,
"limit": null
}
Get node location in the AST
const { Parser } = require('node-sql-parser');
const parser = new Parser();
const ast = parser.astify('SELECT * FROM t', { parseOptions: { includeLocations: true } });
console.log(ast);
ast
for SELECT * FROM t
with the loc
property indicating locations and ranges
{
"with": null,
"type": "select",
"options": null,
"distinct": null,
"columns": [
{
"expr": {
"type": "column_ref",
"table": null,
"column": "*"
},
"as": null,
"loc": {
"start": {
"offset": 7,
"line": 1,
"column": 8
},
"end": {
"offset": 8,
"line": 1,
"column": 9
}
}
}
],
"into": {
"position": null
},
"from": [
{
"db": null,
"table": "t",
"as": null,
"loc": {
"start": {
"offset": 14,
"line": 1,
"column": 15
},
"end": {
"offset": 15,
"line": 1,
"column": 16
}
}
}
],
"where": null,
"groupby": null,
"having": null,
"orderby": null,
"limit": null,
"locking_read": null,
"window": null,
"loc": {
"start": {
"offset": 0,
"line": 1,
"column": 1
},
"end": {
"offset": 15,
"line": 1,
"column": 16
}
}
}
Convert AST back to SQL
const opt = {
database: 'MySQL'
}
const { Parser } = require('node-sql-parser');
const parser = new Parser()
const ast = parser.astify('SELECT * FROM t', opt);
const sql = parser.sqlify(ast, opt);
console.log(sql);
Parse specified Database
There two ways to parser the specified database.
import Parser from the specified database path node-sql-parser/build/{database}
const { Parser } = require('node-sql-parser/build/transactsql')
const parser = new Parser()
const sql = `SELECT id FROM test AS result`
const ast = parser.astify(sql)
console.log(parser.sqlify(ast))
OR you can pass a options object to the parser, and specify the database property.
const opt = {
database: 'Postgresql'
}
const { Parser } = require('node-sql-parser')
const parser = new Parser()
const ast = parser.astify('SELECT * FROM t', opt)
const sql = parser.sqlify(ast, opt)
console.log(sql);
Get TableList, ColumnList, Ast by parse
function
const opt = {
database: 'MariaDB'
}
const { Parser } = require('node-sql-parser/build/mariadb');
const parser = new Parser()
const { tableList, columnList, ast } = parser.parse('SELECT * FROM t', opt);
Get the SQL visited tables
- get the table list that the sql visited
- the format is {type}::{dbName}::{tableName} // type could be select, update, delete or insert
const opt = {
database: 'MySQL'
}
const { Parser } = require('node-sql-parser/build/mysql');
const parser = new Parser();
const tableList = parser.tableList('SELECT * FROM t', opt);
console.log(tableList);
Get the SQL visited columns
- get the column list that the sql visited
- the format is {type}::{tableName}::{columnName} // type could be select, update, delete or insert
- for
select *
, delete
and insert into tableName values()
without specified columns, the .*
column authority regex is required
const opt = {
database: 'MySQL'
}
const { Parser } = require('node-sql-parser/build/mysql');
const parser = new Parser();
const columnList = parser.columnList('SELECT t.id FROM t', opt);
console.log(columnList);
Check the SQL with Authority List
- check table authority
whiteListCheck
function check on table
mode and MySQL
database by default
const { Parser } = require('node-sql-parser');
const parser = new Parser();
const sql = 'UPDATE a SET id = 1 WHERE name IN (SELECT name FROM b)'
const whiteTableList = ['(select|update)::(.*)::(a|b)']
const opt = {
database: 'MySQL',
type: 'table',
}
parser.whiteListCheck(sql, whiteTableList, opt)
const { Parser } = require('node-sql-parser');
const parser = new Parser();
const sql = 'UPDATE a SET id = 1 WHERE name IN (SELECT name FROM b)'
const whiteColumnList = ['select::null::name', 'update::a::id']
const opt = {
database: 'MySQL',
type: 'column',
}
parser.whiteListCheck(sql, whiteColumnList, opt)
:kissing_heart: Acknowledgement
This project is inspired by the SQL parser flora-sql-parser module.
License
Apache-2.0