flora-sql-parser
Advanced tools
Comparing version 0.7.4 to 0.7.5
@@ -31,2 +31,6 @@ 'use strict'; | ||
function identifierToSql(ident) { | ||
return `"${ident}"`; | ||
} | ||
function literalToSQL(literal) { | ||
@@ -112,4 +116,4 @@ const { type } = literal; | ||
function columnRefToSQL(expr) { | ||
let str = expr.column !== '*' ? '"' + expr.column + '"' : '*'; | ||
if (has(expr, 'table') && expr.table !== null) str = '"' + expr.table + '".' + str; | ||
let str = expr.column !== '*' ? identifierToSql(expr.column) : '*'; | ||
if (has(expr, 'table') && expr.table !== null) str = identifierToSql(expr.table) + '.' + str; | ||
return !expr.parentheses ? str : '(' + str + ')'; | ||
@@ -140,3 +144,3 @@ } | ||
str += ' AS '; | ||
if (column.as.match(/^[a-z_][0-9a-z_]*$/i)) str += '"' + column.as + '"'; | ||
if (column.as.match(/^[a-z_][0-9a-z_]*$/i)) str += identifierToSql(column.as); | ||
else str += '\'' + column.as + '\''; | ||
@@ -157,6 +161,7 @@ } | ||
const clauses = []; | ||
let str = baseTable.table ? '"' + baseTable.table + '"' : exprToSQL(baseTable.expr); | ||
if (baseTable.type === 'dual') return 'DUAL'; | ||
let str = baseTable.table ? identifierToSql(baseTable.table) : exprToSQL(baseTable.expr); | ||
if (baseTable.db && baseTable.db !== null) str = baseTable.db + '.' + str; | ||
if (baseTable.as !== null) str += ' AS "' + baseTable.as + '"'; | ||
if (baseTable.as !== null) str += ' AS ' + identifierToSql(baseTable.as); | ||
@@ -172,3 +177,3 @@ clauses.push(str); | ||
if (joinExpr.db !== null) str += (joinExpr.db + '.'); | ||
str += '"' + joinExpr.table + '"'; | ||
str += identifierToSql(joinExpr.table); | ||
} else { | ||
@@ -178,4 +183,5 @@ str += exprToSQL(joinExpr.expr); | ||
if (joinExpr.as !== null) str += ' AS "' + joinExpr.as + '"'; | ||
if (joinExpr.as !== null) str += ' AS ' + identifierToSql(joinExpr.as); | ||
if (has(joinExpr, 'on') && joinExpr.on !== null) str += ' ON ' + exprToSQL(joinExpr.on); | ||
if (has(joinExpr, 'using')) str += ' USING (' + joinExpr.using.map(identifierToSql).join(', ') + ')'; | ||
@@ -182,0 +188,0 @@ clauses.push(str); |
{ | ||
"name": "flora-sql-parser", | ||
"version": "0.7.4", | ||
"version": "0.7.5", | ||
"description": "Parse SQL (select) statements into abstract syntax tree (AST) and convert ASTs back to SQL.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -53,3 +53,3 @@ 'use strict'; | ||
["'", '"', 'n', 't', '\\'].forEach((char) => { | ||
it('should escape char "' + char + '"', () => { | ||
it(`should escape char ${char} "`, () => { | ||
sql = `SELECT ' escape \\${char}'`; | ||
@@ -116,2 +116,7 @@ expect(getParsedSql(sql)).to.equal(sql); | ||
}); | ||
it('should parse DUAL table', () => { | ||
sql = `SELECT "id" FROM DUAL`; | ||
expect(getParsedSql(sql)).to.equal(sql); | ||
}); | ||
}); | ||
@@ -161,2 +166,12 @@ | ||
}); | ||
it('should support USING keyword (single column)', () => { | ||
expect(getParsedSql('SELECT * FROM t1 JOIN t2 USING (id)')) | ||
.to.equal('SELECT * FROM "t1" INNER JOIN "t2" USING ("id")'); | ||
}); | ||
it('should support USING keyword (multiple columns)', () => { | ||
expect(getParsedSql('SELECT * FROM t1 JOIN t2 USING (id1, id2)')) | ||
.to.equal('SELECT * FROM "t1" INNER JOIN "t2" USING ("id1", "id2")'); | ||
}); | ||
}); | ||
@@ -166,5 +181,5 @@ | ||
['<', '<=', '=', '!=', '>=', '>'].forEach((operator) => { | ||
it('should support simple "' + operator + '" comparison', () => { | ||
sql = 'SELECT a fRom db.t wHERE "type" ' + operator + ' 3'; | ||
expect(getParsedSql(sql)).to.equal('SELECT "a" FROM db."t" WHERE "type" ' + operator + ' 3'); | ||
it(`should support simple "${operator}" comparison`, () => { | ||
sql = `SELECT a fRom db.t wHERE "type" ${operator} 3`; | ||
expect(getParsedSql(sql)).to.equal(`SELECT "a" FROM db."t" WHERE "type" ${operator} 3`); | ||
}); | ||
@@ -177,3 +192,3 @@ }); | ||
it('should convert "' + operator + '" to ' + sqlOperator + ' operator for array values', () => { | ||
it(`should convert "${operator}" to ${sqlOperator} operator for array values`, () => { | ||
const ast = { | ||
@@ -198,3 +213,3 @@ type: 'select', | ||
expect(util.astToSQL(ast)).to.equal('SELECT "a" FROM "t" WHERE "id" ' + sqlOperator + ' (1, 2)'); | ||
expect(util.astToSQL(ast)).to.equal(`SELECT "a" FROM "t" WHERE "id" ${sqlOperator} (1, 2)`); | ||
}); | ||
@@ -204,5 +219,5 @@ }); | ||
['IN', 'NOT IN'].forEach((operator) => { | ||
it('should support ' + operator + ' operator', () => { | ||
sql = 'SELECT a FROM t WHERE id ' + operator.toLowerCase() + ' (1, 2, 3)'; | ||
expect(getParsedSql(sql)).to.equal('SELECT "a" FROM "t" WHERE "id" ' + operator + ' (1, 2, 3)'); | ||
it(`should support ${operator} operator`, () => { | ||
sql = `SELECT a FROM t WHERE id ${operator.toLowerCase()} (1, 2, 3)`; | ||
expect(getParsedSql(sql)).to.equal(`SELECT "a" FROM "t" WHERE "id" ${operator} (1, 2, 3)`); | ||
}); | ||
@@ -212,5 +227,5 @@ }); | ||
['IS', 'IS NOT'].forEach((operator) => { | ||
it('should support ' + operator + ' operator', () => { | ||
sql = 'SELECT a FROM t WHERE col ' + operator.toLowerCase() + ' NULL'; | ||
expect(getParsedSql(sql)).to.equal('SELECT "a" FROM "t" WHERE "col" ' + operator + ' NULL'); | ||
it(`should support ${operator} operator`, () => { | ||
sql = `SELECT a FROM t WHERE col ${operator.toLowerCase()} NULL`; | ||
expect(getParsedSql(sql)).to.equal(`SELECT "a" FROM "t" WHERE "col" ${operator} NULL`); | ||
}); | ||
@@ -245,5 +260,5 @@ }); | ||
['EXISTS', 'NOT EXISTS'].forEach((operator) => { | ||
it('should support ' + operator + ' operator', () => { | ||
expect(getParsedSql('SELECT a FROM t WHERE ' + operator + ' (SELECT 1)')) | ||
.to.equal('SELECT "a" FROM "t" WHERE ' + operator + ' (SELECT 1)'); | ||
it(`should support ${operator} operator`, () => { | ||
expect(getParsedSql(`SELECT a FROM t WHERE ${operator} (SELECT 1)`)) | ||
.to.equal(`SELECT "a" FROM "t" WHERE ${operator} (SELECT 1)`); | ||
}); | ||
@@ -484,3 +499,3 @@ }); | ||
Object.keys(unsupportedStatements).forEach((stmtType) => { | ||
it('should throw exception for ' + stmtType + ' statements', () => { | ||
it(`should throw exception for ${stmtType} statements`, () => { | ||
expect(() => { | ||
@@ -487,0 +502,0 @@ getParsedSql(unsupportedStatements[stmtType]); |
@@ -213,2 +213,25 @@ 'use strict'; | ||
}); | ||
it('should parse joins with USING (single column)', () => { | ||
ast = parser.parse('SELECT * FROM t1 JOIN t2 USING (id)'); | ||
expect(ast.from).to.eql([ | ||
{ db: null, table: 't1', as: null }, | ||
{ db: null, table: 't2', as: null, join: 'INNER JOIN', using: ['id'] } | ||
]); | ||
}); | ||
it('should parse joins with USING (multiple columns)', () => { | ||
ast = parser.parse('SELECT * FROM t1 JOIN t2 USING (id1, id2)'); | ||
expect(ast.from).to.eql([ | ||
{ db: null, table: 't1', as: null }, | ||
{ db: null, table: 't2', as: null, join: 'INNER JOIN', using: ['id1', 'id2'] } | ||
]); | ||
}); | ||
it('should parse DUAL table', () => { | ||
ast = parser.parse('SELECT * FROM DUAL'); | ||
expect(ast.from).to.eql([{ type: 'dual' }]); | ||
}); | ||
}); | ||
@@ -255,4 +278,4 @@ | ||
['is', 'is not'].forEach((operator) => { | ||
it('should parse condition', () => { | ||
ast = parser.parse('SELECT * FROM t WHERE "col" ' + operator + ' NULL'); | ||
it(`should parse ${operator} condition`, () => { | ||
ast = parser.parse(`SELECT * FROM t WHERE "col" ${operator} NULL`); | ||
@@ -270,3 +293,3 @@ expect(ast.where).to.eql({ | ||
it('should parse ' + operator.toUpperCase() + ' condition', () => { | ||
ast = parser.parse('SELECT * FROM t WHERE ' + operator + ' (SELECT 1)'); | ||
ast = parser.parse(`SELECT * FROM t WHERE ${operator} (SELECT 1)`); | ||
@@ -273,0 +296,0 @@ expect(ast.where).to.eql({ |
Sorry, the diff of this file is not supported yet
1196
79881
16