diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2ccbe46 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/node_modules/ diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..1d3acd0 --- /dev/null +++ b/.jshintrc @@ -0,0 +1,48 @@ +{ + "predef": [ + "document", + "module", + "require", + "__dirname", + "process", + "console", + "it", + "xit", + "describe", + "xdescribe", + "before", + "beforeEach", + "after", + "afterEach", + "expect", + "Log", + "SERVER", + "RUN_MODE", + "abs" + ], + "node": true, + "es5": false, + "bitwise": true, + "curly": true, + "eqeqeq": true, + "forin": false, + "immed": true, + "latedef": true, + "newcap": true, + "noarg": true, + "noempty": true, + "nonew": true, + "plusplus": false, + "undef": true, + "strict": false, + "trailing": false, + "globalstrict": true, + "nonstandard": true, + "white": true, + "indent": 2, + "expr": true, + "multistr": true, + "onevar": false, + "unused": "vars", + "sub": true +} diff --git a/.npmigore b/.npmigore new file mode 100644 index 0000000..eaa4e5e --- /dev/null +++ b/.npmigore @@ -0,0 +1,4 @@ +/node_modules/ +/peg/ +/test/ +Makefile diff --git a/Makefile b/Makefile index 100fcc1..b60763a 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,12 @@ TESTS = test/unit/*.js REPORTER = spec -test: clean - @npm install - @./node_modules/pegjs/bin/pegjs peg/nquery.pegjs ./base/nquery.js - @./node_modules/mocha/bin/mocha $(TESTS) --reporter spec +install: + @npm install + @./node_modules/pegjs/bin/pegjs -o ./lib/parse.js ./peg/sqlparser.pegjs +test: install + @./node_modules/mocha/bin/mocha -r should $(TESTS) --reporter spec clean: + rm -rf ./node_modules .PHONY: test diff --git a/README.md b/README.md index ae9e2aa..87fb060 100644 --- a/README.md +++ b/README.md @@ -1,124 +1,58 @@ -## ![logo](http://nquery.org/images/robin-small.jpg) nQuery +node-sqlparser -Generic SQL engine for Web and Big-data. +====== + +node-sqlparser, write in javascript ## Install NodeJS Version 0.8.0+ ``` -npm install node-query +npm install node-sqlparser ``` ## Introduction -it could be used in some typical scenarios: - * As a SQL frontend, do syntax checking and formating. - * As a SQL engine for your KV databases like HBase or anything like that. - * Providing a SQL interface for your HTTP/WEB service. - * Do data merging and intergration among many different data sources like Oracle, MySQL, HBase etc. - - -## Demo & Test -to run the demo, type the command: -``` -node demo/demo.js -``` for the test , type the command: ``` -make +make test ``` -read the demo carefully and then you could write own loader/adapter, -there are also many test cases in `test/unit`, they would be great helpful to you. - - ## Usage -please read the demo files `demo/demo.js` - -for a KV storage engine ,what you need to do is providing the query interfaces like: - - * `singleQuery`, - * `rangeQuery`, - * `likeQuery` - -for a SQL storage engine, you should realize a function like : +static function ```js -function query(str, function(err, data) { - ... -}) -``` - -then you could execute SQL like that : (code snippet from `demo.js`) +var sql = 'select * from tablea where field1 = 0'; +var parse = require('node-sqlparser').parse; +var stringify = require('node-sqlparser').stringify; +var astObj = parse(sql); -```js -var sqls = [ - "SELECT * FROM kv.user WHERE id IN ('01', '03')", - "SELECT * FROM kv.user WHERE id LIKE '1%'", - "SELECT type, MAX(age), COUNT(id) FROM kv.user WHERE id BETWEEN '03' AND '10' GROUP BY type ORDER BY MAX(age) DESC", - "SELECT * from mysql.shop where shop_id > 5" -] - -var concurrentJoinSQL = [ - "$a := select * from kv.user where id BETWEEN '03' and '10'", - "$b := select * from mysql.shop where shop_id > 5", - "$c := select a.type , a.id ,b.name, b.title from $a INNER JOIN $b ON a.type = b.type WHERE a.id > '04'", - "return $c" -] - -var sequentialJoinSQL = [ - "$a := select * from kv.user where id BETWEEN '03' and '10'", - //you could also use `unique` do filter firstly - //"$type := UNIQUE($a.type)", - //"$b := select * from mysql.shop where type = $type", - "$b := select * from mysql.shop where type in $a.type", - "$c := select a.type , a.id ,b.name, b.title from $a INNER JOIN $b ON a.type = b.type WHERE a.id > '04'", - "return [$b, $c]" -] +var sqlstr = stringify(astObj); ``` -As you see ,besides as a SQL computation level built on top of KV storage engine, it could do -join operation among kv data source, sql sources, HTTP services now - -## nSQL Definition - -The 'a little strange' sql as you see above, nSQL realize a subset of SQL92, and it -also has some procedure features, it supports variables, it addes types of `var` -/ `array` / `table`, and also keyword `return`, for the details, please see the -specification of `peg/nquery.pgejs`. - - -## Task Scheduling - -As you could see in `concurrentJoinSQL` ,we know that the tasks `$a`, `$b` have no -relations, so nQuery would do them concurrently, but for the procedure of `sequentialJoinSQL`, -`$b` is depending on `$a`,so task `$b` would be executed after the time `$a` completed - -## KeyWord `return` - -In traditional SQL, the query result is a 2-D table , but In nSQL ,we add types of `array` -/ `table`,so now you could return complicated results like - -``` -return [$b, $c, 'hello', [1, 2]] +using ast ``` +var AST = require('node-sqlparser'); +var ast = new AST(); +ast.parse(sql); -###Just Enjoy It! +ast.stringify(); +``` -### Acknowledgements +## Acknowledgements -* PegJS : http://pegjs.majda.cz/ -* NodeJS : http://nodejs.org/ -* BigQuery : https://developers.google.com/bigquery/docs/query-reference -* PL/SQL : http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/fundamentals.htm#autoId0 -* MySQL : http://dev.mysql.com/doc/refman/5.1/en/sql-syntax.html -* Impala : https://github.com/cloudera/impala/blob/master/fe/src/main/cup/sql-parser.y -* PgSQL : http://www.postgresql.org/docs/9.2/interactive/sql-syntax.html +* PegJS : http://pegjs.majda.cz/ +* NodeJS : http://nodejs.org/ +* BigQuery : https://developers.google.com/bigquery/docs/query-reference +* PL/SQL : http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/fundamentals.htm#autoId0 +* MySQL : http://dev.mysql.com/doc/refman/5.1/en/sql-syntax.html +* Impala : https://github.com/cloudera/impala/blob/master/fe/src/main/cup/sql-parser.y +* PgSQL : http://www.postgresql.org/docs/9.2/interactive/sql-syntax.html * ql.io : http://ql.io diff --git a/base/aggregation.js b/base/aggregation.js deleted file mode 100644 index 1b59213..0000000 --- a/base/aggregation.js +++ /dev/null @@ -1,79 +0,0 @@ -// (C) 2011-2013 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - -var Tool = require('../lib/tool'); -var Engine = require('../lib/engine'); -var AstHelper = require('../lib/ast_helper'); - -var runExpr = Engine.run; -var getSelRefCols = AstHelper.getSelRefCols; -var getRefColInfo = AstHelper.getRefColInfo; - -var backupRefCols = AstHelper.backupRefCols; -var restoreRefCols = AstHelper.restoreRefCols; - -function debug(str) { - //console.log(str); -} - -function inspect(obj) { - //console.log(require('util').inspect(obj, false, 10)); -} - -module.exports = doAggregation; - -function doAggregation(dc, sels, info) { - // { - // id1 : { - // cols : [val1, val2, val3,...] - // pos : 2 - // } , - // id2 : { - // cols : [,,] - // pos : - // } - // } - if (!info) { - var refCols = getSelRefCols(sels); - info = getRefColInfo(refCols, dc.columns); - } - //inspect(refCols); - - var i, key, pos, vals; - var valMap = {}; - var rows = dc.data; - for (key in info) { - vals = []; - pos = info[key].pos; - for (i = 0; i < rows.length; i++) { - vals.push(rows[i][pos]); - } - valMap[key] = vals; - } - //inspect(valMap); - var rc; - for (key in info) { - rc = info[key].cols; - vals = valMap[key]; - for (i = 0; i < rc.length; i++) { - rc[i].type = 'literal_list'; - rc[i].value = vals; - } - } - - var val; - var row = []; - for (i = 0; i < sels.length; i++) { - val = runExpr(sels[i].expr); - //for no aggr fuctions - if (Array.isArray(val)) { - val = val[0]; - } - row.push(val); - } - return row; -} diff --git a/base/column.js b/base/column.js deleted file mode 100644 index f904894..0000000 --- a/base/column.js +++ /dev/null @@ -1,135 +0,0 @@ -// (C) 2011-2013 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - -var Tool = require('../lib/tool'); -var Engine = require('../lib/engine'); -var Adapter = require('../lib/adapter'); -var AstHelper = require('../lib/ast_helper'); - -var doGroupby = require('./groupby'); -var doAggregation = require('./aggregation'); - -var runExpr = Engine.run; - -var checkAggrOp = AstHelper.checkAggrOp; -var getRefColPos = AstHelper.getRefColPos; -var getRefColumns = AstHelper.getRefColumns; - -var getSelRefCols = AstHelper.getSelRefCols; -var getRefColInfo = AstHelper.getRefColInfo; - -var fillExprOnRow = AstHelper.fillExprOnRow; -var backupRefCols = AstHelper.backupRefCols; -var getColumnNames = AstHelper.getColumnNames; -var restoreRefCols = AstHelper.restoreRefCols; - - -function debug(str) { - //console.log(str); -} - -function inspect(obj) { - //console.log(require('util').inspect(obj, false, 10)); -} - -module.exports = filter; - -/** -** @param {Array} gb, groupby columns -*/ -function filter(dc, sels, gb) { - if (sels == '*') { - return dc; - } - var rows; - if (checkAggrOp(gb, sels)) { - rows = selectAggr(dc, sels, gb); - } else { - rows = selectCol(dc, sels); - } - - var cols = getColumnNames(sels); - - return { - columns : cols, - data : rows - } -} - -function selectAggr(dc, sels, gb) { - var refCols = getSelRefCols(sels); - var rcInfo = getRefColInfo(refCols, dc.columns); - var rbackup = backupRefCols(refCols); - - var gds; - if (Array.isArray(gb) && gb.length > 0) { - gds = doGroupby(dc, gb); - } else { - gds = { - _ : dc - } - } - var r, gd, key; - var rows = []; - for (key in gds) { - dc = gds[key]; - r = doAggregation(dc, sels, rcInfo); - rows.push(r); - } - restoreRefCols(refCols, rbackup); - return rows; -} - -function selectCol(dc, sels) { - // refCols - // [ - // [aid, bid], - // [cid, aid], - // [cid, bid], - // [aid] - // ] - var exprs = []; - var refPos = []; - var refCols = []; - var rbackup = []; - var i, j, e, rc, rp, rb; - var columns = dc.columns; - for (i = 0; i < sels.length; i++) { - e = sels[i].expr; - rc = getRefColumns(e); - rp = getRefColPos(rc, columns) - - exprs.push(e); - refPos.push(rp); - refCols.push(rc); - - rb = backupRefCols(rc); - rbackup.push(rb); - } - - var rs; - var data = []; - var r, val, row; - var rows = dc.data; - for (i = 0; i < rows.length; i++) { - r = rows[i]; - row = []; - for (j = 0; j < exprs.length; j++) { - fillExprOnRow(r, refCols[j], refPos[j]); - val = runExpr(exprs[j]); - row.push(val); - } - data.push(row); - } - - //restore - for (i = 0; i< refCols.length; i++) { - restoreRefCols(refCols[i], rbackup[i]); - } - //inspect(rbackup); - return data; -} diff --git a/base/distinct.js b/base/distinct.js deleted file mode 100644 index c3e4cc3..0000000 --- a/base/distinct.js +++ /dev/null @@ -1,49 +0,0 @@ -// (C) 2011-2013 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - -/** - * @param {Object} dc like :{ - * columns : ['col1', 'col2'], - * data : [ - * ['a', 'b', 'c'], - * ['b', 'c', 'd'] - * ] - * } - */ - -module.exports = function (dc){ - dc.data = distinct(dc.data); - return dc; -} - -function distinct(data){ - var res = []; - var map = {}; - for(var i = 0; i < data.length; i++){ - var cols = data[i]; - var key = []; - for(var j = 0; j < cols.length; j++){ - var c = cols[j]; - key.push((typeof c ) + c); - } - key = key.join('_'); - - if(map[key] === undefined){ - map[key] = true; - res.push(cols); - } - } - return res; -} - -function debug(str){ - //console.log(str); -} - -function inspect(obj){ - //console.log(require('util').inspect(obj)); -} diff --git a/base/groupby.js b/base/groupby.js deleted file mode 100644 index cafc937..0000000 --- a/base/groupby.js +++ /dev/null @@ -1,58 +0,0 @@ -// (C) 2011-2013 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - - -var AstHelper = require('../lib/ast_helper'); - -module.exports = doGroupby; - -function debug(str){ - //console.log(str); -} - -function inspect(obj){ - //console.log(require("util").inspect(obj, false, 10)); -} - -var getRefColPos = AstHelper.getRefColPos; - -function genGbKey(args){ - var keys = []; - for(var i = 0; i < args.length; i++){ - var c = args[i]; - keys.push((typeof c) + '_' + c); - } - return keys.join('__'); -} - -function doGroupby(dc, gb) { - var i, j; - var columns = dc.columns; - var data = dc.data; - - var gbPos = []; - gbPos = getRefColPos(gb, columns); - - var res = {}; - for (i = 0; i < data.length; i++) { - var gCols = []; - var d = data[i]; - for (j = 0; j < gbPos.length; j++) { - var p = gbPos[j] - gCols.push(d[p]); - } - var key = genGbKey(gCols); - if (res[key] == null){ - res[key] = { - columns : columns, - data : [] - } - } - res[key].data.push(d); - } - return res; -} diff --git a/base/join.js b/base/join.js deleted file mode 100644 index c2c19b9..0000000 --- a/base/join.js +++ /dev/null @@ -1,271 +0,0 @@ -// (C) 2011-2013 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - -exports.leftJoin = leftJoin; -exports.innerJoin = innerJoin; - -function debug(str){ - //console.log(str); -} - -function inspect(obj){ - //console.log(require('util').inspect(obj, false, 10)); -} - -function leftJoin(ta ,tb, on){ - var ka = on.left; - var kb = on.right; - - var klen = kb.length; - var i, j, k; - - //hash b like that: - // kb1 : [ele1, ele2] - // kb2 : [el3, ele5]; - var adata = ta.data; - var bdata = tb.data; - var tblen = bdata.length; - var talen = adata.length; - - var ele; - var aele; - var bele; - var key; - var hba; - - var tbCol, found; - var apos = []; - var acols = ta.columns; - for (i = 0; i < klen; i++) { - for (j = 0; j < acols.length; j++){ - found = false; - for (k = 0; k < acols[j].length; k++) { - tbCol = acols[j][k]; - if (tbCol.table == ka[i].table && tbCol.column == ka[i].column) { - apos.push(j) - found = true; - break; - } - } - if (found) break; - } - } - - - var bpos = []; - var bcols = tb.columns; - for (i = 0; i < klen; i++) { - for (j = 0; j < bcols.length; j++) { - found = false; - for (k = 0; k < bcols[j].length; k++) { - tbCol = bcols[j][k]; - if (tbCol.table == kb[i].table && tbCol.column == kb[i].column) { - bpos.push(j) - found = true; - break; - } - } - if (found) break; - } - } - - //debug(bcols :" + bcols); - //debug("bpos :" + bpos); - - var rcols = [].concat(acols); - for (i = 0; i < apos.length; i++) { - rcols[apos[i]] = rcols[apos[i]].concat(bcols[bpos[i]]); - } - - var diffpos = []; - for (i = 0; i < bcols.length; i++) { - if (bpos.indexOf(i) < 0) { - rcols.push(bcols[i]); - diffpos.push(i); - } - } - var difflen = diffpos.length; - - //debug("rcols :" + rcols); - //debug("diffpos :" + diffpos); - - var dummyhb = []; - for (i = 0; i < bcols.length; i++){ - dummyhb.push(null); - } - dummyhb = [dummyhb]; - - ka = apos; - kb = bpos; - - var hb = {}; - for (i = 0; i < tblen; i++) { - bele = bdata[i]; - key = ""; - for (j = 0; j < klen; j++) { - key += bele[kb[j]]; - key += ","; - } - if (hb[key] == null) hb[key] = []; - hb[key].push(bele); - //debug("bhash index :" + bid); - } - - //result data - var rdata = []; - - for (i = 0; i < talen; i++) { - aele = adata[i]; - //get the related b elements array - key = ""; - for (j = 0; j < klen; j++) { - key += aele[ka[j]]; - key += "," - } - //debug("ta.index : " + key); - hba = hb[key]; - //inspect(hba); - if(hba == null) hba = dummyhb; - //else bingo++; - for (j = 0; j < hba.length; j++) { - ele = [].concat(aele); - //ele = (aele); - bele = hba[j]; - for (k = 0; k < difflen; k++) { - ele.push(bele[diffpos[k]]); - } - rdata.push(ele); - } - } - return { - columns : rcols, - data : rdata - }; -} - -function innerJoin(ta ,tb, on){ - var ka = on.left; - var kb = on.right; - - var klen = kb.length; - var i, j, k; - - //hash b like that: - // kb1 : [ele1, ele2] - // kb2 : [el3, ele5]; - var adata = ta.data; - var bdata = tb.data; - var tblen = bdata.length; - var talen = adata.length; - - var ele; - var aele; - var bele; - var key; - var hba; - - var tbCol, found; - - var apos = []; - var acols = ta.columns; - for (i = 0; i < klen; i++) { - for (j = 0; j < acols.length; j++){ - found = false; - for (k = 0; k < acols[j].length; k++) { - tbCol = acols[j][k]; - if (tbCol.table == ka[i].table && tbCol.column == ka[i].column) { - apos.push(j) - found = true; - break; - } - } - if (found) break; - } - } - - var bpos = []; - var bcols = tb.columns; - for (i = 0; i < klen; i++) { - for (j = 0; j < bcols.length; j++) { - found = false; - for (k = 0; k < bcols[j].length; k++) { - tbCol = bcols[j][k]; - if (tbCol.table == kb[i].table && tbCol.column == kb[i].column) { - bpos.push(j) - found = true; - break; - } - } - if (found) break; - } - } - //console.log("bcols :" + bcols); - //console.log("bpos :" + bpos); - - //concat the join keys - var rcols = [].concat(acols); - for (i = 0; i < apos.length; i++) { - rcols[apos[i]] = rcols[apos[i]].concat(bcols[bpos[i]]); - } - - var diffpos = []; - for (i = 0; i < bcols.length; i++) { - if (bpos.indexOf(i) < 0) { - rcols.push(bcols[i]); - diffpos.push(i); - } - } - var difflen = diffpos.length; - - //debug("rcols :" + rcols); - //debug("diffpos :" + diffpos); - ka = apos; - kb = bpos; - - var hb = {}; - for (i = 0; i < tblen; i++) { - bele = bdata[i]; - key = ""; - for (j = 0; j < klen; j++){ - key += bele[kb[j]]; - key += ","; - } - if (hb[key] == null) hb[key] = []; - hb[key].push(bele); - //debug("bhash index :" + bid); - } - - //result data - var rdata = []; - - for (i = 0; i < talen; i++) { - aele = adata[i]; - //get the related b elements array - key = ""; - for (j = 0; j < klen; j++) { - key += aele[ka[j]]; - key += "," - } - //debug("ta.index : " + key); - hba = hb[key]; - if (hba) { - for (j = 0; j < hba.length; j++) { - bele = hba[j]; - ele = [].concat(aele); - for (k = 0; k < difflen; k++) { - ele.push(bele[diffpos[k]]); - } - rdata.push(ele); - } - } - } - return { - columns : rcols, - data : rdata - }; -} - diff --git a/base/limit.js b/base/limit.js deleted file mode 100644 index faccc8d..0000000 --- a/base/limit.js +++ /dev/null @@ -1,22 +0,0 @@ -// (C) 2011-2013 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - -module.exports = filter; -/** @param {Array} limit [2,0] or [] - [count, offset] - */ -function filter(dc, limits){ - var beg = limits[0]; - var end = beg + limits[1]; - - var dData = dc.data; - var rData = dData.slice(beg, end); - return { - columns : dc.columns, - data : rData - } -} diff --git a/base/mcache.js b/base/mcache.js deleted file mode 100644 index f573f20..0000000 --- a/base/mcache.js +++ /dev/null @@ -1,53 +0,0 @@ -// (C) 2011-2013 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - -function debug(str){ - //console.log(str); -} - -module.exports = Cache; - -function Cache(size) { - this.size = size || 1000; - this.stair = new Array(this.size); - this.pos = 0; - this.map = {}; -} - -Cache.prototype.get = function(key) { - var pb = this.map[key]; - if (pb) { - var pos = pb.pos; - if (pos > 0) { - var nkey = this.stair[pb.pos - 1]; - this.stair[pos] = nkey; - this.stair[pos - 1] = key; - } - pb = pb.body - } - return pb; -} - -Cache.prototype.set = function(key, value) { - //remove the last ono - if (this.pos >= this.size) { - var k = this.stair[this.size -1]; - this.map[k] = undefined; - this.pos = this.size -1; - } - this.map[key] = { - body : value, - pos : this.pos - } - this.stair[this.pos] = key; - return this.pos++; -} - -Cache.prototype.top = function(n) { - n = n || this.pos; - return this.stair.slice(0, n); -} diff --git a/base/nquery.js b/base/nquery.js deleted file mode 100644 index c427b06..0000000 --- a/base/nquery.js +++ /dev/null @@ -1,8513 +0,0 @@ -module.exports = (function(){ - /* - * Generated by PEG.js 0.7.0. - * - * http://pegjs.majda.cz/ - */ - - function quote(s) { - /* - * ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a - * string literal except for the closing quote character, backslash, - * carriage return, line separator, paragraph separator, and line feed. - * Any character may appear in the form of an escape sequence. - * - * For portability, we also escape escape all control and non-ASCII - * characters. Note that "\0" and "\v" escape sequences are not used - * because JSHint does not like the first and IE the second. - */ - return '"' + s - .replace(/\\/g, '\\\\') // backslash - .replace(/"/g, '\\"') // closing quote character - .replace(/\x08/g, '\\b') // backspace - .replace(/\t/g, '\\t') // horizontal tab - .replace(/\n/g, '\\n') // line feed - .replace(/\f/g, '\\f') // form feed - .replace(/\r/g, '\\r') // carriage return - .replace(/[\x00-\x07\x0B\x0E-\x1F\x80-\uFFFF]/g, escape) - + '"'; - } - - var result = { - /* - * Parses the input with a generated parser. If the parsing is successfull, - * returns a value explicitly or implicitly specified by the grammar from - * which the parser was generated (see |PEG.buildParser|). If the parsing is - * unsuccessful, throws |PEG.parser.SyntaxError| describing the error. - */ - parse: function(input, startRule) { - var parseFunctions = { - "start": parse_start, - "init": parse_init, - "union_stmt": parse_union_stmt, - "select_stmt": parse_select_stmt, - "select_stmt_nake": parse_select_stmt_nake, - "column_clause": parse_column_clause, - "column_list_item": parse_column_list_item, - "alias_clause": parse_alias_clause, - "from_clause": parse_from_clause, - "table_ref_list": parse_table_ref_list, - "table_ref": parse_table_ref, - "table_join": parse_table_join, - "table_base": parse_table_base, - "join_op": parse_join_op, - "table_name": parse_table_name, - "on_clause": parse_on_clause, - "where_clause": parse_where_clause, - "group_by_clause": parse_group_by_clause, - "column_ref_list": parse_column_ref_list, - "having_clause": parse_having_clause, - "order_by_clause": parse_order_by_clause, - "order_by_list": parse_order_by_list, - "order_by_element": parse_order_by_element, - "number_or_param": parse_number_or_param, - "limit_clause": parse_limit_clause, - "update_stmt": parse_update_stmt, - "set_list": parse_set_list, - "set_item": parse_set_item, - "replace_insert_stmt": parse_replace_insert_stmt, - "replace_insert": parse_replace_insert, - "value_clause": parse_value_clause, - "value_list": parse_value_list, - "value_item": parse_value_item, - "expr_list": parse_expr_list, - "expr_list_or_empty": parse_expr_list_or_empty, - "or_expr": parse_or_expr, - "and_expr": parse_and_expr, - "not_expr": parse_not_expr, - "comparison_expr": parse_comparison_expr, - "comparison_op_right": parse_comparison_op_right, - "arithmetic_op_right": parse_arithmetic_op_right, - "arithmetic_comparison_operator": parse_arithmetic_comparison_operator, - "is_op_right": parse_is_op_right, - "between_op_right": parse_between_op_right, - "like_op": parse_like_op, - "in_op": parse_in_op, - "contains_op": parse_contains_op, - "like_op_right": parse_like_op_right, - "in_op_right": parse_in_op_right, - "contains_op_right": parse_contains_op_right, - "additive_expr": parse_additive_expr, - "additive_operator": parse_additive_operator, - "multiplicative_expr": parse_multiplicative_expr, - "multiplicative_operator": parse_multiplicative_operator, - "primary": parse_primary, - "column_ref": parse_column_ref, - "column_list": parse_column_list, - "ident": parse_ident, - "column": parse_column, - "column_name": parse_column_name, - "ident_name": parse_ident_name, - "ident_start": parse_ident_start, - "ident_part": parse_ident_part, - "column_part": parse_column_part, - "param": parse_param, - "aggr_func": parse_aggr_func, - "aggr_fun_smma": parse_aggr_fun_smma, - "KW_SUM_MAX_MIN_AVG": parse_KW_SUM_MAX_MIN_AVG, - "aggr_fun_count": parse_aggr_fun_count, - "count_arg": parse_count_arg, - "star_expr": parse_star_expr, - "func_call": parse_func_call, - "literal": parse_literal, - "literal_list": parse_literal_list, - "literal_null": parse_literal_null, - "literal_bool": parse_literal_bool, - "literal_string": parse_literal_string, - "single_char": parse_single_char, - "double_char": parse_double_char, - "escape_char": parse_escape_char, - "line_terminator": parse_line_terminator, - "literal_numeric": parse_literal_numeric, - "number": parse_number, - "int": parse_int, - "frac": parse_frac, - "exp": parse_exp, - "digits": parse_digits, - "digit": parse_digit, - "digit19": parse_digit19, - "hexDigit": parse_hexDigit, - "e": parse_e, - "KW_NULL": parse_KW_NULL, - "KW_TRUE": parse_KW_TRUE, - "KW_FALSE": parse_KW_FALSE, - "KW_SHOW": parse_KW_SHOW, - "KW_DROP": parse_KW_DROP, - "KW_SELECT": parse_KW_SELECT, - "KW_UPDATE": parse_KW_UPDATE, - "KW_CREATE": parse_KW_CREATE, - "KW_DELETE": parse_KW_DELETE, - "KW_INSERT": parse_KW_INSERT, - "KW_REPLACE": parse_KW_REPLACE, - "KW_EXPLAIN": parse_KW_EXPLAIN, - "KW_INTO": parse_KW_INTO, - "KW_FROM": parse_KW_FROM, - "KW_SET": parse_KW_SET, - "KW_AS": parse_KW_AS, - "KW_TABLE": parse_KW_TABLE, - "KW_ON": parse_KW_ON, - "KW_LEFT": parse_KW_LEFT, - "KW_INNER": parse_KW_INNER, - "KW_JOIN": parse_KW_JOIN, - "KW_UNION": parse_KW_UNION, - "KW_VALUES": parse_KW_VALUES, - "KW_EXISTS": parse_KW_EXISTS, - "KW_WHERE": parse_KW_WHERE, - "KW_GROUP": parse_KW_GROUP, - "KW_BY": parse_KW_BY, - "KW_ORDER": parse_KW_ORDER, - "KW_HAVING": parse_KW_HAVING, - "KW_LIMIT": parse_KW_LIMIT, - "KW_ASC": parse_KW_ASC, - "KW_DESC": parse_KW_DESC, - "KW_ALL": parse_KW_ALL, - "KW_DISTINCT": parse_KW_DISTINCT, - "KW_BETWEEN": parse_KW_BETWEEN, - "KW_IN": parse_KW_IN, - "KW_IS": parse_KW_IS, - "KW_LIKE": parse_KW_LIKE, - "KW_CONTAINS": parse_KW_CONTAINS, - "KW_NOT": parse_KW_NOT, - "KW_AND": parse_KW_AND, - "KW_OR": parse_KW_OR, - "KW_COUNT": parse_KW_COUNT, - "KW_MAX": parse_KW_MAX, - "KW_MIN": parse_KW_MIN, - "KW_SUM": parse_KW_SUM, - "KW_AVG": parse_KW_AVG, - "DOT": parse_DOT, - "COMMA": parse_COMMA, - "STAR": parse_STAR, - "LPAREN": parse_LPAREN, - "RPAREN": parse_RPAREN, - "LBRAKE": parse_LBRAKE, - "RBRAKE": parse_RBRAKE, - "__": parse___, - "char": parse_char, - "whitespace": parse_whitespace, - "EOL": parse_EOL, - "EOF": parse_EOF, - "proc_stmts": parse_proc_stmts, - "proc_stmt": parse_proc_stmt, - "proc_init": parse_proc_init, - "assign_stmt": parse_assign_stmt, - "return_stmt": parse_return_stmt, - "proc_expr": parse_proc_expr, - "proc_additive_expr": parse_proc_additive_expr, - "proc_multiplicative_expr": parse_proc_multiplicative_expr, - "proc_join": parse_proc_join, - "proc_primary": parse_proc_primary, - "proc_func_call": parse_proc_func_call, - "proc_primary_list": parse_proc_primary_list, - "proc_array": parse_proc_array, - "var_decl": parse_var_decl, - "mem_chain": parse_mem_chain, - "KW_VAR_PRE": parse_KW_VAR_PRE, - "KW_RETURN": parse_KW_RETURN, - "KW_ASSIGN": parse_KW_ASSIGN - }; - - if (startRule !== undefined) { - if (parseFunctions[startRule] === undefined) { - throw new Error("Invalid rule name: " + quote(startRule) + "."); - } - } else { - startRule = "start"; - } - - var pos = 0; - var reportFailures = 0; - var rightmostFailuresPos = 0; - var rightmostFailuresExpected = []; - - function padLeft(input, padding, length) { - var result = input; - - var padLength = length - input.length; - for (var i = 0; i < padLength; i++) { - result = padding + result; - } - - return result; - } - - function escape(ch) { - var charCode = ch.charCodeAt(0); - var escapeChar; - var length; - - if (charCode <= 0xFF) { - escapeChar = 'x'; - length = 2; - } else { - escapeChar = 'u'; - length = 4; - } - - return '\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), '0', length); - } - - function matchFailed(failure) { - if (pos < rightmostFailuresPos) { - return; - } - - if (pos > rightmostFailuresPos) { - rightmostFailuresPos = pos; - rightmostFailuresExpected = []; - } - - rightmostFailuresExpected.push(failure); - } - - function parse_start() { - var result0, result1, result2; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - pos2 = pos; - reportFailures++; - result0 = parse_init(); - reportFailures--; - if (result0 !== null) { - result0 = ""; - pos = pos2; - } else { - result0 = null; - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_union_stmt(); - if (result2 === null) { - result2 = parse_update_stmt(); - if (result2 === null) { - result2 = parse_replace_insert_stmt(); - } - } - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, ast) { - return { - ast : ast, - param : params - } - })(pos0, result0[2]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - result0 = parse_proc_stmts(); - if (result0 !== null) { - result0 = (function(offset, ast) { - return { - ast : ast - } - })(pos0, result0); - } - if (result0 === null) { - pos = pos0; - } - } - return result0; - } - - function parse_init() { - var result0; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = []; - if (result0 !== null) { - result0 = (function(offset) { params = []; return true; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_union_stmt() { - var result0, result1, result2, result3, result4, result5; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - result0 = parse_select_stmt(); - if (result0 !== null) { - result1 = []; - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_KW_UNION(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_select_stmt(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - while (result2 !== null) { - result1.push(result2); - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_KW_UNION(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_select_stmt(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, head, tail) { - var cur = head; - for (var i = 0; i < tail.length; i++) { - cur._next = tail[i][3]; - cur = cur._next - } - return head; - })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_select_stmt() { - var result0, result1, result2, result3, result4; - var pos0, pos1; - - result0 = parse_select_stmt_nake(); - if (result0 === null) { - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 40) { - result0 = "("; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"(\""); - } - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_select_stmt(); - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - if (input.charCodeAt(pos) === 41) { - result4 = ")"; - pos++; - } else { - result4 = null; - if (reportFailures === 0) { - matchFailed("\")\""); - } - } - if (result4 !== null) { - result0 = [result0, result1, result2, result3, result4]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, s) { - return s[2]; - })(pos0, result0); - } - if (result0 === null) { - pos = pos0; - } - } - return result0; - } - - function parse_select_stmt_nake() { - var result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_KW_SELECT(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_KW_DISTINCT(); - result2 = result2 !== null ? result2 : ""; - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - result4 = parse_column_clause(); - if (result4 !== null) { - result5 = parse___(); - if (result5 !== null) { - result6 = parse_from_clause(); - result6 = result6 !== null ? result6 : ""; - if (result6 !== null) { - result7 = parse___(); - if (result7 !== null) { - result8 = parse_where_clause(); - result8 = result8 !== null ? result8 : ""; - if (result8 !== null) { - result9 = parse___(); - if (result9 !== null) { - result10 = parse_group_by_clause(); - result10 = result10 !== null ? result10 : ""; - if (result10 !== null) { - result11 = parse___(); - if (result11 !== null) { - result12 = parse_order_by_clause(); - result12 = result12 !== null ? result12 : ""; - if (result12 !== null) { - result13 = parse___(); - if (result13 !== null) { - result14 = parse_limit_clause(); - result14 = result14 !== null ? result14 : ""; - if (result14 !== null) { - result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, d, c, f, w, g, o, l) { - return { - type : 'select', - distinct : d, - columns : c, - from : f, - where : w, - groupby : g, - orderby : o, - limit : l - } - })(pos0, result0[2], result0[4], result0[6], result0[8], result0[10], result0[12], result0[14]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_column_clause() { - var result0, result1, result2, result3, result4, result5; - var pos0, pos1, pos2; - - pos0 = pos; - result0 = parse_KW_ALL(); - if (result0 === null) { - pos1 = pos; - result0 = parse_STAR(); - if (result0 !== null) { - pos2 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos2; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } - if (result0 !== null) { - result0 = (function(offset) { - return '*'; - })(pos0); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - pos1 = pos; - result0 = parse_column_list_item(); - if (result0 !== null) { - result1 = []; - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_COMMA(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_column_list_item(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - while (result2 !== null) { - result1.push(result2); - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_COMMA(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_column_list_item(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, head, tail) { - return createList(head, tail); - })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - } - return result0; - } - - function parse_column_list_item() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_additive_expr(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_alias_clause(); - result2 = result2 !== null ? result2 : ""; - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, e, alias) { - return { - expr : e, - as : alias - }; - })(pos0, result0[0], result0[2]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_alias_clause() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_KW_AS(); - result0 = result0 !== null ? result0 : ""; - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_ident(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, i) { return i; })(pos0, result0[2]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_from_clause() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_KW_FROM(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_table_ref_list(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, l) { return l; })(pos0, result0[2]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_table_ref_list() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_table_base(); - if (result0 !== null) { - result1 = []; - result2 = parse_table_ref(); - while (result2 !== null) { - result1.push(result2); - result2 = parse_table_ref(); - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, head, tail) { - tail.unshift(head); - return tail; - })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_table_ref() { - var result0, result1, result2, result3; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse___(); - if (result0 !== null) { - result1 = parse_COMMA(); - if (result1 !== null) { - result2 = parse___(); - if (result2 !== null) { - result3 = parse_table_base(); - if (result3 !== null) { - result0 = [result0, result1, result2, result3]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, t) { return t; })(pos0, result0[3]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - pos1 = pos; - result0 = parse___(); - if (result0 !== null) { - result1 = parse_table_join(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, t) { return t; })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - } - return result0; - } - - function parse_table_join() { - var result0, result1, result2, result3, result4; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_join_op(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_table_base(); - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - result4 = parse_on_clause(); - result4 = result4 !== null ? result4 : ""; - if (result4 !== null) { - result0 = [result0, result1, result2, result3, result4]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, op, t, expr) { - t.join = op; - t.on = expr; - return t; - /* - return { - db : t.db, - table : t.table, - as : t.as, - join : op, - on : expr - } - */ - })(pos0, result0[0], result0[2], result0[4]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_table_base() { - var result0, result1, result2, result3, result4; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_table_name(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_KW_AS(); - result2 = result2 !== null ? result2 : ""; - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - result4 = parse_ident(); - result4 = result4 !== null ? result4 : ""; - if (result4 !== null) { - result0 = [result0, result1, result2, result3, result4]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, t, alias) { - if (t.type == 'var') { - t.as = alias; - return t; - } else { - return { - db : t.db, - table : t.table, - as : alias - } - } - })(pos0, result0[0], result0[4]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_join_op() { - var result0, result1, result2; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - result0 = parse_KW_LEFT(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_KW_JOIN(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return 'LEFT JOIN'; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - pos1 = pos; - pos2 = pos; - result0 = parse_KW_INNER(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos2; - } - } else { - result0 = null; - pos = pos2; - } - result0 = result0 !== null ? result0 : ""; - if (result0 !== null) { - result1 = parse_KW_JOIN(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return 'INNER JOIN'; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - } - return result0; - } - - function parse_table_name() { - var result0, result1, result2, result3, result4; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - result0 = parse_ident(); - if (result0 !== null) { - pos2 = pos; - result1 = parse___(); - if (result1 !== null) { - result2 = parse_DOT(); - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - result4 = parse_ident_name(); - if (result4 !== null) { - result1 = [result1, result2, result3, result4]; - } else { - result1 = null; - pos = pos2; - } - } else { - result1 = null; - pos = pos2; - } - } else { - result1 = null; - pos = pos2; - } - } else { - result1 = null; - pos = pos2; - } - result1 = result1 !== null ? result1 : ""; - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, dt, tail) { - var obj = { - db : '', - table : dt - } - if (tail != '') { - obj.db = dt; - obj.table = tail[3]; - } - return obj; - })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - result0 = parse_var_decl(); - if (result0 !== null) { - result0 = (function(offset, v) { - v.db = ''; - v.table = v.name; - return v; - })(pos0, result0); - } - if (result0 === null) { - pos = pos0; - } - } - return result0; - } - - function parse_on_clause() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_KW_ON(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_or_expr(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, e) { return e; })(pos0, result0[2]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_where_clause() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_KW_WHERE(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_or_expr(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, e) { return e; })(pos0, result0[2]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_group_by_clause() { - var result0, result1, result2, result3, result4; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_KW_GROUP(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_KW_BY(); - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - result4 = parse_column_ref_list(); - if (result4 !== null) { - result0 = [result0, result1, result2, result3, result4]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, l) { return l; })(pos0, result0[4]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_column_ref_list() { - var result0, result1, result2, result3, result4, result5; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - result0 = parse_column_ref(); - if (result0 !== null) { - result1 = []; - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_COMMA(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_column_ref(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - while (result2 !== null) { - result1.push(result2); - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_COMMA(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_column_ref(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, head, tail) { - return createList(head, tail); - })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_having_clause() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_KW_HAVING(); - if (result0 !== null) { - result1 = parse_or_expr(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, e) { return e; })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_order_by_clause() { - var result0, result1, result2, result3, result4; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_KW_ORDER(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_KW_BY(); - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - result4 = parse_order_by_list(); - if (result4 !== null) { - result0 = [result0, result1, result2, result3, result4]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, l) { return l; })(pos0, result0[4]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_order_by_list() { - var result0, result1, result2, result3, result4, result5; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - result0 = parse_order_by_element(); - if (result0 !== null) { - result1 = []; - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_COMMA(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_order_by_element(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - while (result2 !== null) { - result1.push(result2); - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_COMMA(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_order_by_element(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, head, tail) { - return createList(head, tail); - })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_order_by_element() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_or_expr(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_KW_DESC(); - if (result2 === null) { - result2 = parse_KW_ASC(); - } - result2 = result2 !== null ? result2 : ""; - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, e, d) { - var obj = { - expr : e, - type : 'ASC' - } - if (d == 'DESC') { - obj.type = 'DESC'; - } - return obj; - })(pos0, result0[0], result0[2]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_number_or_param() { - var result0; - - result0 = parse_literal_numeric(); - if (result0 === null) { - result0 = parse_param(); - } - return result0; - } - - function parse_limit_clause() { - var result0, result1, result2, result3, result4, result5, result6; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - result0 = parse_KW_LIMIT(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_number_or_param(); - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - pos2 = pos; - result4 = parse_COMMA(); - if (result4 !== null) { - result5 = parse___(); - if (result5 !== null) { - result6 = parse_number_or_param(); - if (result6 !== null) { - result4 = [result4, result5, result6]; - } else { - result4 = null; - pos = pos2; - } - } else { - result4 = null; - pos = pos2; - } - } else { - result4 = null; - pos = pos2; - } - result4 = result4 !== null ? result4 : ""; - if (result4 !== null) { - result0 = [result0, result1, result2, result3, result4]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, i1, tail) { - var res = [i1]; - if (tail == '') { - res.unshift({ - type : 'number', - value : 0 - }); - } else { - res.push(tail[2]); - } - return res; - })(pos0, result0[2], result0[4]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_update_stmt() { - var result0, result1, result2, result3, result4, result5, result6, result7, result8; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_KW_UPDATE(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_table_name(); - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - result4 = parse_KW_SET(); - if (result4 !== null) { - result5 = parse___(); - if (result5 !== null) { - result6 = parse_set_list(); - if (result6 !== null) { - result7 = parse___(); - if (result7 !== null) { - result8 = parse_where_clause(); - if (result8 !== null) { - result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, t, l, w) { - return { - type : 'update', - db : t.db, - table : t.table, - set : l, - where : w - } - })(pos0, result0[2], result0[6], result0[8]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_set_list() { - var result0, result1, result2, result3, result4, result5; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - result0 = parse_set_item(); - if (result0 !== null) { - result1 = []; - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_COMMA(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_set_item(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - while (result2 !== null) { - result1.push(result2); - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_COMMA(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_set_item(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, head, tail) { - return createList(head, tail); - })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_set_item() { - var result0, result1, result2, result3, result4; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_column_name(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - if (input.charCodeAt(pos) === 61) { - result2 = "="; - pos++; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("\"=\""); - } - } - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - result4 = parse_additive_expr(); - if (result4 !== null) { - result0 = [result0, result1, result2, result3, result4]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, c, v) { - return { - column: c, - value : v - } - })(pos0, result0[0], result0[4]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_replace_insert_stmt() { - var result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_replace_insert(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_KW_INTO(); - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - result4 = parse_table_name(); - if (result4 !== null) { - result5 = parse___(); - if (result5 !== null) { - result6 = parse_LPAREN(); - if (result6 !== null) { - result7 = parse___(); - if (result7 !== null) { - result8 = parse_column_list(); - if (result8 !== null) { - result9 = parse___(); - if (result9 !== null) { - result10 = parse_RPAREN(); - if (result10 !== null) { - result11 = parse___(); - if (result11 !== null) { - result12 = parse_value_clause(); - if (result12 !== null) { - result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, ri, t, c, v) { - return { - type : ri, - db : t.db, - table : t.table, - columns : c, - values : v - } - })(pos0, result0[0], result0[4], result0[8], result0[12]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_replace_insert() { - var result0; - var pos0; - - pos0 = pos; - result0 = parse_KW_INSERT(); - if (result0 !== null) { - result0 = (function(offset) { return 'insert'; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - result0 = parse_KW_REPLACE(); - if (result0 !== null) { - result0 = (function(offset) { return 'replace' })(pos0); - } - if (result0 === null) { - pos = pos0; - } - } - return result0; - } - - function parse_value_clause() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_KW_VALUES(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_value_list(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, l) { return l; })(pos0, result0[2]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_value_list() { - var result0, result1, result2, result3, result4, result5; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - result0 = parse_value_item(); - if (result0 !== null) { - result1 = []; - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_COMMA(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_value_item(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - while (result2 !== null) { - result1.push(result2); - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_COMMA(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_value_item(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, head, tail) { - return createList(head, tail); - })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_value_item() { - var result0, result1, result2, result3, result4; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_LPAREN(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_expr_list(); - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - result4 = parse_RPAREN(); - if (result4 !== null) { - result0 = [result0, result1, result2, result3, result4]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, l) { - return l; - })(pos0, result0[2]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_expr_list() { - var result0, result1, result2, result3, result4, result5; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - result0 = parse_or_expr(); - if (result0 !== null) { - result1 = []; - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_COMMA(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_or_expr(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - while (result2 !== null) { - result1.push(result2); - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_COMMA(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_or_expr(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, head, tail) { - var el = { - type : 'expr_list' - } - var l = createExprList(head, tail, el); - - el.value = l; - return el; - })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_expr_list_or_empty() { - var result0; - var pos0, pos1; - - result0 = parse_expr_list(); - if (result0 === null) { - pos0 = pos; - pos1 = pos; - result0 = []; - if (result0 !== null) { - result0 = (function(offset) { - return { - type : 'expr_list', - value : [] - } - })(pos0); - } - if (result0 === null) { - pos = pos0; - } - } - return result0; - } - - function parse_or_expr() { - var result0, result1, result2, result3, result4, result5; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - result0 = parse_and_expr(); - if (result0 !== null) { - result1 = []; - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_KW_OR(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_and_expr(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - while (result2 !== null) { - result1.push(result2); - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_KW_OR(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_and_expr(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, head, tail) { - return createBinaryExprChain(head, tail); - })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_and_expr() { - var result0, result1, result2, result3, result4, result5; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - result0 = parse_not_expr(); - if (result0 !== null) { - result1 = []; - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_KW_AND(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_not_expr(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - while (result2 !== null) { - result1.push(result2); - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_KW_AND(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_not_expr(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, head, tail) { - return createBinaryExprChain(head, tail); - })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_not_expr() { - var result0, result1, result2; - var pos0, pos1, pos2, pos3; - - pos0 = pos; - pos1 = pos; - result0 = parse_KW_NOT(); - if (result0 === null) { - pos2 = pos; - if (input.charCodeAt(pos) === 33) { - result0 = "!"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"!\""); - } - } - if (result0 !== null) { - pos3 = pos; - reportFailures++; - if (input.charCodeAt(pos) === 61) { - result1 = "="; - pos++; - } else { - result1 = null; - if (reportFailures === 0) { - matchFailed("\"=\""); - } - } - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos3; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos2; - } - } else { - result0 = null; - pos = pos2; - } - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_not_expr(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, expr) { - return createUnaryExpr('NOT', expr); - })(pos0, result0[2]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - result0 = parse_comparison_expr(); - } - return result0; - } - - function parse_comparison_expr() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_additive_expr(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_comparison_op_right(); - result2 = result2 !== null ? result2 : ""; - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, left, rh) { - if (rh == '') { - return left; - } else { - var res = null; - if (rh.type == 'arithmetic') { - res = createBinaryExprChain(left, rh.tail); - } else { - res = createBinaryExpr(rh.op, left, rh.right); - } - return res; - } - })(pos0, result0[0], result0[2]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_comparison_op_right() { - var result0; - - result0 = parse_arithmetic_op_right(); - if (result0 === null) { - result0 = parse_in_op_right(); - if (result0 === null) { - result0 = parse_between_op_right(); - if (result0 === null) { - result0 = parse_is_op_right(); - if (result0 === null) { - result0 = parse_like_op_right(); - if (result0 === null) { - result0 = parse_contains_op_right(); - } - } - } - } - } - return result0; - } - - function parse_arithmetic_op_right() { - var result0, result1, result2, result3, result4; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result1 = parse___(); - if (result1 !== null) { - result2 = parse_arithmetic_comparison_operator(); - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - result4 = parse_additive_expr(); - if (result4 !== null) { - result1 = [result1, result2, result3, result4]; - } else { - result1 = null; - pos = pos1; - } - } else { - result1 = null; - pos = pos1; - } - } else { - result1 = null; - pos = pos1; - } - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = []; - while (result1 !== null) { - result0.push(result1); - pos1 = pos; - result1 = parse___(); - if (result1 !== null) { - result2 = parse_arithmetic_comparison_operator(); - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - result4 = parse_additive_expr(); - if (result4 !== null) { - result1 = [result1, result2, result3, result4]; - } else { - result1 = null; - pos = pos1; - } - } else { - result1 = null; - pos = pos1; - } - } else { - result1 = null; - pos = pos1; - } - } else { - result1 = null; - pos = pos1; - } - } - } else { - result0 = null; - } - if (result0 !== null) { - result0 = (function(offset, l) { - return { - type : 'arithmetic', - tail : l - } - })(pos0, result0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_arithmetic_comparison_operator() { - var result0; - - if (input.substr(pos, 2) === ">=") { - result0 = ">="; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\">=\""); - } - } - if (result0 === null) { - if (input.charCodeAt(pos) === 62) { - result0 = ">"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\">\""); - } - } - if (result0 === null) { - if (input.substr(pos, 2) === "<=") { - result0 = "<="; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"<=\""); - } - } - if (result0 === null) { - if (input.substr(pos, 2) === "<>") { - result0 = "<>"; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"<>\""); - } - } - if (result0 === null) { - if (input.charCodeAt(pos) === 60) { - result0 = "<"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"<\""); - } - } - if (result0 === null) { - if (input.charCodeAt(pos) === 61) { - result0 = "="; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"=\""); - } - } - if (result0 === null) { - if (input.substr(pos, 2) === "!=") { - result0 = "!="; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"!=\""); - } - } - } - } - } - } - } - } - return result0; - } - - function parse_is_op_right() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_KW_IS(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_additive_expr(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, op, right) { - return { - op : op, - right : right - } - })(pos0, result0[0], result0[2]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_between_op_right() { - var result0, result1, result2, result3, result4, result5, result6; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_KW_BETWEEN(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_additive_expr(); - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - result4 = parse_KW_AND(); - if (result4 !== null) { - result5 = parse___(); - if (result5 !== null) { - result6 = parse_additive_expr(); - if (result6 !== null) { - result0 = [result0, result1, result2, result3, result4, result5, result6]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, op, begin, end) { - return { - op : op, - right : { - type : 'expr_list', - value : [begin, end] - } - } - })(pos0, result0[0], result0[2], result0[6]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_like_op() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_KW_NOT(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_KW_LIKE(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, nk) { return nk[0] + ' ' + nk[2]; })(pos0, result0); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - result0 = parse_KW_LIKE(); - } - return result0; - } - - function parse_in_op() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_KW_NOT(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_KW_IN(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, nk) { return nk[0] + ' ' + nk[2]; })(pos0, result0); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - result0 = parse_KW_IN(); - } - return result0; - } - - function parse_contains_op() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_KW_NOT(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_KW_CONTAINS(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, nk) { return nk[0] + ' ' + nk[2]; })(pos0, result0); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - result0 = parse_KW_CONTAINS(); - } - return result0; - } - - function parse_like_op_right() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_like_op(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_comparison_expr(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, op, right) { - return { - op : op, - right : right - } - })(pos0, result0[0], result0[2]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_in_op_right() { - var result0, result1, result2, result3, result4, result5, result6; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_in_op(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_LPAREN(); - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - result4 = parse_expr_list(); - if (result4 !== null) { - result5 = parse___(); - if (result5 !== null) { - result6 = parse_RPAREN(); - if (result6 !== null) { - result0 = [result0, result1, result2, result3, result4, result5, result6]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, op, l) { - return { - op : op, - right : l - } - })(pos0, result0[0], result0[4]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - pos1 = pos; - result0 = parse_in_op(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_var_decl(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, op, e) { - return { - op : op, - right : e - } - })(pos0, result0[0], result0[2]); - } - if (result0 === null) { - pos = pos0; - } - } - return result0; - } - - function parse_contains_op_right() { - var result0, result1, result2, result3, result4, result5, result6; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_contains_op(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_LPAREN(); - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - result4 = parse_expr_list(); - if (result4 !== null) { - result5 = parse___(); - if (result5 !== null) { - result6 = parse_RPAREN(); - if (result6 !== null) { - result0 = [result0, result1, result2, result3, result4, result5, result6]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, op, l) { - return { - op : op, - right : l - } - })(pos0, result0[0], result0[4]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - pos1 = pos; - result0 = parse_contains_op(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_var_decl(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, op, e) { - return { - op : op, - right : e - } - })(pos0, result0[0], result0[2]); - } - if (result0 === null) { - pos = pos0; - } - } - return result0; - } - - function parse_additive_expr() { - var result0, result1, result2, result3, result4, result5; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - result0 = parse_multiplicative_expr(); - if (result0 !== null) { - result1 = []; - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_additive_operator(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_multiplicative_expr(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - while (result2 !== null) { - result1.push(result2); - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_additive_operator(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_multiplicative_expr(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, head, tail) { - return createBinaryExprChain(head, tail); - })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_additive_operator() { - var result0; - - if (input.charCodeAt(pos) === 43) { - result0 = "+"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"+\""); - } - } - if (result0 === null) { - if (input.charCodeAt(pos) === 45) { - result0 = "-"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"-\""); - } - } - } - return result0; - } - - function parse_multiplicative_expr() { - var result0, result1, result2, result3, result4, result5; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - result0 = parse_primary(); - if (result0 !== null) { - result1 = []; - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_multiplicative_operator(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_primary(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - while (result2 !== null) { - result1.push(result2); - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_multiplicative_operator(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_primary(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, head, tail) { - return createBinaryExprChain(head, tail) - })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_multiplicative_operator() { - var result0; - - if (input.charCodeAt(pos) === 42) { - result0 = "*"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"*\""); - } - } - if (result0 === null) { - if (input.charCodeAt(pos) === 47) { - result0 = "/"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"/\""); - } - } - if (result0 === null) { - if (input.charCodeAt(pos) === 37) { - result0 = "%"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"%\""); - } - } - } - } - return result0; - } - - function parse_primary() { - var result0, result1, result2, result3, result4; - var pos0, pos1; - - result0 = parse_literal(); - if (result0 === null) { - result0 = parse_aggr_func(); - if (result0 === null) { - result0 = parse_func_call(); - if (result0 === null) { - result0 = parse_column_ref(); - if (result0 === null) { - result0 = parse_param(); - if (result0 === null) { - pos0 = pos; - pos1 = pos; - result0 = parse_LPAREN(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_or_expr(); - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - result4 = parse_RPAREN(); - if (result4 !== null) { - result0 = [result0, result1, result2, result3, result4]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, e) { - e.paren = true; - return e; - })(pos0, result0[2]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - result0 = parse_var_decl(); - } - } - } - } - } - } - return result0; - } - - function parse_column_ref() { - var result0, result1, result2, result3, result4; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_ident(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_DOT(); - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - result4 = parse_column(); - if (result4 !== null) { - result0 = [result0, result1, result2, result3, result4]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, tbl, col) { - return { - type : 'column_ref', - table : tbl, - column : col - }; - })(pos0, result0[0], result0[4]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - result0 = parse_column(); - if (result0 !== null) { - result0 = (function(offset, col) { - return { - type : 'column_ref', - table : '', - column: col - }; - })(pos0, result0); - } - if (result0 === null) { - pos = pos0; - } - } - return result0; - } - - function parse_column_list() { - var result0, result1, result2, result3, result4, result5; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - result0 = parse_column(); - if (result0 !== null) { - result1 = []; - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_COMMA(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_column(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - while (result2 !== null) { - result1.push(result2); - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_COMMA(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_column(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, head, tail) { - return createList(head, tail); - })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_ident() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_ident_name(); - if (result0 !== null) { - result1 = (function(offset, name) { return reservedMap[name.toUpperCase()] === true; })(pos, result0) ? null : ""; - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, name) { - return name; - })(pos0, result0[0]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_column() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_column_name(); - if (result0 !== null) { - result1 = (function(offset, name) { return reservedMap[name.toUpperCase()] === true; })(pos, result0) ? null : ""; - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, name) { - return name; - })(pos0, result0[0]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 96) { - result0 = "`"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"`\""); - } - } - if (result0 !== null) { - if (/^[^`]/.test(input.charAt(pos))) { - result2 = input.charAt(pos); - pos++; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("[^`]"); - } - } - if (result2 !== null) { - result1 = []; - while (result2 !== null) { - result1.push(result2); - if (/^[^`]/.test(input.charAt(pos))) { - result2 = input.charAt(pos); - pos++; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("[^`]"); - } - } - } - } else { - result1 = null; - } - if (result1 !== null) { - if (input.charCodeAt(pos) === 96) { - result2 = "`"; - pos++; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("\"`\""); - } - } - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, chars) { - return chars.join(''); - })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - } - return result0; - } - - function parse_column_name() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_ident_start(); - if (result0 !== null) { - result1 = []; - result2 = parse_column_part(); - while (result2 !== null) { - result1.push(result2); - result2 = parse_column_part(); - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, start, parts) { return start + parts.join(''); })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_ident_name() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_ident_start(); - if (result0 !== null) { - result1 = []; - result2 = parse_ident_part(); - while (result2 !== null) { - result1.push(result2); - result2 = parse_ident_part(); - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, start, parts) { return start + parts.join(''); })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_ident_start() { - var result0; - - if (/^[A-Za-z_]/.test(input.charAt(pos))) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("[A-Za-z_]"); - } - } - return result0; - } - - function parse_ident_part() { - var result0; - - if (/^[A-Za-z0-9_]/.test(input.charAt(pos))) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("[A-Za-z0-9_]"); - } - } - return result0; - } - - function parse_column_part() { - var result0; - - if (/^[A-Za-z0-9_:]/.test(input.charAt(pos))) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("[A-Za-z0-9_:]"); - } - } - return result0; - } - - function parse_param() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 58) { - result0 = ":"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\":\""); - } - } - if (result0 !== null) { - result1 = parse_ident_name(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, l) { - var p = { - type : 'param', - value: l[1] - } - //var key = 'L' + line + 'C' + column; - //debug(key); - //params[key] = p; - params.push(p); - return p; - })(pos0, result0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_aggr_func() { - var result0; - - result0 = parse_aggr_fun_count(); - if (result0 === null) { - result0 = parse_aggr_fun_smma(); - } - return result0; - } - - function parse_aggr_fun_smma() { - var result0, result1, result2, result3, result4, result5, result6; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_KW_SUM_MAX_MIN_AVG(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_LPAREN(); - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - result4 = parse_additive_expr(); - if (result4 !== null) { - result5 = parse___(); - if (result5 !== null) { - result6 = parse_RPAREN(); - if (result6 !== null) { - result0 = [result0, result1, result2, result3, result4, result5, result6]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, name, e) { - return { - type : 'aggr_func', - name : name, - args : { - expr : e - } - } - })(pos0, result0[0], result0[4]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_KW_SUM_MAX_MIN_AVG() { - var result0; - - result0 = parse_KW_SUM(); - if (result0 === null) { - result0 = parse_KW_MAX(); - if (result0 === null) { - result0 = parse_KW_MIN(); - if (result0 === null) { - result0 = parse_KW_AVG(); - } - } - } - return result0; - } - - function parse_aggr_fun_count() { - var result0, result1, result2, result3, result4, result5, result6; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_KW_COUNT(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_LPAREN(); - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - result4 = parse_count_arg(); - if (result4 !== null) { - result5 = parse___(); - if (result5 !== null) { - result6 = parse_RPAREN(); - if (result6 !== null) { - result0 = [result0, result1, result2, result3, result4, result5, result6]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, name, arg) { - return { - type : 'aggr_func', - name : name, - args : arg - } - })(pos0, result0[0], result0[4]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_count_arg() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - result0 = parse_star_expr(); - if (result0 !== null) { - result0 = (function(offset, e) { - return { - expr : e - } - })(pos0, result0); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - pos1 = pos; - result0 = parse_KW_DISTINCT(); - result0 = result0 !== null ? result0 : ""; - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_column_ref(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, d, c) { - return { - distinct : d, - expr : c - } - })(pos0, result0[0], result0[2]); - } - if (result0 === null) { - pos = pos0; - } - } - return result0; - } - - function parse_star_expr() { - var result0; - var pos0; - - pos0 = pos; - if (input.charCodeAt(pos) === 42) { - result0 = "*"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"*\""); - } - } - if (result0 !== null) { - result0 = (function(offset) { - return { - type : 'star', - value : '*' - } - })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_func_call() { - var result0, result1, result2, result3, result4, result5, result6; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_ident(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_LPAREN(); - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - result4 = parse_expr_list_or_empty(); - if (result4 !== null) { - result5 = parse___(); - if (result5 !== null) { - result6 = parse_RPAREN(); - if (result6 !== null) { - result0 = [result0, result1, result2, result3, result4, result5, result6]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, name, l) { - return { - type : 'function', - name : name, - args : l - } - })(pos0, result0[0], result0[4]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_literal() { - var result0; - - result0 = parse_literal_string(); - if (result0 === null) { - result0 = parse_literal_numeric(); - if (result0 === null) { - result0 = parse_literal_bool(); - if (result0 === null) { - result0 = parse_literal_null(); - } - } - } - return result0; - } - - function parse_literal_list() { - var result0, result1, result2, result3, result4, result5; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - result0 = parse_literal(); - if (result0 !== null) { - result1 = []; - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_COMMA(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_literal(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - while (result2 !== null) { - result1.push(result2); - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_COMMA(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_literal(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, head, tail) { - return createList(head, tail); - })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_literal_null() { - var result0; - var pos0; - - pos0 = pos; - result0 = parse_KW_NULL(); - if (result0 !== null) { - result0 = (function(offset) { - return { - type : 'null', - value : null - }; - })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_literal_bool() { - var result0; - var pos0; - - pos0 = pos; - result0 = parse_KW_TRUE(); - if (result0 !== null) { - result0 = (function(offset) { - return { - type : 'bool', - value : true - }; - })(pos0); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - result0 = parse_KW_FALSE(); - if (result0 !== null) { - result0 = (function(offset) { - return { - type : 'bool', - value : false - }; - })(pos0); - } - if (result0 === null) { - pos = pos0; - } - } - return result0; - } - - function parse_literal_string() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 34) { - result0 = "\""; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\"\""); - } - } - if (result0 !== null) { - result1 = []; - result2 = parse_double_char(); - while (result2 !== null) { - result1.push(result2); - result2 = parse_double_char(); - } - if (result1 !== null) { - if (input.charCodeAt(pos) === 34) { - result2 = "\""; - pos++; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("\"\\\"\""); - } - } - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 === null) { - pos1 = pos; - if (input.charCodeAt(pos) === 39) { - result0 = "'"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"'\""); - } - } - if (result0 !== null) { - result1 = []; - result2 = parse_single_char(); - while (result2 !== null) { - result1.push(result2); - result2 = parse_single_char(); - } - if (result1 !== null) { - if (input.charCodeAt(pos) === 39) { - result2 = "'"; - pos++; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("\"'\""); - } - } - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } - if (result0 !== null) { - result0 = (function(offset, ca) { - return { - type : 'string', - value : ca[1].join('') - } - })(pos0, result0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_single_char() { - var result0; - - if (/^[^'\\\0-\x1F]/.test(input.charAt(pos))) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("[^'\\\\\\0-\\x1F]"); - } - } - if (result0 === null) { - result0 = parse_escape_char(); - } - return result0; - } - - function parse_double_char() { - var result0; - - if (/^[^"\\\0-\x1F]/.test(input.charAt(pos))) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("[^\"\\\\\\0-\\x1F]"); - } - } - if (result0 === null) { - result0 = parse_escape_char(); - } - return result0; - } - - function parse_escape_char() { - var result0, result1, result2, result3, result4; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 2) === "\\'") { - result0 = "\\'"; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\\'\""); - } - } - if (result0 !== null) { - result0 = (function(offset) { return "'"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - if (input.substr(pos, 2) === "\\\"") { - result0 = "\\\""; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\\\\\"\""); - } - } - if (result0 !== null) { - result0 = (function(offset) { return '"'; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - if (input.substr(pos, 2) === "\\\\") { - result0 = "\\\\"; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\\\\\\\""); - } - } - if (result0 !== null) { - result0 = (function(offset) { return "\\"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - if (input.substr(pos, 2) === "\\/") { - result0 = "\\/"; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\\/\""); - } - } - if (result0 !== null) { - result0 = (function(offset) { return "/"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - if (input.substr(pos, 2) === "\\b") { - result0 = "\\b"; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\\b\""); - } - } - if (result0 !== null) { - result0 = (function(offset) { return "\b"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - if (input.substr(pos, 2) === "\\f") { - result0 = "\\f"; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\\f\""); - } - } - if (result0 !== null) { - result0 = (function(offset) { return "\f"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - if (input.substr(pos, 2) === "\\n") { - result0 = "\\n"; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\\n\""); - } - } - if (result0 !== null) { - result0 = (function(offset) { return "\n"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - if (input.substr(pos, 2) === "\\r") { - result0 = "\\r"; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\\r\""); - } - } - if (result0 !== null) { - result0 = (function(offset) { return "\r"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - if (input.substr(pos, 2) === "\\t") { - result0 = "\\t"; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\\t\""); - } - } - if (result0 !== null) { - result0 = (function(offset) { return "\t"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - pos1 = pos; - if (input.substr(pos, 2) === "\\u") { - result0 = "\\u"; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\\u\""); - } - } - if (result0 !== null) { - result1 = parse_hexDigit(); - if (result1 !== null) { - result2 = parse_hexDigit(); - if (result2 !== null) { - result3 = parse_hexDigit(); - if (result3 !== null) { - result4 = parse_hexDigit(); - if (result4 !== null) { - result0 = [result0, result1, result2, result3, result4]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, h1, h2, h3, h4) { - return String.fromCharCode(parseInt("0x" + h1 + h2 + h3 + h4)); - })(pos0, result0[1], result0[2], result0[3], result0[4]); - } - if (result0 === null) { - pos = pos0; - } - } - } - } - } - } - } - } - } - } - return result0; - } - - function parse_line_terminator() { - var result0; - - if (/^[\n\r]/.test(input.charAt(pos))) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("[\\n\\r]"); - } - } - return result0; - } - - function parse_literal_numeric() { - var result0; - var pos0; - - pos0 = pos; - result0 = parse_number(); - if (result0 !== null) { - result0 = (function(offset, n) { - return { - type : 'number', - value : n - } - })(pos0, result0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_number() { - var result0, result1, result2, result3; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_int(); - if (result0 !== null) { - result1 = parse_frac(); - if (result1 !== null) { - result2 = parse_exp(); - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - result0 = [result0, result1, result2, result3]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, int_, frac, exp) { return parseFloat(int_ + frac + exp); })(pos0, result0[0], result0[1], result0[2]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - pos1 = pos; - result0 = parse_int(); - if (result0 !== null) { - result1 = parse_frac(); - if (result1 !== null) { - result2 = parse___(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, int_, frac) { return parseFloat(int_ + frac); })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - pos1 = pos; - result0 = parse_int(); - if (result0 !== null) { - result1 = parse_exp(); - if (result1 !== null) { - result2 = parse___(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, int_, exp) { return parseFloat(int_ + exp); })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - pos1 = pos; - result0 = parse_int(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, int_) { return parseFloat(int_); })(pos0, result0[0]); - } - if (result0 === null) { - pos = pos0; - } - } - } - } - return result0; - } - - function parse_int() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_digit19(); - if (result0 !== null) { - result1 = parse_digits(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, digit19, digits) { return digit19 + digits; })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - result0 = parse_digit(); - if (result0 === null) { - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 45) { - result0 = "-"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"-\""); - } - } - if (result0 === null) { - if (input.charCodeAt(pos) === 43) { - result0 = "+"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"+\""); - } - } - } - if (result0 !== null) { - result1 = parse_digit19(); - if (result1 !== null) { - result2 = parse_digits(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, op, digit19, digits) { return "-" + digit19 + digits; })(pos0, result0[0], result0[1], result0[2]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 45) { - result0 = "-"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"-\""); - } - } - if (result0 === null) { - if (input.charCodeAt(pos) === 43) { - result0 = "+"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"+\""); - } - } - } - if (result0 !== null) { - result1 = parse_digit(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, op, digit) { return "-" + digit; })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - } - } - } - return result0; - } - - function parse_frac() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 46) { - result0 = "."; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\".\""); - } - } - if (result0 !== null) { - result1 = parse_digits(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, digits) { return "." + digits; })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_exp() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_e(); - if (result0 !== null) { - result1 = parse_digits(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, e, digits) { return e + digits; })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_digits() { - var result0, result1; - var pos0; - - pos0 = pos; - result1 = parse_digit(); - if (result1 !== null) { - result0 = []; - while (result1 !== null) { - result0.push(result1); - result1 = parse_digit(); - } - } else { - result0 = null; - } - if (result0 !== null) { - result0 = (function(offset, digits) { return digits.join(""); })(pos0, result0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_digit() { - var result0; - - if (/^[0-9]/.test(input.charAt(pos))) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("[0-9]"); - } - } - return result0; - } - - function parse_digit19() { - var result0; - - if (/^[1-9]/.test(input.charAt(pos))) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("[1-9]"); - } - } - return result0; - } - - function parse_hexDigit() { - var result0; - - if (/^[0-9a-fA-F]/.test(input.charAt(pos))) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("[0-9a-fA-F]"); - } - } - return result0; - } - - function parse_e() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (/^[eE]/.test(input.charAt(pos))) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("[eE]"); - } - } - if (result0 !== null) { - if (/^[+\-]/.test(input.charAt(pos))) { - result1 = input.charAt(pos); - pos++; - } else { - result1 = null; - if (reportFailures === 0) { - matchFailed("[+\\-]"); - } - } - result1 = result1 !== null ? result1 : ""; - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, e, sign) { return e + sign; })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_KW_NULL() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 4).toLowerCase() === "null") { - result0 = input.substr(pos, 4); - pos += 4; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"NULL\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_TRUE() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 4).toLowerCase() === "true") { - result0 = input.substr(pos, 4); - pos += 4; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"TRUE\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_FALSE() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 5).toLowerCase() === "false") { - result0 = input.substr(pos, 5); - pos += 5; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"FALSE\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_SHOW() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 4).toLowerCase() === "show") { - result0 = input.substr(pos, 4); - pos += 4; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"SHOW\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_DROP() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 4).toLowerCase() === "drop") { - result0 = input.substr(pos, 4); - pos += 4; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"DROP\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_SELECT() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 6).toLowerCase() === "select") { - result0 = input.substr(pos, 6); - pos += 6; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"SELECT\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_UPDATE() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 6).toLowerCase() === "update") { - result0 = input.substr(pos, 6); - pos += 6; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"UPDATE\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_CREATE() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 6).toLowerCase() === "create") { - result0 = input.substr(pos, 6); - pos += 6; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"CREATE\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_DELETE() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 6).toLowerCase() === "delete") { - result0 = input.substr(pos, 6); - pos += 6; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"DELETE\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_INSERT() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 6).toLowerCase() === "insert") { - result0 = input.substr(pos, 6); - pos += 6; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"INSERT\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_REPLACE() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 7).toLowerCase() === "replace") { - result0 = input.substr(pos, 7); - pos += 7; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"REPLACE\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_EXPLAIN() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 7).toLowerCase() === "explain") { - result0 = input.substr(pos, 7); - pos += 7; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"EXPLAIN\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_INTO() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 4).toLowerCase() === "into") { - result0 = input.substr(pos, 4); - pos += 4; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"INTO\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_FROM() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 4).toLowerCase() === "from") { - result0 = input.substr(pos, 4); - pos += 4; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"FROM\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_SET() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 3).toLowerCase() === "set") { - result0 = input.substr(pos, 3); - pos += 3; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"SET\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_AS() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 2).toLowerCase() === "as") { - result0 = input.substr(pos, 2); - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"AS\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_TABLE() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 5).toLowerCase() === "table") { - result0 = input.substr(pos, 5); - pos += 5; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"TABLE\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_ON() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 2).toLowerCase() === "on") { - result0 = input.substr(pos, 2); - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"ON\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_LEFT() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 4).toLowerCase() === "left") { - result0 = input.substr(pos, 4); - pos += 4; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"LEFT\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_INNER() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 5).toLowerCase() === "inner") { - result0 = input.substr(pos, 5); - pos += 5; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"INNER\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_JOIN() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 4).toLowerCase() === "join") { - result0 = input.substr(pos, 4); - pos += 4; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"JOIN\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_UNION() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 5).toLowerCase() === "union") { - result0 = input.substr(pos, 5); - pos += 5; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"UNION\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_VALUES() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 6).toLowerCase() === "values") { - result0 = input.substr(pos, 6); - pos += 6; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"VALUES\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_EXISTS() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 6).toLowerCase() === "exists") { - result0 = input.substr(pos, 6); - pos += 6; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"EXISTS\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_WHERE() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 5).toLowerCase() === "where") { - result0 = input.substr(pos, 5); - pos += 5; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"WHERE\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_GROUP() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 5).toLowerCase() === "group") { - result0 = input.substr(pos, 5); - pos += 5; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"GROUP\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_BY() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 2).toLowerCase() === "by") { - result0 = input.substr(pos, 2); - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"BY\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_ORDER() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 5).toLowerCase() === "order") { - result0 = input.substr(pos, 5); - pos += 5; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"ORDER\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_HAVING() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 6).toLowerCase() === "having") { - result0 = input.substr(pos, 6); - pos += 6; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"HAVING\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_LIMIT() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - if (input.substr(pos, 5).toLowerCase() === "limit") { - result0 = input.substr(pos, 5); - pos += 5; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"LIMIT\""); - } - } - if (result0 !== null) { - pos1 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos1; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_KW_ASC() { - var result0, result1; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - if (input.substr(pos, 3).toLowerCase() === "asc") { - result0 = input.substr(pos, 3); - pos += 3; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"ASC\""); - } - } - if (result0 !== null) { - pos2 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos2; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return 'ASC'; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_KW_DESC() { - var result0, result1; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - if (input.substr(pos, 4).toLowerCase() === "desc") { - result0 = input.substr(pos, 4); - pos += 4; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"DESC\""); - } - } - if (result0 !== null) { - pos2 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos2; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return 'DESC'; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_KW_ALL() { - var result0, result1; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - if (input.substr(pos, 3).toLowerCase() === "all") { - result0 = input.substr(pos, 3); - pos += 3; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"ALL\""); - } - } - if (result0 !== null) { - pos2 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos2; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return 'ALL'; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_KW_DISTINCT() { - var result0, result1; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - if (input.substr(pos, 8).toLowerCase() === "distinct") { - result0 = input.substr(pos, 8); - pos += 8; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"DISTINCT\""); - } - } - if (result0 !== null) { - pos2 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos2; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return 'DISTINCT';})(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_KW_BETWEEN() { - var result0, result1; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - if (input.substr(pos, 7).toLowerCase() === "between") { - result0 = input.substr(pos, 7); - pos += 7; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"BETWEEN\""); - } - } - if (result0 !== null) { - pos2 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos2; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return 'BETWEEN'; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_KW_IN() { - var result0, result1; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - if (input.substr(pos, 2).toLowerCase() === "in") { - result0 = input.substr(pos, 2); - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"IN\""); - } - } - if (result0 !== null) { - pos2 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos2; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return 'IN'; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_KW_IS() { - var result0, result1; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - if (input.substr(pos, 2).toLowerCase() === "is") { - result0 = input.substr(pos, 2); - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"IS\""); - } - } - if (result0 !== null) { - pos2 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos2; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return 'IS'; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_KW_LIKE() { - var result0, result1; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - if (input.substr(pos, 4).toLowerCase() === "like") { - result0 = input.substr(pos, 4); - pos += 4; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"LIKE\""); - } - } - if (result0 !== null) { - pos2 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos2; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return 'LIKE'; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_KW_CONTAINS() { - var result0, result1; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - if (input.substr(pos, 8).toLowerCase() === "contains") { - result0 = input.substr(pos, 8); - pos += 8; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"CONTAINS\""); - } - } - if (result0 !== null) { - pos2 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos2; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return 'CONTAINS';})(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_KW_NOT() { - var result0, result1; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - if (input.substr(pos, 3).toLowerCase() === "not") { - result0 = input.substr(pos, 3); - pos += 3; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"NOT\""); - } - } - if (result0 !== null) { - pos2 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos2; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return 'NOT'; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_KW_AND() { - var result0, result1; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - if (input.substr(pos, 3).toLowerCase() === "and") { - result0 = input.substr(pos, 3); - pos += 3; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"AND\""); - } - } - if (result0 !== null) { - pos2 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos2; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return 'AND'; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_KW_OR() { - var result0, result1; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - if (input.substr(pos, 2).toLowerCase() === "or") { - result0 = input.substr(pos, 2); - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"OR\""); - } - } - if (result0 !== null) { - pos2 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos2; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return 'OR'; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_KW_COUNT() { - var result0, result1; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - if (input.substr(pos, 5).toLowerCase() === "count") { - result0 = input.substr(pos, 5); - pos += 5; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"COUNT\""); - } - } - if (result0 !== null) { - pos2 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos2; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return 'COUNT'; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_KW_MAX() { - var result0, result1; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - if (input.substr(pos, 3).toLowerCase() === "max") { - result0 = input.substr(pos, 3); - pos += 3; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"MAX\""); - } - } - if (result0 !== null) { - pos2 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos2; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return 'MAX'; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_KW_MIN() { - var result0, result1; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - if (input.substr(pos, 3).toLowerCase() === "min") { - result0 = input.substr(pos, 3); - pos += 3; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"MIN\""); - } - } - if (result0 !== null) { - pos2 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos2; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return 'MIN'; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_KW_SUM() { - var result0, result1; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - if (input.substr(pos, 3).toLowerCase() === "sum") { - result0 = input.substr(pos, 3); - pos += 3; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"SUM\""); - } - } - if (result0 !== null) { - pos2 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos2; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return 'SUM'; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_KW_AVG() { - var result0, result1; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - if (input.substr(pos, 3).toLowerCase() === "avg") { - result0 = input.substr(pos, 3); - pos += 3; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"AVG\""); - } - } - if (result0 !== null) { - pos2 = pos; - reportFailures++; - result1 = parse_ident_start(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos2; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return 'AVG'; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_DOT() { - var result0; - - if (input.charCodeAt(pos) === 46) { - result0 = "."; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\".\""); - } - } - return result0; - } - - function parse_COMMA() { - var result0; - - if (input.charCodeAt(pos) === 44) { - result0 = ","; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\",\""); - } - } - return result0; - } - - function parse_STAR() { - var result0; - - if (input.charCodeAt(pos) === 42) { - result0 = "*"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"*\""); - } - } - return result0; - } - - function parse_LPAREN() { - var result0; - - if (input.charCodeAt(pos) === 40) { - result0 = "("; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"(\""); - } - } - return result0; - } - - function parse_RPAREN() { - var result0; - - if (input.charCodeAt(pos) === 41) { - result0 = ")"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\")\""); - } - } - return result0; - } - - function parse_LBRAKE() { - var result0; - - if (input.charCodeAt(pos) === 91) { - result0 = "["; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"[\""); - } - } - return result0; - } - - function parse_RBRAKE() { - var result0; - - if (input.charCodeAt(pos) === 93) { - result0 = "]"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"]\""); - } - } - return result0; - } - - function parse___() { - var result0, result1; - - result0 = []; - result1 = parse_whitespace(); - while (result1 !== null) { - result0.push(result1); - result1 = parse_whitespace(); - } - return result0; - } - - function parse_char() { - var result0; - - if (input.length > pos) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("any character"); - } - } - return result0; - } - - function parse_whitespace() { - var result0; - - if (/^[ \t\n\r]/.test(input.charAt(pos))) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("[ \\t\\n\\r]"); - } - } - return result0; - } - - function parse_EOL() { - var result0, result1; - - result0 = parse_EOF(); - if (result0 === null) { - if (/^[\n\r]/.test(input.charAt(pos))) { - result1 = input.charAt(pos); - pos++; - } else { - result1 = null; - if (reportFailures === 0) { - matchFailed("[\\n\\r]"); - } - } - if (result1 !== null) { - result0 = []; - while (result1 !== null) { - result0.push(result1); - if (/^[\n\r]/.test(input.charAt(pos))) { - result1 = input.charAt(pos); - pos++; - } else { - result1 = null; - if (reportFailures === 0) { - matchFailed("[\\n\\r]"); - } - } - } - } else { - result0 = null; - } - } - return result0; - } - - function parse_EOF() { - var result0; - var pos0; - - pos0 = pos; - reportFailures++; - if (input.length > pos) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("any character"); - } - } - reportFailures--; - if (result0 === null) { - result0 = ""; - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_proc_stmts() { - var result0, result1; - - result0 = []; - result1 = parse_proc_stmt(); - while (result1 !== null) { - result0.push(result1); - result1 = parse_proc_stmt(); - } - return result0; - } - - function parse_proc_stmt() { - var result0, result1, result2; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - pos2 = pos; - reportFailures++; - result0 = parse_proc_init(); - reportFailures--; - if (result0 !== null) { - result0 = ""; - pos = pos2; - } else { - result0 = null; - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_assign_stmt(); - if (result2 === null) { - result2 = parse_return_stmt(); - } - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, s) { - return { - stmt : s, - vars: varList - } - })(pos0, result0[2]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_proc_init() { - var result0; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = []; - if (result0 !== null) { - result0 = (function(offset) { varList = []; return true; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_assign_stmt() { - var result0, result1, result2, result3, result4; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_var_decl(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_KW_ASSIGN(); - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - result4 = parse_proc_expr(); - if (result4 !== null) { - result0 = [result0, result1, result2, result3, result4]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, va, e) { - return { - type : 'assign', - left : va, - right: e - } - })(pos0, result0[0], result0[4]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_return_stmt() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_KW_RETURN(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_proc_expr(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, e) { - return { - type : 'return', - expr: e - } - })(pos0, result0[2]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_proc_expr() { - var result0; - - result0 = parse_select_stmt(); - if (result0 === null) { - result0 = parse_proc_join(); - if (result0 === null) { - result0 = parse_proc_additive_expr(); - if (result0 === null) { - result0 = parse_proc_array(); - } - } - } - return result0; - } - - function parse_proc_additive_expr() { - var result0, result1, result2, result3, result4, result5; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - result0 = parse_proc_multiplicative_expr(); - if (result0 !== null) { - result1 = []; - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_additive_operator(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_proc_multiplicative_expr(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - while (result2 !== null) { - result1.push(result2); - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_additive_operator(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_proc_multiplicative_expr(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, head, tail) { - return createBinaryExprChain(head, tail); - })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_proc_multiplicative_expr() { - var result0, result1, result2, result3, result4, result5; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - result0 = parse_proc_primary(); - if (result0 !== null) { - result1 = []; - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_multiplicative_operator(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_proc_primary(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - while (result2 !== null) { - result1.push(result2); - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_multiplicative_operator(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_proc_primary(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, head, tail) { - return createBinaryExprChain(head, tail); - })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_proc_join() { - var result0, result1, result2, result3, result4, result5, result6; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_var_decl(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_join_op(); - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - result4 = parse_var_decl(); - if (result4 !== null) { - result5 = parse___(); - if (result5 !== null) { - result6 = parse_on_clause(); - if (result6 !== null) { - result0 = [result0, result1, result2, result3, result4, result5, result6]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, lt, op, rt, expr) { - return { - type : 'join', - ltable : lt, - rtable : rt, - op : op, - on : expr - } - })(pos0, result0[0], result0[2], result0[4], result0[6]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_proc_primary() { - var result0, result1, result2, result3, result4; - var pos0, pos1; - - result0 = parse_literal(); - if (result0 === null) { - result0 = parse_var_decl(); - if (result0 === null) { - result0 = parse_proc_func_call(); - if (result0 === null) { - result0 = parse_param(); - if (result0 === null) { - pos0 = pos; - pos1 = pos; - result0 = parse_LPAREN(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_proc_additive_expr(); - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - result4 = parse_RPAREN(); - if (result4 !== null) { - result0 = [result0, result1, result2, result3, result4]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, e) { - e.paren = true; - return e; - })(pos0, result0[2]); - } - if (result0 === null) { - pos = pos0; - } - } - } - } - } - return result0; - } - - function parse_proc_func_call() { - var result0, result1, result2, result3, result4, result5, result6; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_ident(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_LPAREN(); - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - result4 = parse_proc_primary_list(); - if (result4 !== null) { - result5 = parse___(); - if (result5 !== null) { - result6 = parse_RPAREN(); - if (result6 !== null) { - result0 = [result0, result1, result2, result3, result4, result5, result6]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, name, l) { - //compatible with original func_call - return { - type : 'function', - name : name, - args : { - type : 'expr_list', - value : l - } - } - })(pos0, result0[0], result0[4]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_proc_primary_list() { - var result0, result1, result2, result3, result4, result5; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - result0 = parse_proc_primary(); - if (result0 !== null) { - result1 = []; - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_COMMA(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_proc_primary(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - while (result2 !== null) { - result1.push(result2); - pos2 = pos; - result2 = parse___(); - if (result2 !== null) { - result3 = parse_COMMA(); - if (result3 !== null) { - result4 = parse___(); - if (result4 !== null) { - result5 = parse_proc_primary(); - if (result5 !== null) { - result2 = [result2, result3, result4, result5]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, head, tail) { - return createList(head, tail); - })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_proc_array() { - var result0, result1, result2, result3, result4; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_LBRAKE(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result2 = parse_proc_primary_list(); - if (result2 !== null) { - result3 = parse___(); - if (result3 !== null) { - result4 = parse_RBRAKE(); - if (result4 !== null) { - result0 = [result0, result1, result2, result3, result4]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, l) { - return { - type : 'array', - value : l - } - })(pos0, result0[2]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_var_decl() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_KW_VAR_PRE(); - if (result0 !== null) { - result1 = parse_ident_name(); - if (result1 !== null) { - result2 = parse_mem_chain(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, name, m) { - //push for analysis - varList.push(name); - return { - type : 'var', - name : name, - members : m - } - })(pos0, result0[1], result0[2]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_mem_chain() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - result0 = []; - pos1 = pos; - if (input.charCodeAt(pos) === 46) { - result1 = "."; - pos++; - } else { - result1 = null; - if (reportFailures === 0) { - matchFailed("\".\""); - } - } - if (result1 !== null) { - result2 = parse_ident_name(); - if (result2 !== null) { - result1 = [result1, result2]; - } else { - result1 = null; - pos = pos1; - } - } else { - result1 = null; - pos = pos1; - } - while (result1 !== null) { - result0.push(result1); - pos1 = pos; - if (input.charCodeAt(pos) === 46) { - result1 = "."; - pos++; - } else { - result1 = null; - if (reportFailures === 0) { - matchFailed("\".\""); - } - } - if (result1 !== null) { - result2 = parse_ident_name(); - if (result2 !== null) { - result1 = [result1, result2]; - } else { - result1 = null; - pos = pos1; - } - } else { - result1 = null; - pos = pos1; - } - } - if (result0 !== null) { - result0 = (function(offset, l) { - var s = []; - for (var i = 0; i < l.length; i++) { - s.push(l[i][1]); - } - return s; - })(pos0, result0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_KW_VAR_PRE() { - var result0; - - if (input.charCodeAt(pos) === 36) { - result0 = "$"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"$\""); - } - } - return result0; - } - - function parse_KW_RETURN() { - var result0; - - if (input.substr(pos, 6).toLowerCase() === "return") { - result0 = input.substr(pos, 6); - pos += 6; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"return\""); - } - } - return result0; - } - - function parse_KW_ASSIGN() { - var result0; - - if (input.substr(pos, 2) === ":=") { - result0 = ":="; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\":=\""); - } - } - return result0; - } - - - function cleanupExpected(expected) { - expected.sort(); - - var lastExpected = null; - var cleanExpected = []; - for (var i = 0; i < expected.length; i++) { - if (expected[i] !== lastExpected) { - cleanExpected.push(expected[i]); - lastExpected = expected[i]; - } - } - return cleanExpected; - } - - function computeErrorPosition() { - /* - * The first idea was to use |String.split| to break the input up to the - * error position along newlines and derive the line and column from - * there. However IE's |split| implementation is so broken that it was - * enough to prevent it. - */ - - var line = 1; - var column = 1; - var seenCR = false; - - for (var i = 0; i < Math.max(pos, rightmostFailuresPos); i++) { - var ch = input.charAt(i); - if (ch === "\n") { - if (!seenCR) { line++; } - column = 1; - seenCR = false; - } else if (ch === "\r" || ch === "\u2028" || ch === "\u2029") { - line++; - column = 1; - seenCR = true; - } else { - column++; - seenCR = false; - } - } - - return { line: line, column: column }; - } - - - var util = require('util'); - - function debug(str){ - console.log(str); - } - - function inspect(obj){ - console.log(util.inspect(obj, false, 10)); - } - - function createUnaryExpr(op, e) { - return { - type : 'unary_expr', - operator : op, - expr : e - } - } - - function createBinaryExpr(op, left, right) { - return { - type : 'binary_expr', - operator : op, - left : left, - right : right - } - } - - function createList(head, tail) { - var result = [head]; - for (var i = 0; i < tail.length; i++) { - result.push(tail[i][3]); - } - return result; - } - - function createExprList(head, tail, room) { - var epList = createList(head, tail); - var exprList = []; - var ep; - for (var i = 0; i < epList.length; i++) { - ep = epList[i]; - //the ep has already added to the global params - if (ep.type == 'param') { - ep.room = room; - ep.pos = i; - } else { - exprList.push(ep); - } - } - return exprList; - } - - function createBinaryExprChain(head, tail) { - var result = head; - for (var i = 0; i < tail.length; i++) { - result = createBinaryExpr(tail[i][1], result, tail[i][3]); - } - return result; - } - - var reservedMap = { - 'SHOW' : true, - 'DROP' : true, - 'SELECT' : true, - 'UPDATE' : true, - 'CREATE' : true, - 'DELETE' : true, - 'INSERT' : true, - 'REPLACE' : true, - 'EXPLAIN' : true, - 'ALL' : true, - 'DISTINCT': true, - 'AS' : true, - 'TABLE' : true, - 'INTO' : true, - 'FROM' : true, - 'SET' : true, - 'LEFT' : true, - 'ON' : true, - 'INNER' : true, - 'JOIN' : true, - 'UNION' : true, - 'VALUES' : true, - 'EXISTS' : true, - 'WHERE' : true, - 'GROUP' : true, - 'BY' : true, - 'HAVING' : true, - 'ORDER' : true, - 'ASC' : true, - 'DESC' : true, - 'LIMIT' : true, - 'BETWEEN' : true, - 'IN' : true, - 'IS' : true, - 'LIKE' : true, - 'CONTAINS': true, - 'NOT' : true, - 'AND' : true, - 'OR' : true, - - //literal - 'TRUE' : true, - 'FALSE' : true, - 'NULL' : true - } - - var cmpPrefixMap = { - '+' : true, - '-' : true, - '*' : true, - '/' : true, - '>' : true, - '<' : true, - '!' : true, - '=' : true, - - //between - 'B' : true, - 'b' : true, - //for is or in - 'I' : true, - 'i' : true, - //for like - 'L' : true, - 'l' : true, - //for not - 'N' : true, - 'n' : true, - //for contains - 'C' : true, - 'c' : true, - } - - //used for store refered parmas - var params = []; - - //used for dependency analysis - var varList = []; - - - var result = parseFunctions[startRule](); - - /* - * The parser is now in one of the following three states: - * - * 1. The parser successfully parsed the whole input. - * - * - |result !== null| - * - |pos === input.length| - * - |rightmostFailuresExpected| may or may not contain something - * - * 2. The parser successfully parsed only a part of the input. - * - * - |result !== null| - * - |pos < input.length| - * - |rightmostFailuresExpected| may or may not contain something - * - * 3. The parser did not successfully parse any part of the input. - * - * - |result === null| - * - |pos === 0| - * - |rightmostFailuresExpected| contains at least one failure - * - * All code following this comment (including called functions) must - * handle these states. - */ - if (result === null || pos !== input.length) { - var offset = Math.max(pos, rightmostFailuresPos); - var found = offset < input.length ? input.charAt(offset) : null; - var errorPosition = computeErrorPosition(); - - throw new this.SyntaxError( - cleanupExpected(rightmostFailuresExpected), - found, - offset, - errorPosition.line, - errorPosition.column - ); - } - - return result; - }, - - /* Returns the parser source code. */ - toSource: function() { return this._source; } - }; - - /* Thrown when a parser encounters a syntax error. */ - - result.SyntaxError = function(expected, found, offset, line, column) { - function buildMessage(expected, found) { - var expectedHumanized, foundHumanized; - - switch (expected.length) { - case 0: - expectedHumanized = "end of input"; - break; - case 1: - expectedHumanized = expected[0]; - break; - default: - expectedHumanized = expected.slice(0, expected.length - 1).join(", ") - + " or " - + expected[expected.length - 1]; - } - - foundHumanized = found ? quote(found) : "end of input"; - - return "Expected " + expectedHumanized + " but " + foundHumanized + " found."; - } - - this.name = "SyntaxError"; - this.expected = expected; - this.found = found; - this.message = buildMessage(expected, found); - this.offset = offset; - this.line = line; - this.column = column; - }; - - result.SyntaxError.prototype = Error.prototype; - - return result; -})(); diff --git a/base/orderby.js b/base/orderby.js deleted file mode 100644 index 93ba36f..0000000 --- a/base/orderby.js +++ /dev/null @@ -1,55 +0,0 @@ -// (C) 2011-2013 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - -var AstHelper = require('../lib/ast_helper'); - -module.exports = orderby; - -function debug(str){ - //console.log(str); -} - -function inspect(obj){ - //console.log(require("util").inspect(obj, false, 10)); -} - -/** - * @param {Array} orderby [{name : 'col1' , type : "ASC"}, ...] - */ -function orderby(dc, orderby) { - var cPos = []; - var dCols = dc.columns; - var dData = dc.data; - var pos; - for (var i = 0; i < orderby.length ; i++) { - pos = AstHelper.getRowPosByCol(dCols, orderby[i].name); - cPos.push(pos); - } - //debug('orderby pos'); - //inspect(cPos); - var rData = dData.sort(function(a, b){ - var cmp = 0; - for(var i = 0; i < cPos.length; i++){ - var pos = cPos[i]; - if (a[pos] != b[pos]) { - if (a[pos] > b[pos]) { - cmp = 1; - } else { - cmp = -1; - } - if(orderby[i].type == 'DESC') cmp = -cmp; - break; - } - } - return cmp; - }); - - return { - columns : dCols, - data : rData - } -} diff --git a/base/postprocess.js b/base/postprocess.js deleted file mode 100644 index 8f4ff42..0000000 --- a/base/postprocess.js +++ /dev/null @@ -1,27 +0,0 @@ -// (C) 2011-2013 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - -module.exports = getFinalColName; - -function getFinalColName(dc, sp){ - var cols = dc.columns; - var rows = dc.data; - var fcols = []; - - var col; - for (var i = 0; i < cols.length; i++) { - col = cols[i].pop(); - fcols.push(col.column); - //push it again ,don't change the data,only copy - cols[i].push(col); - } - - return { - columns : fcols, - data : rows - } -} diff --git a/base/procedure.js b/base/procedure.js deleted file mode 100644 index 7943bba..0000000 --- a/base/procedure.js +++ /dev/null @@ -1,224 +0,0 @@ -// (C) 2011-2013 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - -var Jobs = require('../lib/jobs'); -var Table = require('../lib/table'); -var Merger = require('../lib/merger'); -var Engine = require('../lib/engine'); -var Context = require('../lib/context'); -var Executor = require('../lib/executor'); -var AstHelper = require('../lib/ast_helper'); - -var runAST = Executor.runAST; -var runPlain = Engine.run; -var AstReader = AstHelper.Reader; -var doSelectOnTable = Executor.doSelectOnTable; - -function debug(str) { - //console.log(str); -} - -function inspect(obj) { - //console.log(require('util').inspect(obj, false, 10, true)); -} - -function doAssign(left, right, ctx) { - //var typeVal = js2nSQL(right); - var typeVal = right; - //TODO ,if complicated type ,should CLONE - var varid = left.name; - var members = left.members; - if (members.length > 0) { - var obj = ctx[varid]; - var len = members.length; - for (var i = 0; i < len - 1; i++) { - obj = obj[members[i]]; - } - var lastMem = members[len - 1]; - obj[lastMeb] = typeVal; - } else { - ctx[varid] = typeVal; - } - //debug('ctx now :'); - //inspect(ctx); -} - -function runExpr(expr, ctx, cb) { - //debug(runExpr); - //inspect(expr); - if (expr.type == 'select') { - var tables = expr.from; - var varTableNum = 0; - for (var i = 0; i < tables.length; i++) { - if (tables[i].type == 'var') { - varTableNum++; - } - } - if (varTableNum == tables.length) { - var tbl = doTableJoin(tables, ctx); - var ar = new AstReader(expr); - //inspect('temp join table :'); - //inspect(tbl); - tbl = doSelectOnTable(tbl, ar, ctx); - tbl = new Table(tbl); - cb(null, tbl); - } else { - if (varTableNum > 0) { - throw Error('can\'t do join when one or more tables are not ready...'); - } else { - //debug('runAST in procedure'); - runAST(expr, ctx, function(err, dc) { - if (err) { - cb(err); - } else { - cb(null, new Table(dc)); - } - }); - } - } - } else { - Context.setctx(ctx); - var data = runPlain(expr); - cb(null, data); - } -} - -function doTableJoin(from, ctx) { - var tbs = []; - var ons = []; - var ops = []; - - var tb, op, on; - var i, tbunit; - var tbName, tbAlias; - for (i = 0; i < from.length; i++) { - tbunit = from[i]; - inspect(tbunit); - tb = Context.getBindVar(tbunit, ctx); - //here we should add table/alias info to the data - - tbName = tbunit.name; - tbAlias= (tbunit.as != '') ? tbunit.as : undefined; - tb = tb.get(tbName, tbAlias); - - op = tbunit.join; - on = regularOnExpr(tbunit.on); - - tbs.push(tb); - ops.push(op); - ons.push(on); - } - - var res = tbs[0]; - for (i = 1; i < tbs.length; i++) { - res = Merger.join(res, tbs[i], ops[i], ons[i]); - } - return res; -} - -function regularOnExpr(on) { - //first split and - var rels = []; - var stack = []; - var expr; - if (on) { - stack.push(on); - } - while (stack.length > 0) { - expr = stack.pop(); - if (expr.type == 'binary_expr' && expr.operator == 'AND') { - stack.push(expr.right); - stack.push(expr.left); - } else { - rels.push(expr); - } - } - var ons = { - left : [], - right: [] - } - var rel; - for (var i = 0; i < rels.length; i++) { - rel = rels[i]; - ons.left.push({ - table : rel.left.table, - column: rel.left.column - }) - ons.right.push({ - table : rel.right.table, - column: rel.right.column - }) - } - return ons; -} - -exports.run = run; - -function run(stps, cb) { - var i, j, stm, stmts; - var ret; - var t, tasks; - var jobs = []; - var ctx = {}; - for (i = 0; i < stps.length; i++) { - stmts = stps[i]; - tasks = []; - for (j = 0; j < stmts.length; j++) { - t = new Task(stmts[j], ctx); - tasks.push(t); - } - jobs.push(tasks); - } - - Jobs.doSequential(jobs, function(err) { - if (err) { - cb(err); - } else { - var obj = ctx['__return']; - if (obj instanceof Table) { - obj = obj.getData(); - } else { - hackTable(obj); - } - cb(null, obj); - } - }); -} - -function hackTable(obj) { - if (Array.isArray(obj)) { - var i, len, ele; - len = obj.length; - for (i =0; i < len; i++) { - ele = obj[i]; - if (ele instanceof Table) { - obj[i] = ele.getData(); - } else { - hackTable(obj[i]); - } - } - } -} - -function Task(stm, ctx) { - this._stm = stm; - this._ctx = ctx; -} - -Task.prototype.run = function(cb) { - var stm = this._stm; - var ctx = this._ctx; - runExpr(stm.right, ctx, function(err, data) { - if (err) { - cb(err); - } else { - doAssign(stm.left, data, ctx); - cb(null); - } - }); -} - diff --git a/base/topology.js b/base/topology.js deleted file mode 100644 index de255f8..0000000 --- a/base/topology.js +++ /dev/null @@ -1,102 +0,0 @@ -// (C) 2011-2013 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - -var Tool = require('../lib/tool'); -exports.order = order; - -function debug(str) { - //console.log(str); -} - -function inspect(obj) { - //console.log(require('util').inspect(obj, false, 10)); -} - -function order(stmts) { - var i, j, o, v, s; - var rs, ds; - var nodes = []; - var deps = []; - for (i = 0; i < stmts.length; i++) { - s = stmts[i]; - deps = []; - if (s.stmt && s.stmt.type == 'assign') { - v = s.vars[0]; - ds = s.vars; - for (j = 0; j < ds.length; j++) { - if (ds[j] != v) deps.push(ds[j]); - } - } else if (s.stmt && s.stmt.type == 'return') { - if (i != stmts.length -1 ) { - throw new Error('return statement should be the LAST'); - } - v = '__return'; - deps = s.vars; - //hack the last return format - var nr = {}; - nr.type = 'assign'; - nr.left = { - type : 'var', - name : '__return', - members : [] - } - nr.right = s.stmt.expr; - - stmts[i].stmt = nr; - - } - - o = { - 'var' : v, - 'deps': deps - } - nodes.push(o); - } - - //debug('nodes'); - //inspect(nodes); - //inspect(stmts); - //do orders - var ok; - var sts = {}; - var seqs = []; - var arr = []; - for (i = 0; i < nodes.length;) { - o = nodes[i]; - deps = o.deps; - ok = true; - for (j = 0; j < deps.length; j++) { - if (sts[deps[j]] != true) { - ok = false; - break; - } - } - //debug('i : ' + i + ', ok :' + ok); - if (ok) { - arr.push(stmts[i].stmt); - i++; - } else { - if (arr.length > 0) { - seqs.push(arr); - for (j = 0; j < i; j++) { - o = nodes[j]; - v = o['var']; - sts[v] = true; - } - arr = []; - } else { - throw new Error('can\'t decide order for : ' + o['var']); - } - } - } - - if (arr.length > 0) { - seqs.push(arr); - } - - return seqs; -} diff --git a/base/where.js b/base/where.js deleted file mode 100644 index 20fcdf9..0000000 --- a/base/where.js +++ /dev/null @@ -1,57 +0,0 @@ -// (C) 2011-2012 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - -var Engine = require('../lib/engine'); -var AstHelper = require('../lib/ast_helper'); - -var runExpr = Engine.run; -var fillExprOnRow = AstHelper.fillExprOnRow - -module.exports = filter; - -function debug(str) { - //console.log(str); -} - -function inspect(obj) { - //console.log(require('util').inspect(obj, false, 10, true)); -} - - -function filter(dc, e) { - - var cols = dc.columns; - var rows = dc.data; - - //debug('before where filter:'); - //inspect(dc); - var res = []; - var refCols = AstHelper.getRefColumns(e); - var refPos = AstHelper.getRefColPos(refCols, cols); - - //debug('resPos:') - //inspect(refPos); - var rbackup = AstHelper.backupRefCols(refCols); - var i, r; - for (i = 0; i < rows.length; i++) { - r = rows[i]; - //debug('row : ' + i); - fillExprOnRow(r, refCols, refPos); - //var ret; - if (runExpr(e)) { - res.push(r); - } - } - - AstHelper.restoreRefCols(refCols, rbackup); - //debug('after filter'); - //inspect(refCols); - return { - columns : cols, - data : res - } -} diff --git a/demo/demo.js b/demo/demo.js deleted file mode 100644 index 454bc78..0000000 --- a/demo/demo.js +++ /dev/null @@ -1,112 +0,0 @@ -// (C) 2011-2013 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - -var KV = require('./kv'); -var Mysql = require('./mysql'); -var Loader = require('./loader'); - -var nQuery = require('../index'); -var Query = nQuery.Query; -var Context = nQuery.Context; -var Executor = nQuery.Executor; - -function debug(str) { - console.log(str); -} - -function inspect(obj) { - console.log(require('util').inspect(obj, false, 10)); -} - -var kvInfo = { - 'kv.user' : { - primaryKeys : ['id'], - prefixMatch : true, - rangeQuery : true - } -} - -var dbInfo = { - kv: { - storageType : 'kv', - storageEngine : KV - }, - mysql : { - storageType : 'sql', - storageEngine : Mysql - } -} - - -function main() { - Loader.setDBInfo(dbInfo); - Loader.setKVInfo(kvInfo); - - Executor.setLoader(Loader.load); - - var sqls = [ - "SELECT * FROM kv.user WHERE id IN ('01', '03')", - "SELECT * FROM kv.user WHERE id LIKE '1%'", - "SELECT type, MAX(age), COUNT(id) FROM kv.user WHERE id BETWEEN '03' AND '10' GROUP BY type ORDER BY MAX(age) DESC", - "SELECT * from mysql.shop where shop_id > 5" - ] - - var concurrentJoinSQL = [ - "$a := select * from kv.user where id BETWEEN '03' and '10'", - "$b := select * from mysql.shop where shop_id > 5", - "$c := select a.type , a.id ,b.name, b.title from $a INNER JOIN $b ON a.type = b.type WHERE a.id > '04'", - "return $c" - ] - - var sequentialJoinSQL = [ - "$a := select * from kv.user where id BETWEEN '03' and '10'", - //you could also use `unique` do filter firstly - //"$type := UNIQUE($a.type)", - //"$b := select * from mysql.shop where type = $type", - "$b := select * from mysql.shop where type in $a.type", - "$c := select a.type , a.id ,b.name, b.title from $a INNER JOIN $b ON a.type = b.type WHERE a.id > '04'", - "return [$b, $c]" - ] - - printSeperator(); - - for (var i = 0; i < sqls.length; i++) { - doQuery(sqls[i]); - } - - doQuery(concurrentJoinSQL.join('\n')); - - doQuery(sequentialJoinSQL.join('\n')); -} - -function printSeperator() { - var str = ''; - for(var i = 0; i < 80; i++) { - str += '-' - } - debug(str); -} - -function doQuery(sql) { - Query.runSQL(sql, function(err, dc) { - if (err) { - if (err.stack) { - debug(err.stack); - } else { - debug(err); - } - } else { - debug('sql :'); - debug('' + sql); - debug('\ndata:'); - inspect(dc); - printSeperator(); - } - }); -} - -main(); diff --git a/demo/kv.js b/demo/kv.js deleted file mode 100644 index 5fe6d46..0000000 --- a/demo/kv.js +++ /dev/null @@ -1,85 +0,0 @@ -// (C) 2011-2013 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - -var columns = [ - 'id', 'name' , 'type', 'age', 'gender' - ]; - -var data = [ - ['00', 'alice', 'a', 18, 'male' ], - ['01', 'bob', 'b', 18, 'female' ], - ['02', 'edward','a', 13, 'male' ], - ['03', 'selly', 'c', 18, 'female' ], - ['04', 'miller','a', 12, 'male' ], - ['05', 'alice', 'd', 18, 'male' ], - ['06', 'edward','a', 12, 'female' ], - ['07', 'alice', 'e', 18, 'male' ], - ['08', 'kenney','a', 12, 'female' ], - ['09', 'kobe', 'e', 28, 'male' ], - ['10', 'kikyou','a', 12, 'female' ], - ['11', 'onesa', 'e', 28, 'male' ] - ]; - -module.exports = { - singleQuery : singleQuery, - rangeQuery : rangeQuery, - likeQuery : likeQuery -} - -function singleQuery(k) { - var rows = data; - var row; - - var ret = { - columns : columns, - data : [] - } - for (var i = 0; i < rows.length; i++) { - row = rows[i]; - if (row[0] == k) { - ret.data.push(row); - break; - } - } - return ret; -} - -function rangeQuery(beg, end) { - var rows = data; - var row; - - var ret = { - columns : columns, - data : [] - } - for (var i = 0; i < rows.length; i++) { - row = rows[i]; - if (row[0] >= beg && row[0] < end) { - ret.data.push(row); - } - } - return ret; -} - -//begin with `str` -function likeQuery(str) { - //console.log('likeQuery of :' + str); - var rows = data; - var row; - - var ret = { - columns : columns, - data : [] - } - for (var i = 0; i < rows.length; i++) { - row = rows[i]; - if (row[0].indexOf(str) == 0) { - ret.data.push(row); - } - } - return ret; -} diff --git a/demo/loader.js b/demo/loader.js deleted file mode 100644 index 420a7ca..0000000 --- a/demo/loader.js +++ /dev/null @@ -1,141 +0,0 @@ -// (C) 2011-2013 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - -var nQuery = require('../index') - -var Adapter = nQuery.Adapter; -var Context = nQuery.Context; -var Extractor = nQuery.Extractor; - -var kvInfo = {}; -var dbInfo = {}; - -exports.setDBInfo = function(info) { - dbInfo = info; -} - -exports.setKVInfo = function(info) { - kvInfo = info; -} - -exports.load = load; - - -function debug(str) { - console.log(str); -} - -function inspect(obj) { - console.log(require('util').inspect(obj, false, 10)); -} - -function load(ar, ctx, cb) { -//you could copy these functions - var db = ar.getDB(); - //debug('db : ' + db); - - var info = dbInfo[db]; - - if (!info) { - cb(new Error('no registered db info found...')); - return; - } - - var engine = info.storageEngine; - if (!engine) { - cb(new Error('no registered load found for :' + db)); - return; - } - - var dbType = info.storageType; - - if (dbType == 'kv') { - var table = ar.getTableOrig(); - var dt = db + '.' + table; - - var opt = kvInfo[dt]; - - if (!opt) { - cb(new Error('no registered kv table info found for :' + dt)); - return; - } - kvLoad(ar, ctx, engine, opt, cb); - } else if (dbType == 'sql') { - sqlLoad(ar, ctx, engine, cb); - } else { - cb(new Error('unrecognized db type : ') + dbType); - } -} - -function sqlLoad(ar, ctx, engine, cb) { - Context.setctx(ctx); - var ast = ar.getAst(); - var str = Adapter.toSQL(ast, ctx); - - //debug('do sqlLoad: ' + str); - engine.query(str, function(err, dc, info) { - //in most cases, the post-filter was null or undefined - cb(err, dc); - }); -} - -function kvLoad(ar ,ctx, engine, opt, cb) { - Context.setctx(ctx); - var ast = ar.getAst(); - var info = Extractor.getKeyInfo(ast.where, opt); - - if (!info) { - cb(new Error('no registered db info found...')); - return; - } - //inspect(info); - - var inKeys = info['IN'] || []; - var btwKeys = info['BETWEEN'] || []; - var likeKeys = info['LIKE'] || []; - - var dcs = []; - - var i, dc; - //here we use sync-method just for demostration, - //in fact ,you should use async instead - for (i = 0; i < inKeys.length; i++) { - dc = engine.singleQuery(inKeys[i]); - dcs.push(dc); - } - - for (i = 0; i < btwKeys.length; i++) { - dc = engine.rangeQuery(btwKeys[i][0], btwKeys[i][1]); - dcs.push(dc); - } - - for (i = 0; i < likeKeys.length; i++) { - dc = engine.likeQuery(likeKeys[i]); - dcs.push(dc); - } - - dc = dataUnion(dcs); - - cb(null, dc, ar); -} - -function dataUnion(dcs) { - var res = {}; - var dc; - for (var i = 0; i < dcs.length; i++) { - dc = dcs[i]; - //here maybe you should use clone instead - if (i == 0) { - res.columns = dc.columns; - res.data = dc.data; - } else { - res.data = res.data.concat(dc.data); - } - } - return res; -} - diff --git a/demo/mysql.js b/demo/mysql.js deleted file mode 100644 index 0fbd821..0000000 --- a/demo/mysql.js +++ /dev/null @@ -1,49 +0,0 @@ -// (C) 2011-2013 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - -var nQuery = require('../index'); - -var Parser = nQuery.Parser; -var Executor = nQuery.Executor; -var AstReader = nQuery.AstReader; - -var dc = { - columns : [ - 'name' , 'type', 'shop_id', 'title', 'money' - ], - data : [ - ['edward', 'a', 1, 'spring', 100], - ['bob', 'b', 2, 'spring', 100], - ['alice', 'b', 3, 'spring', 120], - ['selly', 'b', 4, 'spring', 120], - ['kikyou', 'c', 5, 'summer', 220], - ['kobe', 'c', 6, 'summer', 320], - ['onesa', 'd', 8, 'summer', 320], - ['miller', 'd', 9, 'summer', 320] - ] -} - -exports.query = function(str, cb) { - var dc; - try { - dc = run(str); - } catch (e) { - cb(e); - return; - } - cb(null, dc); -} - -var doSelectFilter = Executor.doSelectFilter; - -function run(str) { - var ast = Parser.parse(str); - var ar = new AstReader(ast); - - var res = doSelectFilter(dc, ar); - return res; -} diff --git a/index.js b/index.js index aef498c..8b5986c 100644 --- a/index.js +++ b/index.js @@ -1,14 +1,7 @@ -exports.parse = require('./lib/parser').parse; -exports.tplParse = require('./lib/parser').tplParse; - -exports.Table = require('./lib/table'); -exports.Query = require('./lib/query'); -exports.Parser = require('./lib/parser'); -exports.Merger = require('./lib/merger'); -exports.Adapter = require('./lib/adapter'); -exports.Context = require('./lib/context'); -exports.Executor = require('./lib/executor'); -exports.Extractor = require('./lib/extractor'); -exports.AstHelper = require('./lib/ast_helper'); - -exports.AstReader = require('./lib/ast_helper').Reader; +/*! + * node-sqlparser: index.js + * Create : 2014-05-21 18:05:12 + */ +exports.AST = require('./lib/ast'); +exports.parse = require('./lib/parse').parse; +exports.stringify = require('./lib/stringify'); \ No newline at end of file diff --git a/lib/ast.js b/lib/ast.js new file mode 100644 index 0000000..1024590 --- /dev/null +++ b/lib/ast.js @@ -0,0 +1,43 @@ +/** + * @class AST Helper + */ +var parse = require('./parse').parse; +var stringify = require('./stringify'); + +function AST(ast) { + this.ast = ast; +} + +AST.prototype = { + /** + * parse sql string to ast object + * @param {String} sql + */ + parse: function (sql) { + this.ast = parse(sql); + }, + /** + * stringify ast object to sql + * @return {String} sql + */ + stringify: function () { + return stringify(this.ast); + }, + /** + * 获取 sql 中依赖的table 列表 + * @return {[type]} [description] + */ + getTables: function () { + + }, + /** + * 获取 sql 中命中的字段, select中的 + * + * @return {[type]} [description] + */ + getSelectedColumns: function () { + + } +}; + +module.exports = AST; diff --git a/lib/ast_helper.js b/lib/ast_helper.js deleted file mode 100644 index a450e20..0000000 --- a/lib/ast_helper.js +++ /dev/null @@ -1,473 +0,0 @@ -// (C) 2011-2013 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - -var Tool = require('./tool'); -var Adapter = require('./adapter'); - -var clone = Tool.clone; - -exports.getRefColumns = getRefColumns - -function debug(str) { - //console.log(str); -} - -function inspect(obj) { - //console.log(require('util').inspect(obj, false, 10, true)); -} - -function getRefColumns(expr) { - var stack = [expr]; - var cur, t; - var res = []; - while(stack.length > 0) { - cur = stack.pop(); - t = cur.type; - switch (t) { - case 'column_ref' : - res.push(cur); - break; - case 'binary_expr': - stack.push(cur.right); - stack.push(cur.left); - break; - case 'unary_expr' : - stack.push(cur.expr); - break; - case 'aggr_func' : - stack.push(cur.args.expr); - break; - case 'function' : - stack = stack.concat(cur.args.value); - break; - default: - break; - } - } - return res; -} - -exports.getSelRefCols = function (sels) { - // refCols - // [{type : 'column_ref', column :}, ...] - var i, e, rc; - var refCols = []; - for (i = 0; i < sels.length; i++) { - e = sels[i].expr; - //exprs.push(e); - rc = getRefColumns(e); - refCols = refCols.concat(rc); - } - return refCols; -} - -// { -// id1 : { -// cols : [rc1, rc2, rc3,...] -// pos : 2 -// } , -// id2 : { -// cols : [,,] -// pos : -// } -// } -exports.getRefColInfo = getRefColInfo; -function getRefColInfo(refCols, columns) { - //inspect(refCols); - //inspect(columns); - var i, obj, rc, key; - var colMap = {}; - for (i = 0; i < refCols.length; i++) { - rc = refCols[i]; - key = rc.column; - if (rc.table && rc.table != '') { - key = rc.table + '.' + key; - } - obj = colMap[key]; - if (!obj) { - obj = {}; - obj.cols = []; - obj.pos = getRowPosByCol(columns, rc); - colMap[key] = obj; - } - obj.cols.push(rc); - } - return colMap; -} - -exports.getRowPosByCol = getRowPosByCol; - -function getRowPosByCol(columns, col) { - var pos = -1; - var cols; - var i, j; - //debug('getRowPosByCol:'); - //inspect(columns); - //inspect(col); - for (i = 0; i < columns.length; i++) { - cols = columns[i]; - for (j = 0; j < cols.length; j++) { - if (col.table == cols[j].table && col.column == cols[j].column) { - pos = i; - break; - } - } - if (pos >= 0) break; - } - if (pos < 0) { - throw new Error('no column found for :' + col.table + '.' + col.column); - } else { - return pos; - } -} - -exports.getColNameByExpr = getColNameByExpr; -function getColNameByExpr(expr) { - var name; - if (expr.type == 'column_ref') { - name = expr.column; - } else { - name = Adapter.exprToSQL(expr); - } - return name; -} - -//this used to get the column name/alias -//both for cloumn-clause and order by clause -exports.getColumnNames = getColumnNames; -function getColumnNames(columns) { - //inspect(columns); - var res = []; - var i, as, name, c, cols, expr; - for (i = 0; i < columns.length; i++) { - cols = []; - c = columns[i]; - expr = c.expr; - if (expr.type == 'column_ref') { - cols.push({ - table : expr.table, - column: expr.column - }) - } else { - cols.push({ - table : '', - column: Adapter.exprToSQL(expr) - }) - } - as = c.as; - if (as && as != '') { - cols.push({ - table : '', - column: as - }); - } - res.push(cols); - } - return res; -} - -exports.getRefColPos = function(refCols, cols) { - //debug('getRefColPos:'); - //inspect(refCols); - //inspect(cols); - var i, j, k, rc, cs, found; - var refPos = []; - for (i = 0; i < refCols.length; i++) { - rc = refCols[i]; - found = false; - for (j = 0; j < cols.length; j++) { - cs = cols[j]; - for (k = 0; k < cs.length; k++) { - if (rc.column == cs[k].column) { - if (!rc.table || rc.table == '' || (rc.table == cs[k].table)) { - refPos.push(j); - found = true; - break; - } - } - } - if (found) break; - } - if (found == false) { - throw new Error('no column found for :' + rc.column); - } - } - return refPos; -} - -exports.backupRefCols = function(refCols) { - return clone(refCols); -} - -exports.restoreRefCols = function(refCols, rbackup) { - //restore the cols - var c, rb; - for (var i = 0; i < refCols.length; i++) { - c = refCols[i]; - rb = rbackup[i]; - c.type = rb.type; - c.value = undefined; - } -} - - -//TODO, just work-around now ,recur checking needed -exports.checkAggrOp = function(gb, sels) { - var ret = false; - if (Array.isArray(gb) && gb.length > 0) { - ret = true; - } else if (Array.isArray(sels)) { - for (var i = 0; i < sels.length; i++) { - if (sels[i].expr.type == 'aggr_func') { - ret = true; - break; - } - } - } - return ret; -} - -//for orderby columns ,if not existed in the select clause -//we need append it, after we doOrderby ,just skip thess columns -exports.expandSelect = function (sels, ob) { - var res = sels; - var paddings = []; - var selCols = getColumnNames(sels); - - //debug('expand Select:'); - //inspect(selCols); - //inspect(ob); - var i, j, k; - var colNames; - var table, column; - var expr, eobj, found; - for (i = 0; i < ob.length; i++) { - expr = ob[i].expr; - if (expr.type == 'column_ref') { - table = expr.table; - column = expr.column; - } else { - table = ''; - column = Adapter.exprToSQL(expr); - } - found = false; - for (j = 0; j < selCols.length; j++) { - colNames = selCols[j]; - for (k = 0; k < colNames.length; k++) { - if (colNames[k].table == table && colNames[k].column == column) { - found = true; - break; - } - } - if (found) break; - } - if (found == false) { - paddings.push(ob[i]); - } - } - if (paddings.length > 0) { - res = res.concat(paddings); - } - //debug('expand result:'); - //inspect(res); - return res; -} - -exports.shrinkSelect = function(dc, selCols) { - var allCols = dc.columns; - var nsize = selCols.length; - - if (allCols.length > nsize) { - var i, rows; - var rows = dc.data; - for (i = 0; i < rows.length; i++) { - rows[i] = rows[i].slice(0, nsize); - } - dc.columns = allCols.slice(0, nsize); - } - return dc; -} - -exports.Reader = Reader - -function Reader(ast) { - this._ast = ast; -} - -Reader.prototype.getDB = function() { - var dt = this._ast.from; - var db = ''; - if (dt && Array.isArray(dt)) { - db = dt[0].db; - } - return db; -} - -Reader.prototype.getTableAlias = function() { - var dt = this._ast.from; - var alias = ''; - if (dt && Array.isArray(dt)) { - alias = dt[0].as; - } - return alias; -} - -Reader.prototype.getTableOrig = function() { - var dt = this._ast.from; - var orig = ''; - if (dt && Array.isArray(dt)) { - orig = dt[0].table; - } - return orig; -} - -//get pure final colNames -Reader.prototype.getAsNames = function() { - var cols = this._ast.columns; - var res = []; - if (Array.isArray(cols)) { - var i, c, as, expr; - for (i = 0; i < cols.length; i++) { - c = cols[i]; - as = c.as; - if (as == '') { - expr = c.expr - as = getColNameByExpr(expr); - } - res.push(as); - } - } - return res; -} - -Reader.prototype.getOrderby = function() { - var res = []; - var ods = this._ast.orderby; - var obj; - if (Array.isArray(ods)) { - var i, obj, expr; - for (i = 0; i < ods.length; i++) { - expr = ods[i].expr; - if (expr.type == 'column_ref') { - obj = { - table : expr.table, - column: expr.column - } - } else { - obj = { - table : '', - column : Adapter.exprToSQL(expr) - } - } - res.push({ - type : ods[i].type, - name : obj - }); - } - } - return res; -} - -Reader.prototype.getGroupby = function() { - var res = []; - var ods = this._ast.groupby; - if (Array.isArray(ods)) { - var obj ;; - for (var i = 0; i < ods.length; i++) { - obj = { - table : ods[i].table, - column: ods[i].column - } - res.push(obj); - } - } - return res; -} - -Reader.prototype.getLimits = function() { - var res = []; - var lm = this._ast.limit; - if (Array.isArray(lm) && lm.length == 2) { - res.push(lm[0].value); - res.push(lm[1].value); - } - return res; -} - -Reader.prototype.isDistinct = function() { - return this._ast.distinct == 'DISTINCT'; -} - -Reader.prototype.getType = function() { - return this._ast.type ; -} - -Reader.prototype.getAst = function() { - return this._ast; -} - -exports.fillExprOnRow = function(row, refCols, refPos) { - var c, pos, val; - for (var j = 0; j < refCols.length; j++) { - c = refCols[j]; - pos = refPos[j]; - val = row[pos]; - //inspect(e); - fill(c, val); - } -} - -exports.createBinaryExpr = function(op, left, right) { - var o = { - operator: op, - type : 'binary_expr' - } - if (left && left.type) { - o.left = left; - } else { - o.left = fill({}, left); - } - - if (op == 'BETWEEN' ) { - var beg = fill({}, right[0]) - var end = fill({}, right[1]) - o.right = { - type : 'expr_list', - value :[beg, end] - }; - } else { - if ((right && right.type) || Array.isArray(right)) { - o.right = right; - } else { - o.right = fill({}, right); - } - } - return o; -} - -exports.fill = fill; - -function fill(tpl, v) { - var t = typeof v; - if (t == 'string') { - tpl.type = 'string'; - tpl.value = v; - } else if (t == 'number') { - tpl.type = 'number'; - tpl.value = v; - } else if (t === 'boolean') { - tpl.type = 'bool'; - tpl.value = v; - } else if (v === null) { - tpl.type = 'null', - tpl.value = null - } else { - } - return tpl; -} - - diff --git a/lib/context.js b/lib/context.js deleted file mode 100644 index 476c479..0000000 --- a/lib/context.js +++ /dev/null @@ -1,33 +0,0 @@ -// (C) 2011-2013 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - -var Table = require('./table'); - -exports.getBindVar = getBindVar; - -var env = {}; -exports.setctx = function(obj) { - env = obj || {}; -} - -function getBindVar(expr, ctx) { - ctx = ctx || env; - var varid = expr.name; - var members = expr.members; - - var obj = ctx[varid]; - var index; - for(var i = 0; i < members.length; i++) { - index = members[i]; - if (obj instanceof Table) { - obj = obj.getColumn(index); - } else { - obj = obj[index]; - } - } - return obj; -} diff --git a/lib/engine.js b/lib/engine.js deleted file mode 100644 index 34e4466..0000000 --- a/lib/engine.js +++ /dev/null @@ -1,356 +0,0 @@ -// (C) 2011-2013 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - -var Table = require('./table'); -var Context = require('./context'); - -exports.run = run; - -function debug(str) { - //console.log(str); -} - -function inspect(obj) { - //console.log(require('util').inspect(obj, false, 10, true)); -} - -function run(e) { - //inspect(e); - var t = e.type; - var res; - //todo - switch (t) { - case 'unary_expr' : - res = runUnaryExpr(e); - break; - case 'binary_expr': - res = runBinaryExpr(e); - break; - //TODO, now only count is claasified as aggr - case 'aggr_func': - res = runAggrFunc(e); - break; - case 'function' : - res = runFunction(e); - break; - case 'var': - res = Context.getBindVar(e); - break; - case 'array': - //debug('arr'); - //inspect(e); - res = getArrayVal(e); - // code - break; - default : - //for number ,string , bool, null - res = e.value; - } - return res; -} - -//only `NOT` or `!` now -function runUnaryExpr(e) { - return !(run(e.expr)); -} - -function runBinaryExpr(e){ - var op = e.operator; - var left = e.left; - var right = e.right; - var res; - switch(op) { - case '+' : - res = run(left) + run(right); - break; - case '-' : - res = run(left) - run(right); - break; - case '*' : - res = run(left) * run(right); - break; - case '/' : - res = run(left) / run(right); - break; - case '%' : - res = run(left) % run(right); - break; - case '=' : - res = run(left) == run(right); - break; - case '>' : - res = run(left) > run(right); - break; - case '>=' : - res = run(left) >= run(right); - break; - case '<' : - res = run(left) < run(right); - break; - case '<=' : - res = run(left) <= run(right); - break; - case '!=' : - case '<>' : - res = run(left) != run(right); - break; - case 'IS' : - res = run(left) == run(right); - break; - case 'LIKE' : - var lval = run(left); - var rval = run(right); - res = like(lval, rval); - break; - case 'BETWEEN': - var lval = run(left); - var rarr = getExprListVal(right); - var rbeg = rarr[0]; - var rend = rarr[1]; - res = (lval >= rbeg && lval <= rend); - break; - case 'IN' : - var lval = run(left); - var rarr = getExprListVal(right); - res = (rarr.indexOf(lval) >= 0) - break; - case 'NOT IN' : - var lval = run(left); - var rarr = getExprListVal(right); - res = (rarr.indexOf(lval) < 0); - break; - case 'AND' : - var lval = run(left); - var rval = run(right); - res = (lval && rval) - break; - case 'OR' : - var lval = run(left); - if (lval) { - res = true; - } else { - res = run(right); - } - break; - default : - res = 'binary operator not supported now :' + op - } - return res; -} - -/** -* { -* type: 'expr_list', -* value: [ -* { -* type: 'literal_list', -* table: 'a', -* column: 'id', -* value: [ 1, 2, 2, 3, 3, 5, 6 ] -* } -* ] -* } -*/ -function getAggrListVal(eList) { - var res = []; - if (Array.isArray(eList)) { - return eList; - }else if (eList && eList.value && - eList.value[0] && - Array.isArray(eList.value[0].value)) { - res = eList.value[0].value; - } - return res; -} - -function getArrayVal(e) { - var res = []; - var vals = e.value; - var v; - for (var i = 0; i < vals.length; i++) { - v = run(vals[i]); - res.push(v); - } - return res; -} - -exports.getExprListVal = getExprListVal; - -function getExprListVal(eList) { - var res = []; - if (Array.isArray(eList)) { - res = eList; - } else if (eList.type == 'expr_list') { - res = getArrayVal(eList); - /* - var vals = eList.value; - for (var i = 0; i < vals.length; i++) { - res.push(vals[i].value); - } - */ - } else { - throw new Error('error expr list type'); - } - return res; -} - -var fnMap = { - 'FLOOR' : floor, - 'CEIL' : ceiling, - 'CEILING' : ceiling, - 'UNIQUE' : unique -}; - -var aggrMap = { - 'MAX' : max, - 'MIN' : min, - 'COUNT' : count, - 'SUM' : sum, - 'AVG' : avg -} - -//todo, do distinct filter or something -function runAggrFunc(e) { - var fn = aggrMap[e.name]; - return fn(e.args); -} - -function runFunction(e) { - var name = e.name; - if (name) { - name = name.toUpperCase(); - } - var fn; - var args; - if (fn = fnMap[name]) { - args = getExprListVal(e.args); - debug('fn : ' + name); - debug('args: '); - inspect(args); - return fn(args); - } else { - throw new Error('function not supported for :' + e.name); - } -} - -function like(str, pattern) { - //now only support 'str%' or 'str' - //console.log('str: ' + str + ', pattern : '+ pattern); - var pos = pattern.indexOf('%'); - if (pos < 0) { - return (str.indexOf(pattern) >= 0); - } else { - var p = pattern.substr(0, pos); - if (pos == pattern.length - 1) { - return (str.indexOf(p) == 0); - } else { - return (str.indexOf(p) >= 0); - } - } -} - -function count(args){ - var ret; - var arr = getAggrListVal(args.expr.value); - if (Array.isArray(arr)) { - ret = arr.length; - } else { - ret = 1; - } - return ret; -} - -function max(args){ - //debug('call max'); - //inspect(arr); - var ret; - var arr = getAggrListVal(args.expr.value); - if(Array.isArray(arr)){ - ret = arr[0]; - for(var i = 1; i < arr.length; i++){ - if(arr[i] > ret) ret = arr[i]; - } - } - return ret; -} - -function min(args){ - //debug('call max'); - //inspect(arr); - var ret; - var arr = getAggrListVal(args.expr.value); - if(Array.isArray(arr)){ - ret = arr[0]; - for(var i = 1; i < arr.length; i++){ - if(arr[i] < ret) ret = arr[i]; - } - } - return ret; -} - -//we only deal the first arg, -function floor(arr){ - if(Array.isArray(arr)){ - return Math.floor(arr[0]); - } else { - return Math.floor(arr); - } -} - -function ceiling(arr){ - if(Array.isArray(arr)){ - return Math.ceil(arr[0]); - } else { - return Math.ceil(arr); - } -} - -function unique(arr){ - var res = []; - var map = {}; - var ele, key; - for (var i = 0; i < arr.length; i++){ - ele = arr[i]; - key = (typeof ele ) + ele; - if(map[key] === undefined){ - map[key] = true; - res.push(ele); - } - } - return res; -} - -function sum(args){ - //debug('call sum'); - //inspect(arr); - var ret; - var arr = getAggrListVal(args.expr.value); - if (Array.isArray(arr)){ - ret = arr[0]; - for(var i = 1; i < arr.length; i++){ - ret += arr[i]; - } - } - return ret; -} - -function avg(args){ - //debug('call sum'); - //inspect(arr); - var ret; - var len = 1; - var arr = getAggrListVal(args.expr.value); - if(Array.isArray(arr)){ - ret = arr[0]; - for(var i = 1; i < arr.length; i++){ - ret += arr[i]; - } - len = arr.length; - } - return ret/len; -} - diff --git a/lib/executor.js b/lib/executor.js deleted file mode 100644 index 5e3a234..0000000 --- a/lib/executor.js +++ /dev/null @@ -1,190 +0,0 @@ -// (C) 2011-2013 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - -var doWhereFilter = require('../base/where'); -var doColumnSelect = require('../base/column'); -var doOrderby = require('../base/orderby'); -var doLimitFilter = require('../base/limit'); -var doDistinctFilter = require('../base/distinct'); -var doPostprocess = require('../base/postprocess'); - -var Table = require('./table'); -var Context = require('./context'); -var AstHelper = require('./ast_helper'); - -var AstReader = AstHelper.Reader; -var expandSelect = AstHelper.expandSelect; -var shrinkSelect = AstHelper.shrinkSelect; - -function debug(str) { - //console.log(str); -} - -function inspect(obj) { - //console.log(require('util').inspect(obj, false, 10, true)); -} - -var load = loadData; -exports.setLoader = function(fn) { - load = fn; -} - -function loadData(ast, env, cb) { - var rawData = { - columns: [ 'hello', 'nQuery' ], - data: [ - [ - 'hi, dear', - 'you should add your own data sources...' - ] - ] - }; - cb(null, rawData); -} - -function select(dc, ar) { - if (dc.columns.length == 0) { - //TODO, if select '*' and empty - //inspect(dc.columns); - return { - columns : ar.getAsNames(), - data : dc.data - } - } - //debug('do Select now'); - //debug('before preprocess'); - //inspect(dc); - //inspect(ar); - //dc = doPreprocess(dc, ar); - //adjustSelectAst(ast); - //debug('after preprocess') - //inspect(dc); - - var ast = ar.getAst(); - var where = ast.where; - if (where && where != '') { - dc = doWhereFilter(dc, where); - } - - var sels = ast.columns; - if (sels != '*') { - //do select-column expand - var ob = ast.orderby; - if (Array.isArray(ob) && ob.length > 0) { - //debug('before expand:') - //inspect(sels); - sels = expandSelect(sels, ob); - //debug('after expand:') - //inspect(sels); - } - } - - //debug('before column select'); - //inspect(dc); - - var gb = ar.getGroupby(); - //dc = doGroupbyFilter (dc, ast); - //data = doHavingFilter (data, ast.having); - //do groupby, and column select - dc = doColumnSelect(dc, sels, gb); - - //debug('before orderby'); - //inspect(dc); - var orderby = ar.getOrderby(); - if (orderby.length > 0) { - dc = doOrderby(dc, orderby); - //do select-column shrink - //debug('before shrink, the columns'); - //inspect(ast.columns); - if (sels != '*') { - dc = shrinkSelect(dc, ast.columns); - } - } - - //debug('after orderby'); - //inspect(dc); - - if (ar.isDistinct()) { - dc = doDistinctFilter(dc, ar); - } - - //debug('before limit'); - //inspect(dc); - var limits = ar.getLimits(); - if (Array.isArray(limits) && limits.length == 2){ - dc = doLimitFilter(dc, limits); - } - - dc = doPostprocess(dc, ar); - //debug('select will return'); - //inspect(dc); - return dc; -} - -//NOTE the diffrence -exports.doSelectFilter = doSelectFilter; -exports.doSelectOnTable = select; - -function doSelectFilter(dc, ar) { - var tbl = new Table(dc); - var tbName = ar.getTableOrig(); - var tbAlias = ar.getTableAlias(); - tbl = tbl.get(tbName, tbAlias); - return select(tbl, ar); -} - -function doPostFilter(dc, ar, ctx) { - //set the global unique ctx - Context.setctx(ctx); - var type = ar.getType(); - switch (type) { - case 'select' : - dc = doSelectFilter(dc, ar); - break; - //TODO - case 'update' : - dc = update(ar); - break; - case 'insert' : - case 'replace' : - dc = replace_insert(ar); - break; - default: - throw new Error('not supported stmt :' + type); - break; - } - return dc; -} - -exports.runAST = runAST; - -function runAST(ast, ctx, cb) { - //inspect(ast); - if (typeof(ctx) == 'function' && !cb) { - cb = ctx; - ctx = {}; - } - - var ar = new AstReader(ast); - load(ar, ctx, function(err, dc, filter) { - if (err) { - cb(err); - } else { - //for sqldriver , filter maybe null, - //for kv-type, the filter could be ar if you don't mask some key-column predicates - if (filter) { - try { - dc = doPostFilter(dc, filter, ctx); - } catch (e) { - cb(e); - return; - } - } - cb(null, dc); - } - }); -} diff --git a/lib/extractor.js b/lib/extractor.js deleted file mode 100644 index 612290f..0000000 --- a/lib/extractor.js +++ /dev/null @@ -1,158 +0,0 @@ -// (C) 2011-2013 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - -var Engine = require('./engine'); -var Context = require('./context'); - -var run = Engine.run; -var getExprListVal = Engine.getExprListVal; - -//kv storage info -/* -{ - storageType : 'kv', - primaryKeys : [id, name], - prefixMatch : true, - rangeSupport : true -} -*/ - -exports.getKeyInfo = getKeyInfoOnWhere; - -function inspect(obj) { - //console.log(require('util').inspect(obj, false, 10)); -} - -function debug(str) { - //console.log(str); -} - -function splitOrExpr(where) { - var cur, t; - var res = []; - var stack = [where]; - while(stack.length > 0) { - cur = stack.pop(); - if (cur.type == 'binary_expr' && cur.operator == 'OR') { - stack.push(cur.right); - stack.push(cur.left); - } else { - res.push(cur) - } - } - return res; -} - -function getKeyInfoOnAndExpr(expr, options) { - var cur, t, info; - var res = {}; - var stack = [expr]; - var k, val; - while(stack.length > 0) { - cur = stack.pop(); - t = cur.type; - if (t == 'binary_expr') { - var l = cur.left; - var r = cur.right; - var op = cur.operator; - if (op == 'AND' || op == 'OR') { - stack.push(r); - stack.push(l); - } else if (l.type == 'column_ref') { - if (info = getKeyColumn(l, r, op, options)) { - mergeKeyInfo(res, info); - } - } - } - } - return res; -} - -function mergeKeyInfo(res, info) { - var k, val; - for(k in info) { - if (res[k] == undefined) { - res[k] = []; - } - val = info[k]; - if (k == 'IN' && Array.isArray(val)) { - //only single-key batch values could be pushed - res[k] = res[k].concat(val); - } else { - res[k].push(val); - } - } -} - -function appendKeyInfo(res, info) { - var k, val; - for(k in info) { - if (res[k] == undefined) { - res[k] = info[k]; - } else { - res[k] = res[k].concat(info[k]); - } - } -} - -function getKeyColumn(l, r, op, options) { - var keys = options.primaryKeys; - var res; - //TODO ,now only support single primary key - if (keys.length == 1) { - var key = keys[0]; - if (l.column == key) { - //TODO , check types - if (op == '=' || op == 'IN') { - res = {}; - if (typeof(r) == 'object' && r.type == 'expr_list') { - res['IN'] = getExprListVal(r); - } else { - res['IN'] = run(r); - } - } if (options.rangeQuery && op == 'BETWEEN') { - res = {}; - if (typeof(r) == 'object' && r.type == 'expr_list') { - res['BETWEEN'] = getExprListVal(r); - } else { - var rbeg = run(r[0]); - var rend = run(r[1]); - res['BETWEEN'] = [rbegin, rend]; - } - } if (options.prefixMatch && op == 'LIKE') { - var val = run(r); - if (typeof val == 'string') { - var pos = val.indexOf('%'); - if (pos > 0 && pos == val.length - 1) { - res = {}; - res['LIKE'] = val.substr(0, pos); - } - } - } - } - } - return res; -} - -function getKeyInfoOnWhere(where, options) { - var i ,info; - var res = {}; - var andExprs = splitOrExpr(where); - debug('AndExprs'); - inspect(andExprs); - for (i = 0; i < andExprs.length; i++) { - info = getKeyInfoOnAndExpr(andExprs[i], options); - //inspect(info); - if (Object.keys(info).length == 0) { - throw Error('requird primary keys not ful-filled'); - } else { - appendKeyInfo(res, info); - } - } - return res; -} - diff --git a/lib/jobs.js b/lib/jobs.js deleted file mode 100644 index 5a3cf55..0000000 --- a/lib/jobs.js +++ /dev/null @@ -1,67 +0,0 @@ -// (C) 2011-2013 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - -var Context = require('./context'); - -exports.doSequential = doSequentialJobs; -exports.doConcurrent = doConcurrentTasks; - -function doSequentialJobs(jobs, cb) { - if (jobs.length == 0) { - cb(null); - } - var count = 0; - function jobCb(err) { - count++; - if (err) { - cb(err); - } else { - if (count == jobs.length) { - cb(null); - } else { - doNextJob(); - } - } - } - - function doNextJob() { - var job = jobs[count]; - doConcurrentTasks(job, jobCb) - } - - doNextJob(); -} - -function doConcurrentTasks(tasks, cb) { - if (!Array.isArray(tasks)) { - tasks = [tasks]; - } - - var count = 0; - var finished = false; - function taskCb(err) { - if (finished) { - return; - } - count++; - if (err) { - finished = true; - cb(err); - } else { - if (count == tasks.length) { - finished = true; - cb(null); - } - } - } - - for (var i = 0; i < tasks.length; i++) { - var task = tasks[i]; - task.run(taskCb); - } -} - diff --git a/lib/join.js b/lib/join.js deleted file mode 100644 index ba0894b..0000000 --- a/lib/join.js +++ /dev/null @@ -1,273 +0,0 @@ -// (C) 2011-2013 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - -var Context = require('./context'); - -exports.leftJoin = leftJoin; -exports.innerJoin = innerJoin; - -function debug(str){ - //console.log(str); -} - -function inspect(obj){ - //console.log(require('util').inspect(obj, false, 10)); -} - -function leftJoin(ta ,tb, on){ - var ka = on.left; - var kb = on.right; - - var klen = kb.length; - var i, j, k; - - //hash b like that: - // kb1 : [ele1, ele2] - // kb2 : [el3, ele5]; - var adata = ta.data; - var bdata = tb.data; - var tblen = bdata.length; - var talen = adata.length; - - var ele; - var aele; - var bele; - var key; - var hba; - - var tbCol, found; - var apos = []; - var acols = ta.columns; - for (i = 0; i < klen; i++) { - for (j = 0; j < acols.length; j++){ - found = false; - for (k = 0; k < acols[j].length; k++) { - tbCol = acols[j][k]; - if (tbCol.table == ka[i].table && tbCol.column == ka[i].column) { - apos.push(j) - found = true; - break; - } - } - if (found) break; - } - } - - - var bpos = []; - var bcols = tb.columns; - for (i = 0; i < klen; i++) { - for (j = 0; j < bcols.length; j++) { - found = false; - for (k = 0; k < bcols[j].length; k++) { - tbCol = bcols[j][k]; - if (tbCol.table == kb[i].table && tbCol.column == kb[i].column) { - bpos.push(j) - found = true; - break; - } - } - if (found) break; - } - } - - //debug(bcols :" + bcols); - //debug("bpos :" + bpos); - - var rcols = [].concat(acols); - for (i = 0; i < apos.length; i++) { - rcols[apos[i]] = rcols[apos[i]].concat(bcols[bpos[i]]); - } - - var diffpos = []; - for (i = 0; i < bcols.length; i++) { - if (bpos.indexOf(i) < 0) { - rcols.push(bcols[i]); - diffpos.push(i); - } - } - var difflen = diffpos.length; - - //debug("rcols :" + rcols); - //debug("diffpos :" + diffpos); - - var dummyhb = []; - for (i = 0; i < bcols.length; i++){ - dummyhb.push(null); - } - dummyhb = [dummyhb]; - - ka = apos; - kb = bpos; - - var hb = {}; - for (i = 0; i < tblen; i++) { - bele = bdata[i]; - key = ""; - for (j = 0; j < klen; j++) { - key += bele[kb[j]]; - key += ","; - } - if (hb[key] == null) hb[key] = []; - hb[key].push(bele); - //debug("bhash index :" + bid); - } - - //result data - var rdata = []; - - for (i = 0; i < talen; i++) { - aele = adata[i]; - //get the related b elements array - key = ""; - for (j = 0; j < klen; j++) { - key += aele[ka[j]]; - key += "," - } - //debug("ta.index : " + key); - hba = hb[key]; - //inspect(hba); - if(hba == null) hba = dummyhb; - //else bingo++; - for (j = 0; j < hba.length; j++) { - ele = [].concat(aele); - //ele = (aele); - bele = hba[j]; - for (k = 0; k < difflen; k++) { - ele.push(bele[diffpos[k]]); - } - rdata.push(ele); - } - } - return { - columns : rcols, - data : rdata - }; -} - -function innerJoin(ta ,tb, on){ - var ka = on.left; - var kb = on.right; - - var klen = kb.length; - var i, j, k; - - //hash b like that: - // kb1 : [ele1, ele2] - // kb2 : [el3, ele5]; - var adata = ta.data; - var bdata = tb.data; - var tblen = bdata.length; - var talen = adata.length; - - var ele; - var aele; - var bele; - var key; - var hba; - - var tbCol, found; - - var apos = []; - var acols = ta.columns; - for (i = 0; i < klen; i++) { - for (j = 0; j < acols.length; j++){ - found = false; - for (k = 0; k < acols[j].length; k++) { - tbCol = acols[j][k]; - if (tbCol.table == ka[i].table && tbCol.column == ka[i].column) { - apos.push(j) - found = true; - break; - } - } - if (found) break; - } - } - - var bpos = []; - var bcols = tb.columns; - for (i = 0; i < klen; i++) { - for (j = 0; j < bcols.length; j++) { - found = false; - for (k = 0; k < bcols[j].length; k++) { - tbCol = bcols[j][k]; - if (tbCol.table == kb[i].table && tbCol.column == kb[i].column) { - bpos.push(j) - found = true; - break; - } - } - if (found) break; - } - } - //console.log("bcols :" + bcols); - //console.log("bpos :" + bpos); - - //concat the join keys - var rcols = [].concat(acols); - for (i = 0; i < apos.length; i++) { - rcols[apos[i]] = rcols[apos[i]].concat(bcols[bpos[i]]); - } - - var diffpos = []; - for (i = 0; i < bcols.length; i++) { - if (bpos.indexOf(i) < 0) { - rcols.push(bcols[i]); - diffpos.push(i); - } - } - var difflen = diffpos.length; - - //debug("rcols :" + rcols); - //debug("diffpos :" + diffpos); - ka = apos; - kb = bpos; - - var hb = {}; - for (i = 0; i < tblen; i++) { - bele = bdata[i]; - key = ""; - for (j = 0; j < klen; j++){ - key += bele[kb[j]]; - key += ","; - } - if (hb[key] == null) hb[key] = []; - hb[key].push(bele); - //debug("bhash index :" + bid); - } - - //result data - var rdata = []; - - for (i = 0; i < talen; i++) { - aele = adata[i]; - //get the related b elements array - key = ""; - for (j = 0; j < klen; j++) { - key += aele[ka[j]]; - key += "," - } - //debug("ta.index : " + key); - hba = hb[key]; - if (hba) { - for (j = 0; j < hba.length; j++) { - bele = hba[j]; - ele = [].concat(aele); - for (k = 0; k < difflen; k++) { - ele.push(bele[diffpos[k]]); - } - rdata.push(ele); - } - } - } - return { - columns : rcols, - data : rdata - }; -} - diff --git a/lib/merger.js b/lib/merger.js deleted file mode 100644 index 8dbf3f7..0000000 --- a/lib/merger.js +++ /dev/null @@ -1,49 +0,0 @@ -var Table = require('./table'); - -var leftJoin = require('../base/join').leftJoin; -var innerJoin = require('../base/join').innerJoin; - -function debug(str) { - //console.log(str); -} - -function inspect(obj) { - //console.log(require('util').inspect(obj, false, 10)); -} - -exports.join = function (ltb, rtb, op, ons ) { - //debug('ons:') - //inspect(ons); - //debug('ops:') - //inspect(op); - var fn = leftJoin; - if (!op || op == '' || op == 'JOIN' || op == 'INNER JOIN'){ - fn = innerJoin; - } - //inspect(onParam); - var table = fn(ltb, rtb, ons); - return table; -} - -exports.union = function(dArr) { - if (dArr.length == 1) { - return dArr[0]; - } - - var lCols = []; - for(var i = 0; i < dArr.length; i++){ - lCols = dArr[i].getColNames(); - if(lCols.length > 0) break; - } - var cols = [].concat(lCols); - var data = []; - for(var i = 0; i < dArr.length; i++){ - var cData = dArr[i].getRows(); - data = data.concat(cData); - } - - return new Table({ - columns : cols, - data : data - }); -} diff --git a/lib/parse.js b/lib/parse.js new file mode 100644 index 0000000..e69de29 diff --git a/lib/parser.js b/lib/parser.js deleted file mode 100644 index 5021cfb..0000000 --- a/lib/parser.js +++ /dev/null @@ -1,137 +0,0 @@ -// (C) 2011-2013 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - -var Parser = require('../base/nquery'); -var MCache = require('../base/mcache'); - -var clone = require('./tool').clone; - -function debug(str) { - //console.log(str); -} - -function inspect(obj) { - //console.log(require('util').inspect(obj, false, 10, true)); -} - -exports.parse = function (sql){ - var ap = Parser.parse(sql); - return ap.ast; -} - -var cache = new MCache(1000); - -exports.tplParse = function (sql, data){ - if (!data || typeof(data) != 'object') { - data = {}; - } - //get cache first - var ap, ast, tpls; - if (Object.keys(data).length > 0) { - //debug('try get cache'); - ap = cache.get(sql); - } - if (!ap) { - ap = Parser.parse(sql); - tpls = ap.param; - if (tpls.length > 0) { - //debug('set for : ' + sql); - cache.set(sql, ap); - } - } else { - tpls = ap.param; - } - ast = ap.ast; - //the params were associated with the ast objeect - //only set when there are params - if (tpls.length > 0) { - inspect(ast); - inspect(tpls); - inspect(data); - ast = linkAstData(ast, tpls, data); - } - return ast; -} - -function linkAstData(ast, tpls, data) { - var i, bpl, tpl, value; - var backup = []; - for (i = 0; i < tpls.length; i++) { - tpl = tpls[i]; - value = data[tpl.value]; - - if (value === undefined) { - throw new Error('the template element not instantiated :' + tpl.value); - } - //do backup first - bpl = {}; - bpl.value = tpl.value; - if (tpl.room) { - bpl.room_value = clone(tpl.room.value); - } - backup.push(bpl); - } - //we MUST seperate the two steps, for may two tpls use the same room - for (i = 0; i < tpls.length; i++) { - tpl = tpls[i]; - value = data[tpl.value]; - //debug('\ninstantiate :' + tpl.value); - instantiateTpl(tpl, value) - } - - ast = clone(ast); - //debug('before restore ,the backup'); - //inspect(backup); - //restore the point of tpl/ast - for (i = 0; i < tpls.length; i++) { - tpl = tpls[i]; - bpl = backup[i]; - - tpl.type = 'param'; - tpl.value = bpl.value; - if (tpl.room) { - tpl.room.value = bpl.room_value; - } - } - return ast; -} - -function instantiateTpl(tpl, v) { - var t = typeof v; - if (Array.isArray(v)) { - //TODO ,use maybe should support mixed - //type of array and literal values in param and set it at the speficfic position - var list = []; - if (tpl.room && Array.isArray(tpl.room.value)) { - list = tpl.room.value; - } else { - tpl.type = 'expr_list'; - tpl.value = list; - } - for (var i = 0; i < v.length; i++) { - var e = instantiateTpl({}, v[i]); - list.push(e); - } - } else if(tpl.room && Array.isArray(tpl.room.value)) { - tpl.room.value.push(instantiateTpl({}, v)); - } else if (t == 'string') { - tpl.type = 'string'; - tpl.value = v; - } else if (t == 'number') { - tpl.type = 'number'; - tpl.value = v; - } else if (t === 'boolean') { - tpl.type = 'bool'; - tpl.value = v; - } else if (v === null) { - tpl.type = 'null', - tpl.value = null - } - return tpl; -} - - diff --git a/lib/query.js b/lib/query.js deleted file mode 100644 index 900a653..0000000 --- a/lib/query.js +++ /dev/null @@ -1,34 +0,0 @@ -// (C) 2011-2013 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - -var Parser = require('./parser'); -var Executor = require('./executor'); - -var Procedure = require('../base/procedure'); -var Topology = require('../base/topology'); - -var runAST = Executor.runAST; -var runProc = Procedure.run; -var doAstOrder = Topology.order; - -exports.runSQL = function (str, cb) { - var ast; - try { - ast = Parser.parse(str); - } catch (e) { - cb(e) - return; - } - - if (Array.isArray(ast)) { - var stps = doAstOrder(ast); - runProc(stps, cb); - } else { - runAST(ast, cb); - } -} - diff --git a/lib/adapter.js b/lib/stringify.js similarity index 72% rename from lib/adapter.js rename to lib/stringify.js index 95c1046..fa3e626 100644 --- a/lib/adapter.js +++ b/lib/stringify.js @@ -1,15 +1,13 @@ // (C) 2011-2013 Alibaba Group Holding Limited. // This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. +// modify it under the terms of the GNU General Public License +// version 2 as published by the Free Software Foundation. // Author :windyrobin -var Context = require('./context'); - //http://dev.mysql.com/doc/refman/5.0/en/string-literals.html // for mysql only -// NOTE: myfox != mysql + var escapeMap = { '\0' : '\\0', '\'' : '\\\'', @@ -23,12 +21,12 @@ var escapeMap = { // '%' : '\\%', // '_' : '\_' }; - + function escape(str) { var res = []; var c, e; for (var i = 0 ;i < str.length; i++) { - c = str[i]; + c = str[i]; e = escapeMap[c]; if (e) { c = e; @@ -38,31 +36,25 @@ function escape(str) { return res.join(''); } -function inspect(obj) { - //console.log(require('util').inspect(obj ,false, 10, true)); -} - function literalToSQL(l) { - var ret; var t = l.type; var v = l.value; - if (t == 'number') { - //nothing - } else if (t == 'string') { - v = "'" + escape(v) + "'"; - //v = '"' + v + '"'; - } else if (t == 'bool') { - v = v ? 'TRUE' : 'FALSE'; - } else if (t == 'null') { - v = 'NULL' - } else if (t == 'star') { + // if t === number, do nothing + if (t === 'string') { + v = '\'' + escape(v) + '\''; + //v = '"' + v + '"'; + } else if (t === 'bool') { + v = v ? 'TRUE' : 'FALSE'; + } else if (t === 'null') { + v = 'NULL'; + } else if (t === 'star') { v = '*'; } if (l.paren) { - return '(' + v + ')'; + return '(' + v + ')'; } else { - return v; + return v; } } @@ -71,15 +63,15 @@ function unaryToSQL(e) { if (e.paren) { return '(' + str + ')'; } else { - return str; + return str; } } function getExprListSQL(l) { - var es = []; + var es = []; for (var i = 0; i < l.length; i++) { - es.push(exprToSQL(l[i])) - } + es.push(exprToSQL(l[i])); + } return es; } @@ -88,13 +80,13 @@ function binaryToSQL(e) { var left = e.left; var right = e.right; - var lstr = exprToSQL(left); - var rstr = exprToSQL(right); + var lstr = exprToSQL(left); + var rstr = exprToSQL(right); if (Array.isArray(rstr)) { - if (op == '=') { + if (op === '=') { op = 'IN'; - } - if (op == 'BETWEEN') { + } + if (op === 'BETWEEN') { rstr = rstr[0] + ' AND ' + rstr[1]; } else { rstr = '(' + rstr.join(', ') + ')'; @@ -105,19 +97,18 @@ function binaryToSQL(e) { if (e.paren) { return '(' + str + ')'; } else { - return str; + return str; } } function aggrToSQL(e) { var args = e.args; - var expr = args.expr var str = exprToSQL(args.expr); var name = e.name; - if (name == 'COUNT') { + if (name === 'COUNT') { //inspect(args); - var d = args.distinct; - if (d && d != '') { + var distinct = args.distinct; + if (distinct) { str = 'DISTINCT ' + str; } } @@ -133,25 +124,23 @@ function funcToSQL(e) { if (e.paren) { return '(' + str + ')'; } else { - return str; + return str; } } function columnRefToSQL(e) { var str = e.column; - if (e.table && e.table != '') { + if (e.table) { str = e.table + '.' + str; } if (e.paren) { return '(' + str + ')'; } else { - return str; + return str; } } -exports.exprToSQL = exprToSQL; - function exprToSQL(e) { var t = e.type; var res ; @@ -175,21 +164,28 @@ function exprToSQL(e) { res = getExprListSQL(e.value); break; case 'var' : - res = varToSQL(e); + // res = varToSQL(e); + throw new Error('unsupported type `var`'); + case 'param': + res = paramToSql(e); break; default: - res = literalToSQL(e); + res = literalToSQL(e); } return res; } +function paramToSql(e) { + return e.value === '?' ? '?' : ':' + e.value; +} + function js2nSQLExpr(val) { var type = typeof val; - var obj = {} + var obj = {}; switch (type) { case 'string': case 'number': - obj.type = type + obj.type = type; obj.value = val; break; case 'boolean': @@ -212,26 +208,27 @@ function js2nSQLExpr(val) { obj.type = 'object'; obj.value = val; } - break + break; default: obj.type = 'unknown'; } return obj; } - +/* function varToSQL(e) { var val = Context.getBindVar(e); var expr = js2nSQLExpr(val); return exprToSQL(expr); } +*/ function unionToSQL(s, options) { var str = selectToSQL(s, options); var res = []; res.push(str); while (s._next) { - str = selectToSQL(s._next, options); - res.push('UNION') + str = selectToSQL(s._next, options); + res.push('UNION'); res.push(str); s = s._next; } @@ -248,64 +245,64 @@ function selectToSQL(s, options) { var limit = s.limit; var clauses = []; - var i, str; + var i, str, cs; options = options || {}; clauses.push('SELECT'); //distinct - if (distinct && distinct != '') { - clauses.push(distinct); + if (distinct) { + clauses.push(distinct); } - + //column clause //inspect(columns); - if (columns == '*') { + if (columns === '*') { clauses.push('*'); } else { - var cs = []; + cs = []; for (i = 0; i < columns.length; i++) { var ea = columns[i]; str = exprToSQL(ea.expr); - if (ea.as != '') { + if (ea.as) { str += (' AS ' + ea.as); } cs.push(str); - } + } clauses.push(cs.join(', ')); } //from clause if (Array.isArray(from)) { - clauses.push('FROM'); - var cs = []; var tbase = from[0]; + clauses.push('FROM'); + cs = []; str = tbase.table; - if (options.keep_db !== false && tbase.db != '') { + if (options.keep_db !== false && tbase.db) { str = tbase.db + '.' + str; } - if (tbase.as != '') { - str += ' AS ' + tbase.as + if (tbase.as) { + str += ' AS ' + tbase.as; } cs.push(str); for (i = 1; i < from.length; i++) { - var tref = from[i]; - if (tref.join && tref.join != '') { + var tref = from[i]; + if (tref.join) { str = ' ' + tref.join + ' '; } else { - str = ', '; + str = ', '; } - if (options.keep_db !== false && tref.db != '') { + if (options.keep_db !== false && tref.db) { str += (tref.db + '.'); } str += tref.table; - if (tref.as != '') { - str += ' AS ' + tref.as + if (tref.as) { + str += ' AS ' + tref.as; } - if (tref.on && tref.on != '') { - str += ' ON ' + exprToSQL(tref.on); + if (tref.on) { + str += ' ON ' + exprToSQL(tref.on); } cs.push(str); } @@ -313,18 +310,17 @@ function selectToSQL(s, options) { } //where clause - if (where && where != '') { - clauses.push('WHERE ' + exprToSQL(where)); + if (where) { + clauses.push('WHERE ' + exprToSQL(where)); } - + if (Array.isArray(groupby)) { var l = getExprListSQL(groupby); clauses.push('GROUP BY ' + l.join(', ')); } if (Array.isArray(orderby)) { - var l = getExprListSQL(orderby); - var cs = []; + cs = []; for (var i = 0; i < orderby.length; i++) { var o = orderby[i]; str = exprToSQL(o.expr); @@ -356,12 +352,12 @@ function updateToSQL(stmt, options) { res.push(stmt.table); } else { res.push(stmt.db + '.' + stmt.table); - } + } res.push('SET'); var cs = []; var sets = stmt.set; - var i, ele, str; + var i, str; for (i = 0; i < sets.length; i++) { str = sets[i].column + ' = ' + exprToSQL(sets[i].value); cs.push(str); @@ -369,9 +365,9 @@ function updateToSQL(stmt, options) { res.push(cs.join(', ')); - if (stmt.where && stmt.where != '') { - str = 'WHERE ' - str += exprToSQL(stmt.where); + if (stmt.where) { + str = 'WHERE '; + str += exprToSQL(stmt.where); res.push(str); } return res.join(' '); @@ -381,7 +377,7 @@ function replace_insertToSQL(stmt, options) { options = options || {}; var res = []; res.push(stmt.type.toUpperCase()); - res.push('INTO') + res.push('INTO'); if (options.keep_db === false) { res.push(stmt.table); } else { @@ -389,16 +385,16 @@ function replace_insertToSQL(stmt, options) { } res.push('(' + stmt.columns.join(', ') + ')'); - res.push('VALUES') + res.push('VALUES'); - var i, ele, str; + var i; var cs = []; var vs = stmt.values; for (i = 0; i < vs.length; i++) { var es = vs[i].value; var rs = []; for (var j = 0; j < es.length; j++) { - rs.push(exprToSQL(es[j])); + rs.push(exprToSQL(es[j])); } cs.push('(' + rs.join(', ') + ')'); } @@ -407,25 +403,39 @@ function replace_insertToSQL(stmt, options) { return res.join(' '); } - -exports.toSQL = function (stmt, options) { +/** + * stringify the ast to sql string + * @param {AST} ast ast + * @param {Object} opt options + * @return {[type]} [description] + */ +module.exports = function (ast, opt) { + var options = { + keep_db: true, + offset: false + }; + for (var k in opt) { + options[k] = opt[k]; + } var res ; - switch (stmt.type) { + switch (ast.type) { case 'select' : - res = unionToSQL(stmt, options); + res = unionToSQL(ast, options); break; case 'update' : - res = updateToSQL(stmt, options); + res = updateToSQL(ast, options); break; case 'insert' : case 'replace': - res = replace_insertToSQL(stmt, options); + res = replace_insertToSQL(ast, options); break; case 'delete' : - res = deleteToSQL(stmt, options); - break; + throw new Error('ERROR TYPE :' + ast.type + ', NOT SUPPORTED'); default : - throw new Error('ERROR TYPE :' + stmt.type + ', NOT SUPPORTED'); + throw new Error('ERROR TYPE :' + ast.type + ', NOT SUPPORTED'); } return res; -} +}; + +module.exports.exprToSQL = exprToSQL; + diff --git a/lib/table.js b/lib/table.js deleted file mode 100644 index f4e040b..0000000 --- a/lib/table.js +++ /dev/null @@ -1,137 +0,0 @@ -// (C) 2011-2013 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - -module.exports = Table; - -function debug(str){ - //console.log(str); -} - -function inspect(obj){ - //debug(require('util').inspect(obj, false, 10)); -} - -/** - * @param {Object} obj could be like : - * { - * columns : [ - * f0 , - * f1 , - * f3 - * ], - * data : [ - * ['a', 'b' , 'c'], - * ['b', 'd' , 'e'], - * ... - * ] - * } - * or format like that : - * [ - * {f0 : 'a', f1 : 'b', f2 : 'c'}, - * {f0 : 'b', f1 : 'd', f2 : 'e'}, - * ... - * ] - * - * @param {String} alias, the table alias, if not null , - * we will use this as the column prefix - */ -function Table(obj) { - this._colNames = []; - this._rows = []; - - if (obj != null) { - if (Array.isArray(obj)) { - var cols = []; - var data = []; - var i, o, row, col; - for (i = 0; i < obj.length; i++) { - o = obj[i]; - row = []; - for (col in o) { - //init columns; - if (i == 0) { - cols.push(col); - } - row.push(o[col]); - } - data.push(row); - } - this._colNames = cols; - this._rows = data; - } else if (Array.isArray(obj.columns) && Array.isArray(obj.data)) { - //if we think the columns are already 2d - this._colNames = obj.columns; - this._rows = obj.data; - } - } -} - -Table.prototype.getColumn = function(col){ - var res = []; - var rows = this._rows; - var rLen = rows.length; - var pos = this._colNames.indexOf(col); - if (pos >= 0) { - for(var i = 0; i < rLen; i++){ - res.push(rows[i][pos]); - } - } else if(rLen > 0) { - throw new Error('no column found for : ' + col); - } - return res; -} - -Table.prototype.getColNames = function(){ - return this._colNames; -} - -Table.prototype.setColNames = function(arr){ - this._colNames = arr; -} - -Table.prototype.getRows = function(){ - return this._rows; -} - -Table.prototype.get = function(table, alias){ - var cols = this._colNames; - var cs, cname; - var fcols = []; - for (var i = 0; i < cols.length; i++) { - cname = cols[i]; - cs = []; - cs.push({ - table : table, - column: cname - }) - if (alias || alias === '' ) { - cs.push({ - table : alias, - column: cname - }) - } - fcols.push(cs); - } - return { - columns : fcols, - data : this._rows - }; -} - -//only be called once,for it will pop the colNames -Table.prototype.getData = function(){ - return { - __nsql_type__ : 'table', - columns : this._colNames, - data : this._rows - }; -} - -Table.prototype.setRowData = function(d){ - this._rows = d; -} - diff --git a/lib/tool.js b/lib/tool.js deleted file mode 100644 index 8b51d42..0000000 --- a/lib/tool.js +++ /dev/null @@ -1,32 +0,0 @@ -// (C) 2011-2013 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin - -exports.clone = clone; - -function clone(obj) { - var type = typeof(obj); - if ('object' == type && null !== obj) { - var res; - if (Array.isArray(obj)) { - res = []; - for (var i =0, l = obj.length; i < l; i++) { - res.push(clone(obj[i])); - } - } else { - res = {}; - var k, v; - var keys = Object.keys(obj); - for (var i =0, l = keys.length; i < l; i++) { - k = keys[i]; - v = clone(obj[k]) - res[k] = v; - } - } - return res; - } - return obj; -} diff --git a/package.json b/package.json index 6ae1e2e..a727fa0 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,11 @@ { - "author": "windyrobin", - "name": "node-query", - "description": "general sql query interface for hybrid data sources", - "version": "0.3.3", + "author": "windyrobin (https://github.com/windyrobin)", + "maintainers": [ + "fish (https://github.com/fishbar)" + ], + "name": "node-sqlparser", + "description": "a sql parser for node.js", + "version": "1.0.4", "repository": { "url": "git://github.com/alibaba/nquery.git" }, @@ -12,12 +15,11 @@ "engines": { "node": ">=0.8.0" }, - "dependencies": { - }, + "dependencies": {}, "devDependencies": { - "pegjs": ">=0.7.0", + "pegjs": "0.10.0", "mocha": ">=1.0.0", - "should":">=1.2.0" + "should": ">=1.2.0" }, "readmeFilename": "README.md", "main": "index.js", @@ -25,11 +27,9 @@ "test": "test" }, "keywords": [ - "SQL", - "Engine", - "Hybird", - "Data", - "Source" + "sql parser", + "sql ast", + "custom sql" ], - "license": "GPLv2" + "license": "GPL-2.0" } diff --git a/peg/nquery-doc.bnf b/peg/nquery-doc.bnf deleted file mode 100644 index d60fb43..0000000 --- a/peg/nquery-doc.bnf +++ /dev/null @@ -1,785 +0,0 @@ -{ - var util = require('util'); - - function debug(str){ - console.log(str); - } - - function inspect(obj){ - console.log(util.inspect(obj, false, 10)); - } - - function createUnaryExpr(op, e) { - return { - type : 'unary_expr', - operator : op, - expr : e - } - } - - function createBinaryExpr(op, left, right) { - return { - type : 'binary_expr', - operator : op, - left : left, - right : right - } - } - - function createList(head, tail) { - var result = [head]; - for (var i = 0; i < tail.length; i++) { - result.push(tail[i][3]); - } - return result; - } - - function createExprList(head, tail) { - var epList = createList(head, tail); - var exprList = []; - var ep; - for (var i = 0; i < epList.length; i++) { - ep = epList[i]; - //the ep has already added to the global params - if (ep.type == 'param') { - ep.room = exprList; - ep.pos = i; - } else { - exprList.push(ep); - } - } - return exprList; - } - - function createBinaryExprChain(head, tail) { - var result = head; - for (var i = 0; i < tail.length; i++) { - result = createBinaryExpr(tail[i][1], result, tail[i][3]); - } - return result; - } - - var reservedMap = { - 'SHOW' : true, - 'DROP' : true, - 'SELECT' : true, - 'UPDATE' : true, - 'CREATE' : true, - 'DELETE' : true, - 'INSERT' : true, - 'REPLACE' : true, - 'EXPLAIN' : true, - 'ALL' : true, - 'DISTINCT': true, - 'AS' : true, - 'TABLE' : true, - 'INTO' : true, - 'FROM' : true, - 'SET' : true, - 'LEFT' : true, - 'ON' : true, - 'INNER' : true, - 'JOIN' : true, - 'UNION' : true, - 'VALUES' : true, - 'EXISTS' : true, - 'WHERE' : true, - 'GROUP' : true, - 'BY' : true, - 'HAVING' : true, - 'ORDER' : true, - 'ASC' : true, - 'DESC' : true, - 'LIMIT' : true, - 'BETWEEN' : true, - 'IN' : true, - 'IS' : true, - 'LIKE' : true, - 'CONTAINS': true, - 'NOT' : true, - 'AND' : true, - 'OR' : true, - - //literal - 'TRUE' : true, - 'FALSE' : true, - 'NULL' : true - } - - //used for store refered parmas - var params = []; -} - -start - = &init ast:(union_stmt / update_stmt / replace_insert_stmt) { - return { - ast : ast, - param : params - } - } - -init = { params = []; return true; } - -union_stmt - = head:select_stmt tail:(__ KW_UNION __ select_stmt)* { - var cur = head; - for (var i = 0; i < tail.length; i++) { - cur._next = tail[i][3]; - cur = cur._next - } - return head; - } - -select_stmt - = select_stmt_nake - / s:('(' __ select_stmt __ ')') { - return s[2]; - } - -select_stmt_nake - = KW_SELECT __ - d:KW_DISTINCT? __ - c:column_clause __ - f:from_clause? __ - w:where_clause? __ - g:group_by_clause? __ - o:order_by_clause? __ - l:limit_clause? { - return { - type : 'select', - distinct : d, - columns : c, - from : f, - where : w, - groupby : g, - orderby : o, - limit : l - } - } - -column_clause - = (KW_ALL / (STAR !ident_start)) { - return '*'; - } - / head:column_list_item tail:(__ COMMA __ column_list_item)* { - return createList(head, tail); - } - -/** - * maybe you should use `expr` instead of `primary` or `additive_expr` - * to support complicated expression in column clause - */ -column_list_item - = e:additive_expr __ alias:alias_clause? { - return { - expr : e, - as : alias - }; - } - -alias_clause - = KW_AS? __ i:ident { return i; } - -from_clause - = KW_FROM __ l:table_ref_list { return l; } - -table_ref_list - = head:table_base - tail:table_ref* { - tail.unshift(head); - return tail; - } - -table_ref - = __ COMMA __ t:table_base { return t; } - / __ t:table_join { return t; } - - -table_join - = op:join_op __ t:table_base __ expr:on_clause? { - return { - db : t.db, - table : t.table, - as : t.as, - join : op, - on : expr - } - } - -table_base - = t:table_name __ KW_AS? __ alias:ident? { - return { - db : t.db, - table : t.table, - as : alias - } - } - -join_op - = KW_LEFT __ KW_JOIN { return 'LEFT JOIN'; } - / (KW_INNER __)? KW_JOIN { return 'INNER JOIN'; } - -table_name - = db:ident __ DOT __ tbl:ident { - return { - db:db, - table : tbl - }; - } - / tbl:ident { - return { - db: '', - table : tbl - }; - } - -on_clause - = KW_ON __ e:expr { return e; } - -where_clause - = KW_WHERE __ e:expr { return e; } - -group_by_clause - = KW_GROUP __ KW_BY __ l:column_ref_list { return l; } - -column_ref_list - = head:column_ref tail:(__ COMMA __ column_ref)* { - return createList(head, tail); - } - -having_clause - = KW_HAVING e:expr { return e; } - -order_by_clause - = KW_ORDER __ KW_BY __ l:order_by_list { return l; } - -order_by_list - = head:order_by_element tail:(__ COMMA __ order_by_element)* { - return createList(head, tail); - } - -order_by_element - = e:expr __ KW_DESC { - return { - expr: e, - type : 'DESC' - }; - } - / e:expr __ KW_ASC? { - return { - expr: e, - type : 'ASC' - }; - } - -limit_clause - = KW_LIMIT __ i1:number __ COMMA __ i2:number { return [i1, i2]; } - / KW_LIMIT __ i1:number { return [0, i1]; } - - -update_stmt - = KW_UPDATE __ - t:table_name __ - KW_SET __ - l:set_list __ - w:where_clause { - return { - type : 'update', - db : t.db, - table : t.table, - set : l, - where : w - } - } - -set_list - = head:set_item tail:(__ COMMA __ set_item)* { - return createList(head, tail); - } - -/** - * here only use `additive_expr` to support 'col1 = col1+2' - * if you want to use lower operator, please use '()' like below - * 'col1 = (col2 > 3)' - */ -set_item - = c:ident __ '=' __ v:additive_expr { - return { - column: c, - value : v - } - } - -replace_insert_stmt - = ri:replace_insert __ - KW_INTO __ - t:table_name __ LPAREN __ - c:column_list __ RPAREN __ - v:value_clause { - return { - type : ri, - db : t.db, - table : t.table, - columns : c, - values : v - } - } - -replace_insert - = KW_INSERT { return 'insert'; } - / KW_REPLACE { return 'replace' } - -value_clause - = KW_VALUES __ l:value_list { return l; } - -value_list - = head:value_item tail:(__ COMMA __ value_item)* { - return createList(head, tail); - } - -value_item - = LPAREN __ l:expr_list __ RPAREN { - return l; - } - -//for template auto fill -expr_list - = head:expr tail:(__ COMMA __ expr)*{ - var l = createExprList(head, tail); - return { - type : 'expr_list', - value : l - } - } - -/** - * Borrowed from PL/SQL ,the priority of below list IS ORDER BY DESC - * --------------------------------------------------------------------------------------------------- - * | +, - | identity, negation | - * | *, / | multiplication, division | - * | +, - | addition, subtraction, concatenation | - * | =, <, >, <=, >=, <>, !=, IS, LIKE, BETWEEN, IN, CONTAINS | comparion | - * | !, NOT | logical negation | - * | AND | conjunction | - * | OR | inclusion | - * --------------------------------------------------------------------------------------------------- - */ - -expr = or_expr - -or_expr - = head:and_expr tail:(__ KW_OR __ and_expr)* { - return createBinaryExprChain(head, tail); - } - -and_expr - = head:not_expr tail:(__ KW_AND __ not_expr)* { - return createBinaryExprChain(head, tail); - } - -//here we should use `NOT` instead of `comparision_expr` to support chain-expr -not_expr - = (KW_NOT / "!" !"=") __ expr:not_expr { - return createUnaryExpr('NOT', expr); - } - / comparison_expr - -comparison_expr - = left:additive_expr __ rh:comparison_op_right? { - if (rh == '') { - return left; - } else { - var res = null; - if (rh.type == 'arithmetic') { - res = createBinaryExprChain(left, rh.tail); - } else { - res = createBinaryExpr(rh.op, left, rh.right); - } - return res; - } - } - -comparison_op_right - = arithmetic_op_right - / in_op_right - / between_op_right - / is_op_right - / like_op_right - / contains_op_right - -//very be careful here, use pattern `+` instead of '*' -arithmetic_comparison_expr - = head:additive_expr - tail:(__ arithmetic_comparison_operator __ additive_expr)+ { - return createBinaryExprChain(head, tail); - } - -arithmetic_op_right - = l:(__ arithmetic_comparison_operator __ additive_expr)+ { - return { - type : 'arithmetic', - tail : l - } - } - -arithmetic_comparison_operator - = ">=" / ">" / "<=" / "<>" / "<" / "=" / "!=" - -is_comparison_expr - = left:additive_expr __ op:KW_IS __ right:additive_expr { - return createBinaryExpr(op, left, right); - } - -is_op_right - = op:KW_IS __ right:additive_expr { - return { - op : op, - right : right - } - } - -between_comparison_expr - = left:additive_expr __ op:KW_BETWEEN __ begin:literal __ KW_AND __ end:literal { - return createBinaryExpr(op, left, [begin, end]); - } - -between_op_right - = op:KW_BETWEEN __ begin:literal __ KW_AND __ end:literal { - return { - op : op, - right : [begin, end] - } - } - - -like_op - = nk:(KW_NOT __ KW_LIKE) { return nk[0] + ' ' + nk[2]; } - / KW_LIKE - -in_op - = nk:(KW_NOT __ KW_IN) { return nk[0] + ' ' + nk[2]; } - / KW_IN - -contains_op - = nk:(KW_NOT __ KW_CONTAINS) { return nk[0] + ' ' + nk[2]; } - / KW_CONTAINS - -like_comparison_expr - = left:additive_expr __ op:like_op __ right:comparison_expr { - return createBinaryExpr( op, left, right); - } - -like_op_right - = op:like_op __ right:comparison_expr { - return { - op : op, - right : right - } - } - -in_comparison_expr - = left:additive_expr __ op:in_op __ LPAREN __ l:expr_list __ RPAREN { - return createBinaryExpr(op, left, l); - } - -in_op_right - = op:in_op __ LPAREN __ l:expr_list __ RPAREN { - return { - op : op, - right : l - } - } - -contains_comparison_expr - = left:additive_expr __ op:contains_op __ LPAREN __ l:expr_list __ RPAREN { - return createBinaryExpr(op, left, l); - } - -contains_op_right - = op:contains_op __ LPAREN __ l:expr_list __ RPAREN { - return { - op : op, - right : l - } - } - -additive_expr - = head:multiplicative_expr - tail:(__ additive_operator __ multiplicative_expr)* { - return createBinaryExprChain(head, tail); - } - -additive_operator - = "+" / "-" - -multiplicative_expr - = head:primary - tail:(__ multiplicative_operator __ primary)* { - return createBinaryExprChain(head, tail) - } - -multiplicative_operator - = "*" / "/" / "%" - -primary - = literal - / func_call - / column_ref - / param - / LPAREN __ e:expr __ RPAREN { - e.paren = true; - return e; - } - -column_ref - = tbl:ident __ DOT __ col:column { - return { - type : 'column_ref', - table : tbl, - column : col - }; - } - / col:column { - return { - type : 'column_ref', - table : '', - column: col - }; - } - -column_list - = head:column tail:(__ COMMA __ column)* { - return createList(head, tail); - } - -ident = - name:ident_name !{ return reservedMap[name.toUpperCase()] === true; } { - return name; - } - -column = - name:column_name !{ return reservedMap[name.toUpperCase()] === true; } { - return name; - } - -column_name - = start:ident_start parts:column_part* { return start + parts.join(''); } - -ident_name - = start:ident_start parts:ident_part* { return start + parts.join(''); } - -ident_start = [A-Za-z_] - -ident_part = [A-Za-z0-9_] - -//to support column name like `cf1:name` in hbase -column_part = [A-Za-z0-9_:] - - -param - = l:(':' ident_name) { - var p = { - type : 'param', - value: l[1] - } - //var key = 'L' + line + 'C' + column; - //debug(key); - //params[key] = p; - params.push(p); - return p; - } - -func_call - = name:ident __ LPAREN __ l:expr_list __ RPAREN { - return { - type : 'function', - name : name, - args : l - } - } - -literal - = literal_string / literal_numeric / literal_bool /literal_null - -literal_list - = head:literal tail:(__ COMMA __ literal)* { - return createList(head, tail); - } - -literal_null - = KW_NULL { - return { - type : 'null', - value : null - }; - } - -literal_bool - = KW_TRUE { - return { - type : 'bool', - value : true - }; - } - / KW_FALSE { - return { - type : 'bool', - value : false - }; - } - -literal_string - = ca:( ('"' double_char* '"') - /("'" single_char* "'")) { - return { - type : 'string', - value : ca[1].join('') - } - } - -single_char - = [^'\\\0-\x1F\x7f] - / escape_char - -double_char - = [^"\\\0-\x1F\x7f] - / escape_char - -escape_char - = "\\'" { return "'"; } - / '\\"' { return '"'; } - / "\\\\" { return "\\"; } - / "\\/" { return "/"; } - / "\\b" { return "\b"; } - / "\\f" { return "\f"; } - / "\\n" { return "\n"; } - / "\\r" { return "\r"; } - / "\\t" { return "\t"; } - / "\\u" h1:hexDigit h2:hexDigit h3:hexDigit h4:hexDigit { - return String.fromCharCode(parseInt("0x" + h1 + h2 + h3 + h4)); - } - -line_terminator - = [\n\r] - -literal_numeric - = n:number { - return { - type : 'number', - value : n - } - } - -number - = int_:int frac:frac exp:exp __ { return parseFloat(int_ + frac + exp); } - / int_:int frac:frac __ { return parseFloat(int_ + frac); } - / int_:int exp:exp __ { return parseFloat(int_ + exp); } - / int_:int __ { return parseFloat(int_); } - -int - = digit19:digit19 digits:digits { return digit19 + digits; } - / digit:digit - / op:("-" / "+" ) digit19:digit19 digits:digits { return "-" + digit19 + digits; } - / op:("-" / "+" ) digit:digit { return "-" + digit; } - -frac - = "." digits:digits { return "." + digits; } - -exp - = e:e digits:digits { return e + digits; } - -digits - = digits:digit+ { return digits.join(""); } - -digit = [0-9] -digit19 = [1-9] - -hexDigit - = [0-9a-fA-F] - -e - = e:[eE] sign:[+-]? { return e + sign; } - - -KW_NULL = "NULL"i !ident_start -KW_TRUE = "TRUE"i !ident_start -KW_FALSE = "FALSE"i !ident_start - -KW_SHOW = "SHOW"i !ident_start -KW_DROP = "DROP"i !ident_start -KW_SELECT = "SELECT"i !ident_start -KW_UPDATE = "UPDATE"i !ident_start -KW_CREATE = "CREATE"i !ident_start -KW_DELETE = "DELETE"i !ident_start -KW_INSERT = "INSERT"i !ident_start -KW_REPLACE = "REPLACE"i !ident_start -KW_EXPLAIN = "EXPLAIN"i !ident_start - - -KW_COUNT = "COUNT"i !ident_start -KW_MAX = "MAX"i !ident_start -KW_MIN = "MIN"i !ident_start -KW_SUM = "SUM"i !ident_start -KW_AVG = "AVG"i !ident_start - -KW_INTO = "INTO"i !ident_start -KW_FROM = "FROM"i !ident_start -KW_SET = "SET"i !ident_start - -KW_AS = "AS"i !ident_start -KW_TABLE = "TABLE"i !ident_start - -KW_ON = "ON"i !ident_start -KW_LEFT = "LEFT"i !ident_start -KW_INNER = "INNER"i !ident_start -KW_JOIN = "JOIN"i !ident_start -KW_UNION = "UNION"i !ident_start -KW_VALUES = "VALUES"i !ident_start - -KW_EXISTS = "EXISTS"i !ident_start - -KW_WHERE = "WHERE"i !ident_start - -KW_GROUP = "GROUP"i !ident_start -KW_BY = "BY"i !ident_start -KW_ORDER = "ORDER"i !ident_start -KW_HAVING = "HAVING"i !ident_start - -KW_ASC = "ASC"i !ident_start -KW_DESC = "DESC"i !ident_start - -KW_LIMIT = "LIMIT"i !ident_start - -KW_ALL = "ALL"i !ident_start { return 'ALL'; } -KW_DISTINCT = "DISTINCT"i !ident_start { return 'DISTINCT';} - -KW_BETWEEN = "BETWEEN"i !ident_start { return 'BETWEEN'; } -KW_IN = "IN"i !ident_start { return 'IN'; } -KW_IS = "IS"i !ident_start { return 'IS'; } -KW_LIKE = "LIKE"i !ident_start { return 'LIKE'; } -KW_CONTAINS = "CONTAINS"i !ident_start { return 'CONTAINS';} - -KW_NOT = "NOT"i !ident_start { return 'NOT'; } -KW_AND = "AND"i !ident_start { return 'AND'; } -KW_OR = "OR"i !ident_start { return 'OR'; } - -//specail character -DOT = '.' -COMMA = ',' -STAR = '*' -LPAREN = '(' -RPAREN = ')' - -__ = - whitespace* - -whitespace = - [ \t\n\r] - -EOL - = EOF - / [\n\r]+ - -EOF = !. - - diff --git a/peg/nquery.pegjs b/peg/sqlparser.pegjs similarity index 73% rename from peg/nquery.pegjs rename to peg/sqlparser.pegjs index c24ae80..108f869 100644 --- a/peg/nquery.pegjs +++ b/peg/sqlparser.pegjs @@ -1,21 +1,20 @@ -// (C) 2011-2012 Alibaba Group Holding Limited. -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// version 2 as published by the Free Software Foundation. - -// Author :windyrobin +/*! + * + * (C) 2011~ Alibaba Group Holding Limited. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * Author: + * windyrobin + * fishbar + * + */ { - var util = require('util'); - - function debug(str){ + function debug(str) { console.log(str); } - function inspect(obj){ - console.log(util.inspect(obj, false, 10)); - } - function createUnaryExpr(op, e) { return { type : 'unary_expr', @@ -30,7 +29,7 @@ operator : op, left : left, right : right - } + } } function createList(head, tail) { @@ -46,13 +45,13 @@ var exprList = []; var ep; for (var i = 0; i < epList.length; i++) { - ep = epList[i]; + ep = epList[i]; //the ep has already added to the global params if (ep.type == 'param') { ep.room = room; ep.pos = i; } else { - exprList.push(ep); + exprList.push(ep); } } return exprList; @@ -85,11 +84,11 @@ 'SET' : true, 'LEFT' : true, 'ON' : true, - 'INNER' : true, - 'JOIN' : true, - 'UNION' : true, - 'VALUES' : true, - 'EXISTS' : true, + 'INNER' : true, + 'JOIN' : true, + 'UNION' : true, + 'VALUES' : true, + 'EXISTS' : true, 'WHERE' : true, 'GROUP' : true, 'BY' : true, @@ -98,13 +97,13 @@ 'ASC' : true, 'DESC' : true, 'LIMIT' : true, - 'BETWEEN' : true, + 'BETWEEN' : true, 'IN' : true, 'IS' : true, 'LIKE' : true, 'CONTAINS': true, 'NOT' : true, - 'AND' : true, + 'AND' : true, 'OR' : true, //literal @@ -133,11 +132,11 @@ 'L' : true, 'l' : true, //for not - 'N' : true, - 'n' : true, + 'N' : true, + 'n' : true, //for contains - 'C' : true, - 'c' : true, + 'C' : true, + 'c' : true, } //used for store refered parmas @@ -147,21 +146,21 @@ var varList = []; } -start - = &init __ ast:(union_stmt / update_stmt / replace_insert_stmt) { - return { - ast : ast, - param : params - } - } +start + = __ ast:( + union_stmt / + update_stmt / + delete_stmt / + replace_insert_stmt / + create_table_stmt + ) { + ast.params = params; + return ast; + } /ast:proc_stmts { - return { - ast : ast - } + return ast; } -init = { params = []; return true; } - union_stmt = head:select_stmt tail:(__ KW_UNION __ select_stmt)* { var cur = head; @@ -169,22 +168,129 @@ union_stmt cur._next = tail[i][3]; cur = cur._next } - return head; - } + return head; + } + +create_table_stmt + = KW_CREATE __ KW_TABLE __ (KW_IF __ KW_NOT __ KW_EXISTS __) ? + tb: table_name __ '(' __ + clist:columns_defs + __ ')' __ topt:table_options? __ popt:partition_options? __ ';'? __? { + return { + type: 'create_table', + name: tb, + columns: clist, + tableOptions: topt, + partitionOptions: popt + } + } + +columns_defs + = h:column_def t:(__ COMMA __ column_def)* { + return createList(h, t); + } + +column_def + = index_def / + ( + n:column __ + t:column_type + e:(__ (literal/ident_name))* { + let ext = []; + e.forEach((v) => { + ext.push(v[1]); + }); + return { + name: n, + type: t, + ext: ext + } + } + ) + +column_type + = ct: (func_call/ident) { + if (ct.type === 'function') { + let args = []; + ct.args.value.forEach((v) => { + args.push(v.value); + }); + return { + type: ct.name, + args: args + } + } else { + return {type: ct} + } + } + + table_options + = h:table_option t:(__ table_option)* { + let res = h; + t.forEach((v) => { + let tmp = v[1]; + let keys = Object.keys(tmp) + keys.forEach((k) => { + res[k] = tmp[k].column; + }); + }); + return res; + } + + table_option + = k:primary __ '='? __ v:primary { + let obj = {}; + let key = k.type === 'column_ref' ? k.column : k.value; + let value = v.type === 'column_ref' ? v.column : v.value; + obj[key] = value; + return obj; + } + +partition_options + = h:primary t:(__ primary)* { + let res = [h]; + t.forEach((v) => { + res.push(v); + }); + return res; + } + +index_def + = f:$(ident_name* __ ('KEY'i/'INDEX'i)) __ n:column __ '(' l: column_clause ')'{ + let list = []; + l.forEach((v) => { + list.push(v.expr.column) + }); + return { + type: f, + name: n, + columns: list + } + } + + +delete_stmt += KW_DELETE __ f:from_clause __ w:where_clause? { + return { + type: 'delete', + from: f, + where: w + } +} select_stmt = select_stmt_nake / s:('(' __ select_stmt __ ')') { - return s[2]; + return s[2]; } select_stmt_nake - = KW_SELECT __ + = KW_SELECT __ d:KW_DISTINCT? __ - c:column_clause __ + c:column_clause __ f:from_clause? __ - w:where_clause? __ - g:group_by_clause? __ + w:where_clause? __ + g:group_by_clause? __ o:order_by_clause? __ l:limit_clause? { return { @@ -196,48 +302,48 @@ select_stmt_nake groupby : g, orderby : o, limit : l - } + } } -column_clause +column_clause "column_clause" = (KW_ALL / (STAR !ident_start)) { return '*'; - } + } / head:column_list_item tail:(__ COMMA __ column_list_item)* { return createList(head, tail); } /** - * maybe you should use `expr` instead of `primary` or `additive_expr` + * maybe you should use `expr` instead of `primary` or `additive_expr` * to support complicated expression in column clause */ column_list_item - = e:additive_expr __ alias:alias_clause? { + = e:additive_expr __ alias:alias_clause? { return { - expr : e, + expr : e, as : alias - }; - } + }; + } -alias_clause +alias_clause = KW_AS? __ i:ident { return i; } from_clause = KW_FROM __ l:table_ref_list { return l; } table_ref_list - = head:table_base + = head:table_base tail:table_ref* { tail.unshift(head); return tail; } -table_ref +table_ref = __ COMMA __ t:table_base { return t; } - / __ t:table_join { return t; } - - -table_join + / __ t:table_join { return t; } + + +table_join = op:join_op __ t:table_base __ expr:on_clause? { t.join = op; t.on = expr; @@ -251,10 +357,10 @@ table_join on : expr } */ - } - + } + //NOTE that ,the table assigned to `var` shouldn't write in `table_join` -table_base +table_base = t:table_name __ KW_AS? __ alias:ident? { if (t.type == 'var') { t.as = alias; @@ -266,22 +372,22 @@ table_base as : alias } } - } + } join_op - = KW_LEFT __ KW_JOIN { return 'LEFT JOIN'; } + = KW_LEFT __ KW_JOIN { return 'LEFT JOIN'; } / (KW_INNER __)? KW_JOIN { return 'INNER JOIN'; } -table_name - = dt:ident tail:(__ DOT __ ident_name)? { +table_name + = '`'? dt:ident tail:(__ DOT __ ident_name)? '`'? { var obj = { db : '', table : dt } - if (tail != '') { + if (tail) { obj.db = dt; obj.table = tail[3]; - } + } return obj; } /v:var_decl { @@ -290,10 +396,10 @@ table_name return v; } -on_clause +on_clause = KW_ON __ e:expr { return e; } -where_clause +where_clause = KW_WHERE __ e:expr { return e; } group_by_clause @@ -331,14 +437,17 @@ number_or_param = literal_numeric / param +int_or_param + = literal_int / param + limit_clause - = KW_LIMIT __ i1:(number_or_param) __ tail:(COMMA __ number_or_param)? { + = KW_LIMIT __ i1:(int_or_param) __ tail:(COMMA __ int_or_param)? { var res = [i1]; - if (tail == '') { + if (!tail) { res.unshift({ type : 'number', value : 0 - }); + }); } else { res.push(tail[2]); } @@ -346,18 +455,18 @@ limit_clause } update_stmt - = KW_UPDATE __ - t:table_name __ - KW_SET __ - l:set_list __ + = KW_UPDATE __ + t:table_name __ + KW_SET __ + l:set_list __ w:where_clause { return { - type : 'update', + type : 'update', db : t.db, table : t.table, set : l, where : w - } + } } set_list @@ -379,22 +488,22 @@ set_item } replace_insert_stmt - = ri:replace_insert __ - KW_INTO __ - t:table_name __ LPAREN __ + = ri:replace_insert __ + KW_INTO __ + t:table_name __ LPAREN __ c:column_list __ RPAREN __ v:value_clause { return { - type : ri, + type : ri, db : t.db, table : t.table, columns : c, values : v - } + } } replace_insert - = KW_INSERT { return 'insert'; } + = KW_INSERT { return 'insert'; } / KW_REPLACE { return 'replace' } value_clause @@ -403,7 +512,7 @@ value_clause value_list = head:value_item tail:(__ COMMA __ value_item)* { return createList(head, tail); - } + } value_item = LPAREN __ l:expr_list __ RPAREN { @@ -414,38 +523,39 @@ value_item expr_list = head:expr tail:(__ COMMA __ expr)*{ var el = { - type : 'expr_list' + type : 'expr_list' } - var l = createExprList(head, tail, el); + + var l = createExprList(head, tail, el); el.value = l; return el; } expr_list_or_empty - = l:expr_list - / { - return { + = l:expr_list + / (''{ + return { type : 'expr_list', value : [] } - } + }) -/** - * Borrowed from PL/SQL ,the priority of below list IS ORDER BY DESC +/** + * Borrowed from PL/SQL ,the priority of below list IS ORDER BY DESC * --------------------------------------------------------------------------------------------------- - * | +, - | identity, negation | + * | +, - | identity, negation | * | *, / | multiplication, division | * | +, - | addition, subtraction, concatenation | * | =, <, >, <=, >=, <>, !=, IS, LIKE, BETWEEN, IN, CONTAINS | comparion | * | !, NOT | logical negation | * | AND | conjunction | - * | OR | inclusion | + * | OR | inclusion | * --------------------------------------------------------------------------------------------------- */ expr = or_expr - + or_expr = head:and_expr tail:(__ KW_OR __ and_expr)* { return createBinaryExprChain(head, tail); @@ -465,8 +575,8 @@ not_expr comparison_expr = left:additive_expr __ rh:comparison_op_right? { - if (rh == '') { - return left; + if (!rh) { + return left; } else { var res = null; if (rh.type == 'arithmetic') { @@ -478,29 +588,29 @@ comparison_expr } } -/* +/* //optimization for comparison judge, bug because we in use `additive` expr //in column clause now , it have little effect cmp_prefix_char = c:char &{ debug(c); return cmpPrefixMap[c]; } -comparison_op_right +comparison_op_right = &cmp_prefix_char body:( arithmetic_op_right / in_op_right - / between_op_right + / between_op_right / is_op_right / like_op_right / contains_op_right ){ - return body; + return body; } */ -comparison_op_right +comparison_op_right = arithmetic_op_right / in_op_right - / between_op_right + / between_op_right / is_op_right / like_op_right / contains_op_right @@ -511,15 +621,15 @@ arithmetic_op_right type : 'arithmetic', tail : l } - } + } arithmetic_comparison_operator - = ">=" / ">" / "<=" / "<>" / "<" / "=" / "!=" + = ">=" / ">" / "<=" / "<>" / "<" / "=" / "!=" is_op_right = op:KW_IS __ right:additive_expr { return { - op : op, + op : op, right : right } } @@ -537,13 +647,13 @@ between_op_right like_op = nk:(KW_NOT __ KW_LIKE) { return nk[0] + ' ' + nk[2]; } - / KW_LIKE + / KW_LIKE -in_op +in_op = nk:(KW_NOT __ KW_IN) { return nk[0] + ' ' + nk[2]; } / KW_IN -contains_op +contains_op = nk:(KW_NOT __ KW_CONTAINS) { return nk[0] + ' ' + nk[2]; } / KW_CONTAINS @@ -558,13 +668,13 @@ like_op_right in_op_right = op:in_op __ LPAREN __ l:expr_list __ RPAREN { return { - op : op, + op : op, right : l } } / op:in_op __ e:var_decl { return { - op : op, + op : op, right : e } } @@ -572,13 +682,13 @@ in_op_right contains_op_right = op:contains_op __ LPAREN __ l:expr_list __ RPAREN { return { - op : op, + op : op, right : l } } / op:contains_op __ e:var_decl { return { - op : op, + op : op, right : e } } @@ -601,30 +711,30 @@ multiplicative_expr multiplicative_operator = "*" / "/" / "%" -primary +primary = literal / aggr_func - / func_call - / column_ref + / func_call + / column_ref / param - / LPAREN __ e:expr __ RPAREN { - e.paren = true; - return e; - } + / LPAREN __ e:expr __ RPAREN { + e.paren = true; + return e; + } / var_decl -column_ref - = tbl:ident __ DOT __ col:column { +column_ref + = tbl:ident __ DOT __ col:column { return { type : 'column_ref', - table : tbl, + table : tbl, column : col - }; - } - / col:column { + }; + } + / col:column { return { type : 'column_ref', - table : '', + table : '', column: col }; } @@ -634,23 +744,23 @@ column_list return createList(head, tail); } -ident = +ident = name:ident_name !{ return reservedMap[name.toUpperCase()] === true; } { - return name; - } + return name; + } -column = +column = name:column_name !{ return reservedMap[name.toUpperCase()] === true; } { - return name; - } + return name; + } /'`' chars:[^`]+ '`' { - return chars.join(''); + return chars.join(''); } -column_name +column_name = start:ident_start parts:column_part* { return start + parts.join(''); } -ident_name +ident_name = start:ident_start parts:ident_part* { return start + parts.join(''); } ident_start = [A-Za-z_] @@ -661,12 +771,12 @@ ident_part = [A-Za-z0-9_] column_part = [A-Za-z0-9_:] -param - = l:(':' ident_name) { +param "PARAM[:param, ?]" + = l:(':' ident_name) / l:('?') { var p = { type : 'param', - value: l[1] - } + value: l.length > 1 ? l[1] : l[0] + }; //var key = 'L' + line + 'C' + column; //debug(key); //params[key] = p; @@ -678,43 +788,43 @@ aggr_func = aggr_fun_count / aggr_fun_smma -aggr_fun_smma +aggr_fun_smma = name:KW_SUM_MAX_MIN_AVG __ LPAREN __ e:additive_expr __ RPAREN { return { type : 'aggr_func', name : name, args : { - expr : e - } - } + expr : e + } + } } KW_SUM_MAX_MIN_AVG - = KW_SUM / KW_MAX / KW_MIN / KW_AVG + = w:[0-9a-zA-Z_]+{return w.join('');} -aggr_fun_count +aggr_fun_count = name:KW_COUNT __ LPAREN __ arg:count_arg __ RPAREN { return { type : 'aggr_func', name : name, - args : arg - } + args : arg + } } -count_arg +count_arg = e:star_expr { return { - expr : e + expr : e } } / d:KW_DISTINCT? __ c:column_ref { return { - distinct : d, + distinct : d, expr : c } } -star_expr +star_expr = "*" { return { type : 'star', @@ -726,17 +836,17 @@ func_call = name:ident __ LPAREN __ l:expr_list_or_empty __ RPAREN { return { type : 'function', - name : name, + name : name, args : l } } -literal +literal = literal_string / literal_numeric / literal_bool /literal_null literal_list = head:literal tail:(__ COMMA __ literal)* { - return createList(head, tail); + return createList(head, tail); } literal_null @@ -744,25 +854,25 @@ literal_null return { type : 'null', value : null - }; + }; } -literal_bool - = KW_TRUE { +literal_bool + = KW_TRUE { return { type : 'bool', value : true - }; + }; } - / KW_FALSE { + / KW_FALSE { return { type : 'bool', value : false - }; + }; } -literal_string - = ca:( ('"' double_char* '"') +literal_string + = ca:( ('"' double_char* '"') /("'" single_char* "'")) { return { type : 'string', @@ -799,15 +909,22 @@ literal_numeric = n:number { return { type : 'number', - value : n - } + value : n + } } +literal_int "LITERAL INT" + = n:int { + return { + type: 'number', + value: n + } + } number - = int_:int frac:frac exp:exp __ { return parseFloat(int_ + frac + exp); } - / int_:int frac:frac __ { return parseFloat(int_ + frac); } - / int_:int exp:exp __ { return parseFloat(int_ + exp); } - / int_:int __ { return parseFloat(int_); } + = int_:int frac:frac exp:exp __ { var x = parseFloat(int_ + frac + exp); return (x % 1 != 0) ? x.toString() : x.toString() + ".0"} + / int_:int frac:frac __ { var x = parseFloat(int_ + frac); return (x % 1 != 0) ? x.toString() : x.toString() + ".0"} + / int_:int exp:exp __ { return parseFloat(int_ + exp).toString(); } + / int_:int __ { return parseFloat(int_).toString(); } int = digit19:digit19 digits:digits { return digit19 + digits; } @@ -824,23 +941,23 @@ exp digits = digits:digit+ { return digits.join(""); } -digit = [0-9] -digit19 = [1-9] +digit "NUMBER" = [0-9] +digit19 "NUMBER" = [1-9] -hexDigit +hexDigit "HEX" = [0-9a-fA-F] e = e:[eE] sign:[+-]? { return e + sign; } -KW_NULL = "NULL"i !ident_start +KW_NULL = "NULL"i !ident_start KW_TRUE = "TRUE"i !ident_start -KW_FALSE = "FALSE"i !ident_start +KW_FALSE = "FALSE"i !ident_start KW_SHOW = "SHOW"i !ident_start KW_DROP = "DROP"i !ident_start -KW_SELECT = "SELECT"i !ident_start +KW_SELECT = "SELECT"i !ident_start KW_UPDATE = "UPDATE"i !ident_start KW_CREATE = "CREATE"i !ident_start KW_DELETE = "DELETE"i !ident_start @@ -862,6 +979,7 @@ KW_JOIN = "JOIN"i !ident_start KW_UNION = "UNION"i !ident_start KW_VALUES = "VALUES"i !ident_start +KW_IF = "IF"i !ident_start KW_EXISTS = "EXISTS"i !ident_start KW_WHERE = "WHERE"i !ident_start @@ -877,7 +995,7 @@ KW_ASC = "ASC"i !ident_start { return 'ASC'; } KW_DESC = "DESC"i !ident_start { return 'DESC'; } KW_ALL = "ALL"i !ident_start { return 'ALL'; } -KW_DISTINCT = "DISTINCT"i !ident_start { return 'DISTINCT';} +KW_DISTINCT = "DISTINCT"i !ident_start { return 'DISTINCT';} KW_BETWEEN = "BETWEEN"i !ident_start { return 'BETWEEN'; } KW_IN = "IN"i !ident_start { return 'IN'; } @@ -889,8 +1007,8 @@ KW_NOT = "NOT"i !ident_start { return 'NOT'; } KW_AND = "AND"i !ident_start { return 'AND'; } KW_OR = "OR"i !ident_start { return 'OR'; } -KW_COUNT = "COUNT"i !ident_start { return 'COUNT'; } -KW_MAX = "MAX"i !ident_start { return 'MAX'; } +KW_COUNT = "COUNT"i !ident_start { return 'COUNT'; } +KW_MAX = "MAX"i !ident_start { return 'MAX'; } KW_MIN = "MIN"i !ident_start { return 'MIN'; } KW_SUM = "SUM"i !ident_start { return 'SUM'; } KW_AVG = "AVG"i !ident_start { return 'AVG'; } @@ -910,20 +1028,19 @@ __ = char = . -whitespace = - [ \t\n\r] +whitespace 'WHITE_SPACE' = [ \t\n\r] -EOL +EOL "EOF" = EOF / [\n\r]+ - + EOF = !. //begin procedure extension -proc_stmts - = proc_stmt* +proc_stmts + = proc_stmt* -proc_stmt +proc_stmt = &proc_init __ s:(assign_stmt / return_stmt) { return { stmt : s, @@ -931,9 +1048,9 @@ proc_stmt } } -proc_init = { varList = []; return true; } +proc_init = '' { varList = []; return true; } -assign_stmt +assign_stmt = va:var_decl __ KW_ASSIGN __ e:proc_expr { return { type : 'assign', @@ -942,7 +1059,7 @@ assign_stmt } } -return_stmt +return_stmt = KW_RETURN __ e:proc_expr { return { type : 'return', @@ -950,10 +1067,10 @@ return_stmt } } -proc_expr - = select_stmt - / proc_join - / proc_additive_expr +proc_expr + = select_stmt + / proc_join + / proc_additive_expr / proc_array proc_additive_expr @@ -972,29 +1089,29 @@ proc_join = lt:var_decl __ op:join_op __ rt:var_decl __ expr:on_clause { return { type : 'join', - ltable : lt, + ltable : lt, rtable : rt, op : op, on : expr } } -proc_primary +proc_primary = literal / var_decl - / proc_func_call + / proc_func_call / param - / LPAREN __ e:proc_additive_expr __ RPAREN { - e.paren = true; - return e; - } + / LPAREN __ e:proc_additive_expr __ RPAREN { + e.paren = true; + return e; + } proc_func_call = name:ident __ LPAREN __ l:proc_primary_list __ RPAREN { //compatible with original func_call return { type : 'function', - name : name, + name : name, args : { type : 'expr_list', value : l @@ -1002,12 +1119,12 @@ proc_func_call } } -proc_primary_list +proc_primary_list = head:proc_primary tail:(__ COMMA __ proc_primary)* { return createList(head, tail); - } + } -proc_array = +proc_array = LBRAKE __ l:proc_primary_list __ RBRAKE { return { type : 'array', @@ -1016,7 +1133,7 @@ proc_array = } -var_decl +var_decl = KW_VAR_PRE name:ident_name m:mem_chain { //push for analysis varList.push(name); @@ -1025,13 +1142,13 @@ var_decl name : name, members : m } - } + } -mem_chain +mem_chain = l:('.' ident_name)* { var s = []; for (var i = 0; i < l.length; i++) { - s.push(l[i][1]); + s.push(l[i][1]); } return s; } diff --git a/test/benchmark/sql_parse.js b/test/benchmark/sql_parse.js deleted file mode 100644 index bedf4c7..0000000 --- a/test/benchmark/sql_parse.js +++ /dev/null @@ -1,63 +0,0 @@ -//var sqlparser = require('parser-robin'); -var Parser = require('../../lib/parser'); -var Adapter = require('../../lib/adapter'); - - -var NUM = 10000; - -function debug(str) { - console.log(str); -} - -function inspect(obj) { - console.log(require('util').inspect(obj, false, 10)); -} - -function test(fn, name) { - var b = new Date(); - var res; - for (var i = 0; i < NUM; i++) { - ast = fn(); - } - var e = new Date(); - debug('-------------') - debug('id : ' + name); - debug('loop: ' + NUM + ', time: ' + (e-b)); - debug(Adapter.toSQL(ast)); - //inspect(res); - debug('\n'); -} - -var sql = "SELECT C.brand_id AS mk,SUM(B.alipay_auction_num) AS f0 FROM myfox.dim_category AS A,myfox.rpt_brand_info_d AS B,myfox.dim_product_brand_hismap AS C,myfox.dim_brand AS D WHERE C.brand_id=D.brand_id AND B.category_id=C.category_id AND B.brand_id=C.org_brand_id AND A.category_id=B.category_id AND B.thedate>='2010-10-09' AND B.thedate<='2010-10-10' AND B.alipay_trade_amt>0 AND A.category_level1=16 AND A.leaf_flag=1 AND A.deleted=0 GROUP BY A.brand_name,B.brand_id ORDER BY SUM(B.alipay_trade_amt) DESC LIMIT 1500"; - - -var sql_tpl = "SELECT C.brand_id AS mk,SUM(B.alipay_auction_num) AS f0 FROM myfox.dim_category AS A,myfox.rpt_brand_info_d AS B,myfox.dim_product_brand_hismap AS C,myfox.dim_brand AS D WHERE C.brand_id=D.brand_id AND B.category_id=C.category_id AND B.brand_id=C.org_brand_id AND A.category_id=B.category_id AND B.thedate>=:thedate_begin AND B.thedate<=:thedate_end AND B.alipay_trade_amt>0 AND A.category_level1=16 AND A.leaf_flag=1 AND A.deleted=0 GROUP BY A.brand_name,B.brand_id ORDER BY SUM(B.alipay_trade_amt) DESC LIMIT 1500"; -//function oldTest() { -// return sqlparser.parse(sql); -//} - -function parseTest() { - return Parser.tplParse(sql); -} - -function tplParseTest() { - return Parser.tplParse(sql_tpl, { - thedate_begin : '2010-10-09', - thedate_end : '2010-10-10' - }); -} - -function columnTest(){ - var sql = "select cf1:address_city_cnt, cf1:address_cnt, cf1:address_fullname_cnt, cf1:amt_alipay, cf1:coll_cnt, cf1:coll_days, cf1:coll_item_title, cf1:first_gmt_receive_pay, cf1:first_title, cf1:first_total_fee, cf1:love_seller_id, cf1:love_shop_name, cf1:love_shop_trade_cnt, cf1:max_gmt_receive_pay, cf1:max_long_days, cf1:max_long_gmt_receive_pay, cf1:max_long_last_gmt_receive_pay, cf1:max_title, cf1:max_total_fee, cf1:min_gmt_receive_pay, cf1:min_title, cf1:min_total_fee, cf1:num_alipay, cf1:peer_cnt, cf1:peer_for_cnt, cf1:peerpayername, cf1:time_line, cf1:user_order, cf1:user_regdate, cf1:user_star_name, cf1:user_tag, cf1:p_label from hbase_tcif.tcif_20121212 where row = 'bb9a63446090'" - - return Parser.tplParse(sql); -} - -test(columnTest, 'column test'); -test(parseTest, 'sql parse') -test(tplParseTest, 'sql tpl Parse') - -test(parseTest, 'sql parse') -test(tplParseTest, 'sql tpl Parse') - - diff --git a/test/unit/adapter.js b/test/unit/adapter.js deleted file mode 100644 index 17571f0..0000000 --- a/test/unit/adapter.js +++ /dev/null @@ -1,225 +0,0 @@ - -var should = require('should'); -var Adapter = require('../../lib/adapter'); -var Parser = require('../../lib/parser'); -var Context = require('../../lib/context'); - -function debug(str) { - console.log(str); -} -function inspect(obj) { - console.log(require('util').inspect(obj, false, 10, true)); -} - -describe('sql adapter test',function(){ - - it('string escape test', function() { - var sql, ast; - - sql = "SELECT 'single str' ,\"double string \", ' escape \\n \\t \\u0002'"; - ast = Parser.parse(sql); - - var estr = Adapter.toSQL(ast); - estr.should.include('\\n'); - estr.should.include('\\t'); - //inspect(estr); - }); - - it('bool & paren test', function() { - var sql, ast; - - sql = "SELECT (2 = true), (false = 0)"; - ast = Parser.parse(sql); - - var estr = Adapter.toSQL(ast); - estr.should.eql('SELECT (2 = TRUE), (FALSE = 0)'); - //inspect(estr); - }); - - it('aggr function test', function() { - var sql, ast; - - sql = "SELECT md5(a), COUNT(distinct a.id), COUNT(*)"; - ast = Parser.parse(sql); - - var estr = Adapter.toSQL(ast); - estr.should.eql('SELECT md5(a), COUNT(DISTINCT a.id), COUNT(*)'); - }); - - it('func test', function() { - var sql, ast; - - sql = "SELECT md5(a), SUM(b) + 1"; - ast = Parser.parse(sql); - - var estr = Adapter.toSQL(ast); - - estr.should.eql('SELECT md5(a), SUM(b) + 1'); - }); - - it('unary test', function() { - var sql, ast; - - sql = "SELECT (NOT true), (!1) as test"; - ast = Parser.parse(sql); - - var estr = Adapter.toSQL(ast); - //inspect(estr); - //inspect(ast); - - estr.should.eql('SELECT (NOT TRUE), (NOT 1) AS test'); - }); - - it('comparison test', function() { - var sql, ast; - sql = "SELECT a fROM garuda_keykeys.keykeys wHERE type > 3 and id in (1, 2, 3) AND keywords CONTAINS (1,'str')" - ast = Parser.parse(sql); - //inspect(ast); - var estr = Adapter.toSQL(ast); - //inspect(estr); - estr.should.eql("SELECT a FROM garuda_keykeys.keykeys WHERE type > 3 AND id IN (1, 2, 3) AND keywords CONTAINS (1, 'str')"); - - sql = "SELECT a fROM t wHERE type >= 0 AND id between '1' AND 3 and it > 0 " - ast = Parser.parse(sql); - //inspect(ast); - estr = Adapter.toSQL(ast); - //inspect(estr); - estr.should.eql("SELECT a FROM t WHERE type >= 0 AND id BETWEEN '1' AND 3 AND it > 0"); - }); - - it('logical test', function() { - var sql, ast; - - sql = "SELECT (1 > 1 AND 0 > 0 Or NOT true)"; - ast = Parser.parse(sql); - - var estr = Adapter.toSQL(ast); - //inspect(estr); - //inspect(ast); - - estr.should.eql('SELECT (1 > 1 AND 0 > 0 OR NOT TRUE)'); - }); - - - it('procedure test', function() { - var sql, ast; - - sql = "SELECT * from t where id = $id or id NOT CONTAINS $tid"; - ast = Parser.parse(sql); - - Context.setctx({ - id : [1, 2, 'a'], - tid : ['b', 'c'], - }) - var estr = Adapter.toSQL(ast); - //inspect(estr); - //inspect(ast); - estr.should.eql("SELECT * FROM t WHERE id IN (1, 2, 'a') OR id NOT CONTAINS ('b', 'c')"); - }); - - it('clause test', function() { - var sql, ast; - - sql = "SELECT DISTINCT da.id, SUM(da.score) from d.a da where d.c > 0 group by a.id order by sum(a.title) limit 0, 1"; - ast = Parser.parse(sql); - - //inspect(ast); - var estr = Adapter.toSQL(ast); - //inspect(estr); - - estr.should.eql('SELECT DISTINCT da.id, SUM(da.score) FROM d.a AS da WHERE d.c > 0 GROUP BY a.id ORDER BY SUM(a.title) ASC LIMIT 0, 1'); - }); - - it('join test', function() { - var sql, ast; - sql = "SELECT a ,b.c FROM a ,b" - ast = Parser.parse(sql); - //inspect(ast); - var estr = Adapter.toSQL(ast); - estr.should.eql("SELECT a, b.c FROM a, b"); - - sql = "SELECT a ,b.c FROM a LEFT join b on a.c = b.c" - ast = Parser.parse(sql); - //inspect(ast); - var estr = Adapter.toSQL(ast); - estr.should.eql("SELECT a, b.c FROM a LEFT JOIN b ON a.c = b.c"); - }); - - it('whole test', function(){ - var sql, ast, estr; - sql = "SELECT pt.brand_id AS id, bt.brand_name AS name, ht.org_brand_id AS originBrandId, SUM(pt.uid_uv) AS uv, dc.category_level2 AS level2 FROM myfox.dim_category AS dc INNER JOIN myfox.rpt_brand_info_d AS pt ON dc.category_id = pt.category_id INNER JOIN myfox.dim_product_brand_hismap AS ht ON pt.brand_id = ht.brand_id AND pt.category_id = ht.category_id INNER JOIN myfox.dim_brand AS bt ON bt.brand_id = ht.brand_id WHERE pt.brand_id NOT IN (-99, 0) AND dc.deleted = 0 AND bt.brand_name NOT LIKE 'other%' AND dc.category_level1 = '50013864' AND pt.thedate >= '2012-12-13' AND pt.thedate <= '2012-12-19' GROUP BY brand, brand_name ORDER BY SUM(pt.uid_uv) DESC LIMIT 0, 300" - //sql = 'SELECT pt.brand_id AS id, bt.brand_name AS name, ht.org_brand_id AS originBrandId, SUM(pt.uid_uv) AS uv, dc.category_level2 AS level2 FROM myfox.dim_category AS dc INNER JOIN myfox.rpt_brand_info_d AS pt ON dc.category_id = pt.category_id INNER JOIN myfox.dim_product_brand_hismap AS ht ON pt.brand_id = ht.brand_id AND pt.category_id = ht.category_id INNER JOIN myfox.dim_brand AS bt ON bt.brand_id = ht.brand_id WHERE pt.brand_id NOT IN (-99,0) AND dc.deleted = 0 AND bt.brand_name NOT like "other%" AND dc.category_level1 = "50013864" AND pt.thedate >= "2012-12-13" AND pt.thedate <= "2012-12-19" GROUP BY brand, brand_name ORDER BY SUM(pt.uid_uv) DESC LIMIT 0, 300 ' - ast = Parser.parse(sql); - //inspect(ast.from); - estr = Adapter.toSQL(ast); - //debug(estr); - estr.should.eql(sql); - - - sql = "SELECT C.brand_id AS mk,SUM(B.alipay_auction_num) AS f0 FROM myfox.dim_category AS A,myfox.rpt_brand_info_d AS B,myfox.dim_product_brand_hismap AS C,myfox.dim_brand AS D WHERE C.brand_id=D.brand_id AND B.category_id=C.category_id AND B.brand_id=C.org_brand_id AND A.category_id=B.category_id AND B.thedate>='2010-10-09' AND B.thedate<='2010-10-10' AND B.alipay_trade_amt>0 AND A.category_level1=16 AND A.leaf_flag=1 AND A.deleted=0 GROUP BY A.brand_name,B.brand_id ORDER BY SUM(B.alipay_trade_amt) DESC LIMIT 1500"; - - ast = Parser.parse(sql); - //inspect(ast.from); - estr = Adapter.toSQL(ast); - //debug(estr); - estr.should.eql("SELECT C.brand_id AS mk, SUM(B.alipay_auction_num) AS f0 FROM myfox.dim_category AS A, myfox.rpt_brand_info_d AS B, myfox.dim_product_brand_hismap AS C, myfox.dim_brand AS D WHERE C.brand_id = D.brand_id AND B.category_id = C.category_id AND B.brand_id = C.org_brand_id AND A.category_id = B.category_id AND B.thedate >= '2010-10-09' AND B.thedate <= '2010-10-10' AND B.alipay_trade_amt > 0 AND A.category_level1 = 16 AND A.leaf_flag = 1 AND A.deleted = 0 GROUP BY A.brand_name, B.brand_id ORDER BY SUM(B.alipay_trade_amt) DESC LIMIT 0, 1500"); - - - sql = "SELECT a.shop_id AS f30, a.shop_name AS f31, a.shop_star AS f32, a.shop_type AS f33, a.key_category1 AS catid, b.category_name AS catname,c.pict_url AS pict_url FROM myfox.dim_clt_shops AS a LEFT JOIN myfox.dim_category AS b ON a.key_category1=b.category_id INNER JOIN isearch.shop AS c ON a.shop_id=c.id WHERE a.user_wangwang=windyrobin LIMIT 1"; - ast = Parser.parse(sql); - //inspect(ast.from); - estr = Adapter.toSQL(ast); - estr.should.eql('SELECT a.shop_id AS f30, a.shop_name AS f31, a.shop_star AS f32, a.shop_type AS f33, a.key_category1 AS catid, b.category_name AS catname, c.pict_url AS pict_url FROM myfox.dim_clt_shops AS a LEFT JOIN myfox.dim_category AS b ON a.key_category1 = b.category_id INNER JOIN isearch.shop AS c ON a.shop_id = c.id WHERE a.user_wangwang = windyrobin LIMIT 0, 1'); - - }); - - it('if test', function() { - var sql, ast; - sql = 'SELECT IF(A.shop_type=2, \'0\', A.shop_star_level_id) AS mk, IF(A.shop_type=2,\'0\',B.shop_star_level_name) AS f0, SUM(A.alipay_trade_num) AS f1 FROM myfox.rpt_cat_info_shop_star_d AS A LEFT JOIN myfox.dim_shop_star_level AS B ON A.shop_star_level_id=B.shop_star_level_id WHERE A.category_id = "50012082" AND A.thedate >= "2010-10-01" AND A.thedate <= "2010-10-31" AND A.alipay_trade_num > 0 AND A.shop_type <> 2 AND B.shop_star_level_id > 0 GROUP BY A.shop_star_level_id ORDER BY A.shop_star_level_id ASC LIMIT 500' - ast = Parser.parse(sql); - //inspect(ast); - var estr = Adapter.toSQL(ast); - estr.should.eql("SELECT IF(A.shop_type = 2, '0', A.shop_star_level_id) AS mk, IF(A.shop_type = 2, '0', B.shop_star_level_name) AS f0, SUM(A.alipay_trade_num) AS f1 FROM myfox.rpt_cat_info_shop_star_d AS A LEFT JOIN myfox.dim_shop_star_level AS B ON A.shop_star_level_id = B.shop_star_level_id WHERE A.category_id = '50012082' AND A.thedate >= '2010-10-01' AND A.thedate <= '2010-10-31' AND A.alipay_trade_num > 0 AND A.shop_type <> 2 AND B.shop_star_level_id > 0 GROUP BY A.shop_star_level_id ORDER BY A.shop_star_level_id ASC LIMIT 0, 500"); - }); - - - it('update test', function() { - var sql, ast; - sql = "UPDATE db.user_info SET last_login_time = '2012-12-18 12:44:21', last_login_ip = 'hohoo', login_count = login_count+1 WHERE id = 334094" - ast = Parser.parse(sql); - //inspect(ast); - var estr = Adapter.toSQL(ast); - estr.should.eql("UPDATE db.user_info SET last_login_time = '2012-12-18 12:44:21', last_login_ip = 'hohoo', login_count = login_count + 1 WHERE id = 334094"); - }); - - it('insert test', function() { - var sql, ast; - sql = "INSERT INTO cubemeta.meta_user_loginlog_trial (user_id, username, login_time, login_ip, login_url) VALUES ('uid1', 'use1', 'login', 'login_ip', 'login_url')"; - ast = Parser.parse(sql); - //inspect(ast); - var estr = Adapter.toSQL(ast); - //debug(estr); - estr.should.eql("INSERT INTO cubemeta.meta_user_loginlog_trial (user_id, username, login_time, login_ip, login_url) VALUES ('uid1', 'use1', 'login', 'login_ip', 'login_url')"); - }); - - it('replace test', function() { - var sql, ast; - sql = "REplace INTO a.b (c1, c2)VALUES('d', '2'), ('e',1), (TRUE, null)"; - ast = Parser.parse(sql); - //inspect(ast); - var estr = Adapter.toSQL(ast); - //debug(estr); - estr.should.eql("REPLACE INTO a.b (c1, c2) VALUES ('d', '2'), ('e', 1), (TRUE, NULL)"); - }); - - it('union test', function() { - var sql, ast; - sql = "select 1 union select '1' union select a union (select true)"; - ast = Parser.parse(sql); - //inspect(ast); - var estr = Adapter.toSQL(ast); - //debug(estr); - estr.should.eql("SELECT 1 UNION SELECT '1' UNION SELECT a UNION SELECT TRUE"); - }); - -}); diff --git a/test/unit/aggregation.js b/test/unit/aggregation.js deleted file mode 100644 index 05c32cd..0000000 --- a/test/unit/aggregation.js +++ /dev/null @@ -1,82 +0,0 @@ -var should = require('should'); - -var Parser = require('../../lib/parser'); -var AstHelper = require('../../lib/ast_helper'); -var createBinaryExpr = AstHelper.createBinaryExpr; - -var filter = require('../../base/aggregation'); - -var AstReader = AstHelper.Reader; - -function inspect(obj) { - //console.log(require('util').inspect(obj, false, 10, true)); -} - -describe('aggregation test', function(){ - it('basic test', function(){ - var rawData = { - columns: [ - [{table : 'a', column : 'id'}, {table : 'b', column : 'id'}], - [{table : 'a', column : 'name'}], - [{table : 'b', column : 'type'}] - ], - data: [ - [ 1, 'a', 't1' ], - [ 2, 'b', 't2' ], - [ 2, 'b', 't3' ], - [ 3, 'c', 't3' ], - [ 3, 'c', 't4' ], - [ 5, 'b', 't3' ], - [ 6, 'b', 't4' ] - ] - }; - - var str; - var ast; - var res; - - str = "select SUM(a.id) from data"; - ast = Parser.parse(str); - //inspect(ast.columns); - res = filter(rawData, ast.columns); - res.should.eql([22]); - - str = "select COUNT(a.id) from data"; - ast = Parser.parse(str); - //inspect(ast.columns); - res = filter(rawData, ast.columns); - res.should.eql([7]); - - str = "select avg(a.id) from data"; - ast = Parser.parse(str); - //inspect(ast.columns); - res = filter(rawData, ast.columns); - res.should.eql([22/7]); - - str = "select Min(a.id) from data"; - ast = Parser.parse(str); - //inspect(ast.columns); - res = filter(rawData, ast.columns); - res.should.eql([1]); - - str = "select MAX(a.id) from data"; - ast = Parser.parse(str); - //inspect(ast.columns); - res = filter(rawData, ast.columns); - res.should.eql([6]); - - str = "select MAX(a.id)+1, min(a.name), max(b.type) from data"; - ast = Parser.parse(str); - //inspect(ast.columns); - res = filter(rawData, ast.columns); - res.should.eql([7, 'a', 't4']); - - str = "select a.id, min(a.name), max(b.type) from data"; - ast = Parser.parse(str); - //inspect(ast.columns); - res = filter(rawData, ast.columns); - res.should.eql([1, 'a', 't4']); - }); - - -}); diff --git a/test/unit/ast_helper.js b/test/unit/ast_helper.js deleted file mode 100644 index a97775d..0000000 --- a/test/unit/ast_helper.js +++ /dev/null @@ -1,229 +0,0 @@ -var should = require('should'); - -var Parser = require('../../lib/parser'); -var Engine = require('../../lib/engine'); -var AstHelper = require('../../lib/ast_helper'); - -var runExpr = Engine.run; -var createBinaryExpr = AstHelper.createBinaryExpr; - -function inspect(obj) { - //console.log(require('util').inspect(obj, false, 10, true)); -} - -describe('ast helper test', function(){ - - it('get column ref', function(){ - var sql = 'select a from c where a.c > 0 AND b != 2 AND d in (1, 2, 3) OR e like "hello"'; - - var ast = Parser.parse(sql); - var cols = AstHelper.getRefColumns(ast.where); - // inspect(cols); - cols.should.eql([ - { type: 'column_ref', table: 'a', column: 'c' }, - { type: 'column_ref',table: '',column: 'b' }, - { type: 'column_ref',table: '',column: 'd' }, - { type: 'column_ref',table: '',column: 'e' } - ]); - }) - - it('create binary expr', function(){ - var g = createBinaryExpr('>', {type : 'column_ref', value : 'a'}, 0); - var e = createBinaryExpr('=', {type : 'column_ref', value : 'b'}, 0); - //inspect(g); - var a = createBinaryExpr('AND', g, e); - a.should.eql({ - operator: 'AND', - type: 'binary_expr', - left:{ - operator: '>', - type: 'binary_expr', - left: { - type: 'column_ref', - value: 'a' - }, - right: { - type: 'number', - value: 0 - } - }, - right:{ - operator: '=', - type: 'binary_expr', - left: { - type: 'column_ref', - value: 'b' - }, - right: { - type: 'number', - value: 0 - } - } - }); - }) - - it('arithmetic expr', function(){ - var e, r; - e = createBinaryExpr('+', 1, 2); - r = runExpr(e); - r.should.eql(3); - - e = createBinaryExpr('-', 1, 2); - r = runExpr(e); - r.should.eql(-1); - - e = createBinaryExpr('*', 1.0, 5); - r = runExpr(e); - r.should.eql(5); - - e = createBinaryExpr('/', 5, 2); - r = runExpr(e); - r.should.eql(2.5); - - e = createBinaryExpr('%', 5, 3); - r = runExpr(e); - r.should.eql(2); - }); - - it('comparison expr', function(){ - var e, r; - e = createBinaryExpr('>', 1, 0); - r = runExpr(e); - should.ok(r); - - e = createBinaryExpr('>=', 1, 0); - r = runExpr(e); - should.ok(r); - - e = createBinaryExpr('<', 1, 0); - r = runExpr(e); - r.should.eql(false); - - e = createBinaryExpr('<=', 1, 0); - r = runExpr(e); - r.should.eql(false); - - e = createBinaryExpr('!=', 1, 0); - r = runExpr(e); - should.ok(r); - - e = createBinaryExpr('=', 1, 0); - r = runExpr(e); - r.should.eql(false); - - e = createBinaryExpr('<>', 1, 0); - r = runExpr(e); - should.ok(r); - - e = createBinaryExpr('BETWEEN', 1, [0, 2]); - r = runExpr(e); - should.ok(r); - - e = createBinaryExpr('IS', 1, 0); - r = runExpr(e); - r.should.eql(false); - - e = createBinaryExpr('IN', 1, [0, 1, 2]); - r = runExpr(e); - should.ok(r); - - e = createBinaryExpr('NOT IN', 1, [0, 1, 2]); - r = runExpr(e); - r.should.eql(false); - }) - - it('unary expr', function(){ - var e, r; - e = { - type : 'unary_expr', - operator : 'NOT', - expr : createBinaryExpr('=', 1, 0) - }; - r = runExpr(e); - should.ok(r); - }) - - it('logic expr', function(){ - var e, r; - e = createBinaryExpr('AND', true, true); - r = runExpr(e); - should.ok(r); - - e = createBinaryExpr('AND', false, true); - r = runExpr(e); r.should.eql(false); - - e = createBinaryExpr('OR', false, true); - r = runExpr(e); - r.should.eql(true); - - e = createBinaryExpr('OR', false, true); - r = runExpr(e); - r.should.eql(true); - - e = createBinaryExpr('OR', false, false); - r = runExpr(e); - r.should.eql(false); - }) - - it('aggr function call ', function(){ - var e, r; - e = { - type : 'aggr_func', - name : '', - args : { - expr : { - value :[1,2, 3] - } - } - } - e.name = 'COUNT' - r = runExpr(e); - r.should.eql(3) - - e.name = 'SUM', - r = runExpr(e); - inspect(r); - r.should.eql(6) - - e.name = 'AVG'; - r = runExpr(e); - r.should.eql(2) - - e.name = 'MAX'; - r = runExpr(e); - r.should.eql(3) - - e.name = 'MIN'; - r = runExpr(e); - r.should.eql(1) - }) - - it('function call ', function(){ - var e, r; - e = { - type : 'function', - name : '', - args : [1,2, 3] - } - - e.name = 'floor'; - e.args = { - type : 'expr_list', - value : [ - {type : 'number', value : 1.5} - ] - } - r = runExpr(e); - r.should.eql(1) - - e.name = 'floor'; - e.args = [1.5]; - r = runExpr(e); - r.should.eql(1) - - e.name = 'CEILING'; - e.args = [1.5]; - r = runExpr(e); - r.should.eql(2); - }) -}) diff --git a/test/unit/column.js b/test/unit/column.js deleted file mode 100644 index 90c215c..0000000 --- a/test/unit/column.js +++ /dev/null @@ -1,219 +0,0 @@ -var should = require('should'); - -var Parser = require('../../lib/parser'); -var AstHelper = require('../../lib/ast_helper'); -var createBinaryExpr = AstHelper.createBinaryExpr; - -var filter = require('../../base/column'); - -var AstReader = AstHelper.Reader; - -function inspect(obj) { - console.log(require('util').inspect(obj, false, 10, true)); -} - -describe('column filter test', function(){ - it('column simple select', function(){ - var rawData = { - columns: [ - [{table : 'a', column : 'id'}, {table : 'b', column : 'id'}], - [{table : 'a', column : 'name'}], - [{table : 'b', column : 'type'}] - ], - data: [ - [ 1, 'a', 't1' ], - [ 2, 'b', 't2' ], - [ 2, 'b', 't3' ], - [ 3, 'c', 't3' ], - [ 3, 'c', 't4' ], - [ 5, 'b', 't3' ], - [ 6, 'b', 't4' ] - ] - }; - - var idSel = {type : 'column_ref', table : 'a', column : 'id'}; - var typeSel = {type : 'column_ref', table : 'b', column : 'type'}; - //sm.where('a.id',WHERE.EQ, 3); - //inspect(e); - var e = { - columns : [ - {expr : idSel, as : ''}, - {expr : typeSel, as : ''} - ] - } - - var res = filter(rawData, e.columns); - res.data.should.eql([ - [ 1, 't1' ], - [ 2, 't2' ], - [ 2, 't3' ], - [ 3, 't3' ], - [ 3, 't4' ], - [ 5, 't3' ], - [ 6, 't4' ] - ]); - }); - - /* - it('error ', function(){ - var rawData = { - columns: [ - ['a.id', 'b.id'], - ['a.name'], - ['b.type'] - ], - data: [ - [ 1, 'a', 't1' ] - ] - }; - var e = createBinaryExpr('=', {type : 'column_ref', column : 'id'}, 3); - //sm.where('a.id',WHERE.EQ, 3); - //inspect(e); - try{ - var res = filter(rawData, e); - }catch(e) { - e.message.should.include('no column found for :id'); - } - should.not.exist(res); - }); - */ - - it('all scan ', function(){ - var rawData = { - columns: [ - [{table : 'a', column : 'id'}, {table : 'b', column : 'id'}], - [{table : 'a', column : 'name'}], - [{table : 'b', column : 'type'}] - ], - data: [ - [ 1, 'a', 't1' ], - [ 2, 'a', 't1' ] - ] - }; - var e, res; - e = { - columns: '*' - }; - - res = filter(rawData, e.columns); - res.should.eql(rawData); - }); - - it('alias select ', function(){ - var rawData = { - columns: [ - [{table : 'a', column : 'id'}, {table : 'b', column : 'id'}], - [{table : 'a', column : 'name'}], - [{table : 'b', column : 'type'}] - ], - data: [ - [ 1, 'a', 't1' ], - [ 2, 'a', 't1' ] - ] - }; - var idSel = {type : 'column_ref', column : 'id', table : 'a'}; - var typeSel = {type : 'column_ref', column : 'type', table : 'b'}; - //sm.where('a.id',WHERE.EQ, 3); - //inspect(e); - var e = { - columns : [ - {expr : idSel, as : 'aaid'}, - {expr : typeSel, as : ''} - ] - } - var res = filter(rawData, e.columns); - res.columns.should.eql([ - [{table : 'a', column : 'id'}, {table : '', column : 'aaid'}], - [{table : 'b', column : 'type'}] - ]); - }); - - - it('calculation select ', function(){ - var rawData = { - columns: [ - [{table : 'a', column : 'id'}, {table : 'b', column : 'id'}], - [{table : 'a', column : 'name'}], - [{table : 'b', column : 'type'}] - ], - data: [ - [ 1, 'a', 't1' ], - [ 2, 'a', 't1' ] - ] - }; - var e, res; - e = { - columns: [ - { - expr : { - type : 'binary_expr', - operator : '+', - left : { - type : 'column_ref', - column : 'id', - table : 'a' - }, - right : { - type : 'number', - value : 5 - } - }, - as : '' - } - ] - }; - res = filter(rawData, e.columns); - res.data.should.eql([ - [ 6 ], - [ 7] - ]) - - }); - - it('complicated calculation select ', function(){ - var rawData = { - columns: [ - [{table : 'a', column : 'id'}, {table : 'b', column : 'id'}], - [{table : 'a', column : 'name'}], - [{table : 'b', column : 'type'}] - ], - data: [ - [ 1, 'a', 5 ], - [ 2, 'a', 6 ] - ] - }; - var e, res; - e = { - columns: [ - { - expr : { - type : 'binary_expr', - operator : '+', - left : { - type : 'column_ref', - column : 'id', - table : 'a' - }, - right : { - type : 'column_ref', - column : 'type', - table : 'b' - } - }, - as : 'id_type_add' - } - ] - }; - res = filter(rawData, e.columns); - res.should.eql({ - columns : [ - [{table : '', column : 'a.id + b.type'}, {table : '', column : 'id_type_add'}] - ], - data : [ - [ 6 ], - [ 8] - ] - }); - - }); -}); diff --git a/test/unit/create.test.js b/test/unit/create.test.js new file mode 100644 index 0000000..237a475 --- /dev/null +++ b/test/unit/create.test.js @@ -0,0 +1,22 @@ +'use strict'; + +var parser = require('../../lib/parse'); +var stringify = require('../../lib/stringify'); +var expect = require('./expect'); +describe('SQL create', function () { + describe('create table simple', function () { + it.skip('should work fine when create table', function () { + var sql = ` + create table xxxx if not exists ( + a string comment 'xxx' + ); + `; + var result = parser.parse(sql); + var resSql = stringify(result); + expect(result) + .type('create') + .columns(['sum(abc,1)', 'def']); + resSql.toLowerCase().should.equal(sql); + }); + }); +}); diff --git a/test/unit/distinct.js b/test/unit/distinct.js deleted file mode 100644 index a69e2a2..0000000 --- a/test/unit/distinct.js +++ /dev/null @@ -1,47 +0,0 @@ -/* vim: set expandtab tabstop=2 shiftwidth=2 foldmethod=marker: */ -// +--------------------------------------------------------------------+ -// | (C) 2011-2012 Alibaba Group Holding Limited. | -// | This program is free software; you can redistribute it and/or | -// | modify it under the terms of the GNU General Public License | -// | version 2 as published by the Free Software Foundation. | -// +--------------------------------------------------------------------+ - -var should = require('should'); -var distinct = require('../../base/distinct'); - -var AstReader = require('../../lib/ast_helper').Reader; - -describe('disticnt test', function() { - - it('basic distinct test', function() { - var data = { - - columns : ['a', 'b', 'c'], - data : [ - [1, 2, 3], - ['1', 2, 3], - [2, 3, 4], - [2, 4, 4], - [4, 3, 4], - [3, 3, 4], - [2, 3, 4], - [2, 4, 4], - [6, 3, 4], - [1, 2, 3], - ] - } - - var res = distinct(data); - res.data.should.eql([ - [1, 2, 3], - ['1', 2, 3], - [2, 3, 4], - [2, 4, 4], - [4, 3, 4], - [3, 3, 4], - [6, 3, 4], - ] - ); - }); - -}); diff --git a/test/unit/executor.js b/test/unit/executor.js deleted file mode 100644 index d917b8e..0000000 --- a/test/unit/executor.js +++ /dev/null @@ -1,276 +0,0 @@ -var should = require('should'); -var Parser = require('../../lib/parser'); -var Executor = require('../../lib/executor'); - -function debug(str) { - console.log(str); -} - -function inspect(obj) { - console.log(require('util').inspect(obj, false, 10, true)); -} - -describe('executor test', function(){ - var rawData = { - columns: [ - 'id', 'sex' - ], - data: [ - [ 3, 'f' ], - [ 4, 'f' ], - [ 6, 'f' ], - [ 8, 'f' ], - [ 10, 'f' ] - ] - }; - - it('column all test', function(done){ - var str, ast; - - str = 'select * from a' - ast = Parser.parse(str); - Executor.setLoader(function(ar, env, cb){ - cb(null, rawData, ar); - }); - - Executor.runAST(ast, function(err, dc){ - if (err) { - debug(err.stack); - } else { - dc.should.eql({ - columns: [ - 'id', 'sex' - ], - data: [ - [ 3, 'f' ], - [ 4, 'f' ], - [ 6, 'f' ], - [ 8, 'f' ], - [ 10, 'f' ] - ] - }); - done(); - } - }); - }); - - it('column select test', function(done){ - var str = 'select id from a'; - var ast = Parser.parse(str); - - Executor.setLoader(function(ar, env, cb){ - cb(null, rawData, ar); - }); - - Executor.runAST(ast, function(err, dc){ - if (err) { - debug(err.stack); - } else { - dc.should.eql({ - columns : ['id'], - data : [ - [3], - [4], - [6], - [8], - [10] - ] - }); - done(); - } - }); - }); - - it('as column name replace ', function(done){ - var str = 'select id as rid, sex as rsex from a' - Executor.setLoader(function(ar, env, cb){ - cb(null, rawData, ar); - }); - var ast = Parser.parse(str); - Executor.runAST(ast, function(err, dc){ - if (err) { - debug(err.stack); - } else { - dc.should.eql({ - columns: [ 'rid', 'rsex' ], - data: [ - [ 3, 'f' ], - [ 4, 'f' ], - [ 6, 'f' ], - [ 8, 'f' ], - [ 10, 'f' ] - ] - }) - done(); - } - }); - }); - - it('limits filter test', function(done){ - var str = 'select * from a limit 1, 2' - Executor.setLoader(function(ar, env, cb){ - cb(null, rawData, ar); - }); - - var ast = Parser.parse(str); - Executor.runAST(ast, function(err, dc){ - if (err) { - debug(err.stack); - } else { - dc.should.eql({ - columns: [ 'id', 'sex' ], - data: [ - [ 4, 'f' ], - [ 6, 'f' ] - ] - }) - done(); - }; - }); - }); - - it('order filter test', function(done){ - var rawData = { - columns: [ - 'id', 'sex' - ], - data: [ - [ 3, 'a' ], - [ 4, 'f' ], - [ 4, 'b' ], - [ 8, 'f' ], - [ 10, 'c' ] - ] - }; - var str = 'select * from a order by sex ASc, id DESC ' - Executor.setLoader(function(ar, env, cb){ - cb(null, rawData, ar); - }); - - var ast = Parser.parse(str); - Executor.runAST(ast, function(err, dc){ - if (err) { - debug(err.stack); - } else { - dc.should.eql({ - columns: [ 'id', 'sex' ], - data: [ - [ 3, 'a' ], - [ 4, 'b' ], - [ 10, 'c' ], - [ 8, 'f' ], - [ 4, 'f' ] - ] - }); - done(); - }; - }); - }); - - it('groupby filter test', function(){ - var rawData = { - columns: [ - 'id', 'sex' - ], - data: [ - [ 3, 'a' ], - [ 4, 'f' ], - [ 4, 'g' ], - [ 4, 'b' ], - [ 4, 'b' ], - [ 8, 'b' ], - [ 8, 'a' ], - [ 9, 'f' ], - [ 10, 'c' ] - ] - }; - - Executor.setLoader(function(ar, env, cb){ - cb(null, rawData, ar); - }); - var str = 'select id, sex from data group by id' - - var ast = Parser.parse(str); - Executor.runAST(ast, function(err, dc){ - if (err) { - debug(err.stack); - } else { - dc.should.eql({ - columns: [ 'id', 'sex' ], - data: [ - [ 3, 'a' ], - [ 4, 'f' ], - [ 8, 'b' ], - [ 9, 'f' ], - [ 10, 'c' ] - ] - }); - } - }); - - str = 'select id, count(id) from data group by id' - - ast = Parser.parse(str); - Executor.runAST(ast, function(err, dc){ - if (err) { - debug(err.stack); - } else { - dc.should.eql({ - columns: [ 'id', 'COUNT(id)' ], - data: [ - [ 3, 1 ], - [ 4, 4 ], - [ 8, 2 ], - [ 9, 1 ], - [ 10, 1 ] - ] - }); - } - }); - - }) - - it('groupby&orderby ', function(){ - var rawData = { - columns : [ - 'id', 'sex' - ], - data: [ - [ 3, 'a' ], - [ 4, 'f' ], - [ 4, 'g' ], - [ 4, 'b' ], - [ 4, 'b' ], - [ 8, 'b' ], - [ 8, 'a' ], - [ 9, 'f' ], - [ 10, 'c' ] - ] - }; - - Executor.setLoader(function(ar, env, cb){ - cb(null, rawData, ar); - }); - var str = 'select id, min(sex) as msex from data group by id order by count(id)' - - var ast = Parser.parse(str); - Executor.runAST(ast, function(err, dc){ - if (err) { - debug(err.stack); - } else { - dc.should.eql({ - columns: [ 'id', 'msex' ], - data: [ - [ 3, 'a' ], - [ 9, 'f' ], - [ 10, 'c' ], - [ 8, 'a' ], - [ 4, 'b' ], - ] - }); - } - }); - - }); - -}); diff --git a/test/unit/expect.js b/test/unit/expect.js new file mode 100644 index 0000000..4c3d3c9 --- /dev/null +++ b/test/unit/expect.js @@ -0,0 +1,69 @@ +/*! + * node-sqlparser: test/unit/expect.js + * Authors : 剪巽 (https://github.com/fishbar) + * Create : 2014-05-21 18:05:12 + * CopyRight 2014 (c) Alibaba Group + */ +function expect(ast) { + if (this instanceof expect) { + this._ast = ast; + } else { + return new expect(ast); + } +}; + +expect.prototype = { + type: function (type) { + this._ast.type.should.eql(type); + return this; + }, + columns: function (ffs) { + var ff = {}; + ffs.forEach(function (v) { + ff[v] = 0; + }); + this._ast.columns.forEach(function (v) { + var expr = v.expr; + var key; + switch (expr.type) { + case 'column_ref': + key = (expr.table ? expr.table + '.' : '') + expr.column; + break; + case 'aggr_func': + key = expr.name; + break; + } + }); + return this; + }, + from: function () { + return this; + }, + limit: function () { + var limit = this._ast.limit; + var res = []; + var args = arguments; + var flag = true; + limit.forEach(function (v, i) { + var value; + if (v.type === 'number') { + value = parseInt(v.value, 10); + } else { + value = v; + } + if (value !== args[i]) { + flag = false; + } + }); + if (!flag) { + throw new Error('limit check failed!'); + } + return this; + } +} + +function toStringFunc(node) { + var key = node.name + 1; +} + +module.exports = expect; \ No newline at end of file diff --git a/test/unit/expr.js b/test/unit/expr.js deleted file mode 100644 index 615f06c..0000000 --- a/test/unit/expr.js +++ /dev/null @@ -1,531 +0,0 @@ -var should = require('should'); -var Parser = require(__dirname + '/../../lib/parser'); - -function inspect(obj) { - //console.log(require('util').inspect(obj, false, 10, true)); -} - -describe('expression test',function(){ - - it('primary expr test', function() { - var sql, ast; - sql = "SELECT 1, 'str', `select`, true, fun(4), rand(), :id+1, cf1:name, :select"; - ast = Parser.parse(sql); - //inspect(ast.columns); - ast.columns.should.eql([ - { expr: { type: 'number', value: 1 },as: '' }, - { expr: { type: 'string', value: 'str' },as: '' }, - { expr: { type: 'column_ref', column: 'select', table : '' },as: '' }, - { expr: { type: 'bool', value: true },as: '' }, - { - expr: { - type: 'function', - name: 'fun', - args: { - type : 'expr_list', - value : [ { type: 'number', value: 4 } ] - } - }, - as: '' - }, - { - expr: { - type: 'function', - name: 'rand', - args: { - type : 'expr_list', - value : [] - } - }, - as: '' - }, - { - expr: { - type: 'binary_expr', - operator: '+', - left: { type: 'param', value: 'id' }, - right: { type: 'number', value: 1 } - }, - as: '' - }, - { - expr: { - type: 'column_ref', - table: '', - column: 'cf1:name' - }, - as: '' - }, - { expr: { type: 'param', value: 'select' },as: '' } - ]) - }); - - it('aggr function test', function() { - var sql, ast; - - sql = "SELECT count(distinct a.id), count(*), SUM(a.id)"; - ast = Parser.parse(sql); - inspect(ast); - ast.columns.should.eql([ - { - expr: { - type: 'aggr_func', - name: 'COUNT', - args: { - distinct: 'DISTINCT', - expr: { - type: 'column_ref', - table: 'a', - column: 'id' - } - } - }, - as: '' - }, - { - expr: { - type: 'aggr_func', - name: 'COUNT', - args: { - expr : { - type: 'star', value: '*' - } - } - }, - as: '' - }, - { - expr: { - type: 'aggr_func', - name: 'SUM', - args: { - expr : { - type : 'column_ref', - table : 'a', - column: 'id' - } - } - }, - as: '' - } - ]); - - }); - - it('multiplicative expr test', function() { - var sql, ast; - - sql = "SELECT (1*2/3 % fun(4))"; - ast = Parser.parse(sql); - ast.columns.should.eql([{ - expr: { - type: 'binary_expr', - operator: '%', - left: { - type: 'binary_expr', - operator: '/', - left: { - type: 'binary_expr', - operator: '*', - left: { - type: 'number', - value: 1 - }, - right: { - type: 'number', - value: 2 - } - }, - right: { - type: 'number', - value: 3 - } - }, - right: { - type: 'function', - name: 'fun', - args: { - type : 'expr_list', - value : [ { type: 'number', value: 4 } ] - } - }, - paren: true - }, - as: '' - }]); - - }); - - it('additive expr test', function() { - var sql, ast; - - sql = "SELECT (1*2-3+4/5 + 3 % fun(4))"; - ast = Parser.parse(sql); - ast.columns.should.eql([{ - expr: { - type: 'binary_expr', - operator: '+', - left: { - type: 'binary_expr', - operator: '+', - left: { - type: 'binary_expr', - operator: '-', - left: { - type: 'binary_expr', - operator: '*', - left: { - type: 'number', value: 1 - }, - right: { - type: 'number', value: 2 - } - }, - right: { - type: 'number', - value: 3 - } - }, - right: { - type: 'binary_expr', - operator: '/', - left: { - type: 'number', value: 4 - }, - right: { - type: 'number', value: 5 - } - } - }, - right: { - type: 'binary_expr', - operator: '%', - left: { - type: 'number', value: 3 - }, - right: { - type: 'function', - name: 'fun', - args: { - type : 'expr_list', - value : [ { type: 'number', value: 4 } ] - } - } - }, - paren: true - }, - as: '' - }]); - - }); - - it('arithmetic comparison expr test', function() { - var sql, ast; - - sql = "SELECT a FROM b WHERE c > 1+ 3 <= 2 != 1"; - ast = Parser.parse(sql); - - //inspect(ast.where); - ast.where.should.eql({ - type: 'binary_expr', - operator: '!=', - left: { - type: 'binary_expr', - operator: '<=', - left: { - type: 'binary_expr', - operator: '>', - left: { - type: 'column_ref', - table: '', - column: 'c' - }, - right: { - type: 'binary_expr', - operator: '+', - left: { type: 'number', value: 1 }, - right: { type: 'number', value: 3 } - } - }, - right: { type: 'number', value: 2 } - }, - right: { type: 'number', value: 1 } - }) - - }); - - it('in comparison expr test', function() { - var sql, ast; - - sql = "SELECT a FROM b WHERE c in(1, nUll, 3, 'str')"; - ast = Parser.parse(sql); - - ast.where.should.eql({ - type: 'binary_expr', - operator: 'IN', - left:{ - type: 'column_ref', - table: '', - column: 'c' - }, - right: { - type : 'expr_list', - value : [ - { type: 'number', value: 1 }, - { type: 'null', value: null }, - { type: 'number', value: 3}, - { type: 'string', value: 'str' } - ] - } - }); - - }); - - it('is comparison expr test', function() { - var sql, ast; - - sql = "SELECT a FROM b WHERE c IS NULL"; - ast = Parser.parse(sql); - - ast.where.should.eql({ - type: 'binary_expr', - operator: 'IS', - left:{ - type: 'column_ref', - table: '', - column: 'c' - }, - right: { type: 'null', value: null } - }); - }); - - it('like comparison expr test', function() { - var sql, ast; - - sql = "SELECT a FROM b WHERE c lIke 'p'"; - ast = Parser.parse(sql); - - ast.where.should.eql({ - type: 'binary_expr', - operator: 'LIKE', - left:{ - type: 'column_ref', - table: '', - column: 'c' - }, - right: { type: 'string', value: 'p' } - }); - - }); - - it('between comparison expr test', function() { - var sql, ast; - sql = "SELECT a FROM b WHERE c between 1 and '5'"; - ast = Parser.parse(sql); - - ast.where.should.eql({ - type: 'binary_expr', - operator: 'BETWEEN', - left: { - type: 'column_ref', - table: '', - column: 'c' - }, - right: { - type : 'expr_list', - value : [ - { type: 'number', value: 1 }, - { type: 'string', value: '5' } - ] - } - }) - }); - - it('NOT expr test', function() { - var sql, ast; - sql = "SELECT a FROM b WHERE c = (! NOT 1 > 2)"; - ast = Parser.parse(sql); - - //inspect(ast.where); - - ast.where.should.eql({ - type: 'binary_expr', - operator: '=', - left: { - type: 'column_ref', - table: '', - column: 'c' - }, - right: { - type: 'unary_expr', - operator: 'NOT', - expr: { - type: 'unary_expr', - operator: 'NOT', - expr: { - type: 'binary_expr', - operator: '>', - left: { type: 'number', value: 1}, - right: { type: 'number', value: 2 } - } - }, - paren: true - } - }) - - }); - - //priorty : `AND` < `NOT` < `Comaprison` - it('AND expr test', function() { - var sql, ast; - sql = "SELECT a FROM b WHERE NOT c > 0 And NOT a > 1 "; - ast = Parser.parse(sql); - - //inspect(ast.where); - - ast.where.should.eql({ - type: 'binary_expr', - operator: 'AND', - left: { - type: 'unary_expr', - operator: 'NOT', - expr: { - type: 'binary_expr', - operator: '>', - left: { - type: 'column_ref', - table: '', - column: 'c' - }, - right: { - type: 'number', value: 0 - } - } - }, - right: { - type: 'unary_expr', - operator: 'NOT', - expr:{ - type: 'binary_expr', - operator: '>', - left: { - type: 'column_ref', - table: '', - column: 'a' - }, - right: { type: 'number', value: 1 } - } - } - }) - }); - - it('OR expr test', function() { - var sql, ast; - - sql = "SELECT a FROM b WHERE c = 0 OR d > 0 AND e < 0"; - ast = Parser.parse(sql); - //inspect(ast.where); - ast.where.should.eql({ - type: 'binary_expr', - operator: 'OR', - left: { - type: 'binary_expr', - operator: '=', - left: { - type: 'column_ref', - table: '', - column: 'c' - }, - right: { - type: 'number', value: 0 - } - }, - right: { - type: 'binary_expr', - operator: 'AND', - left: { - type: 'binary_expr', - operator: '>', - left: { - type: 'column_ref', - table: '', - column: 'd' - }, - right: { - type: 'number', - value: 0 - } - }, - right: { - type: 'binary_expr', - operator: '<', - left: { - type: 'column_ref', - table: '', - column: 'e' - }, - right: { - type: 'number', - value: 0 - } - } - } - }); - - // priority : 'AND' > 'OR' - sql = "SELECT a FROM b WHERE c = 0 AND d > 0 OR e < 0"; - ast = Parser.parse(sql); - - //inspect(ast.where); - ast.where.should.eql({ - type: 'binary_expr', - operator: 'OR', - left: { - type: 'binary_expr', - operator: 'AND', - left: { - type: 'binary_expr', - operator: '=', - left: { - type: 'column_ref', - table: '', - column: 'c' - }, - right: { - type: 'number', - value: 0 - } - }, - right: { - type: 'binary_expr', - operator: '>', - left: { - type: 'column_ref', - table: '', - column: 'd' - }, - right: { - type: 'number', - value: 0 - } - } - }, - right: { - type: 'binary_expr', - operator: '<', - left: { - type: 'column_ref', - table: '', - column: 'e' - }, - right: { - type: 'number', - value: 0 - } - } - }); - - }); - -}); - diff --git a/test/unit/extractor.js b/test/unit/extractor.js deleted file mode 100644 index 3e4f9cf..0000000 --- a/test/unit/extractor.js +++ /dev/null @@ -1,119 +0,0 @@ -var should = require('should'); -var Parser = require('../../lib/parser'); -var Engine = require('../../lib/engine'); -var Context = require('../../lib/context'); -var Extractor = require('../../lib/extractor'); - -var Topo = require('../../base/topology'); - -function inspect(obj) { - //console.log(require('util').inspect(obj, false, 10, true)); -} - -describe('extractor test',function(){ - var options = { - 'storageType' : 'kv', - 'primaryKeys' : ['id'], - 'rangeQuery' : true, - 'prefixMatch' : true - } - - it('single-key simple test', function() { - var sql ,ast, info; - //sql = "select * from a where id > 0 AND name < 0 and id = 3 and type = 't' and id in ('1', '2') AND (id = 4 OR id =5) OR id = 2", - sql = "select * from a where id = 2", - ast = Parser.parse(sql); - inspect(ast); - info = Extractor.getKeyInfo(ast.where, options); - - info.should.eql({ - 'IN' : [2] - }) - - sql = "select * from a where id = 2 OR nid = 2", - ast = Parser.parse(sql); - inspect(ast); - try { - info = Extractor.getKeyInfo(ast.where, options); - } catch(e) { - e.message.should.include('primary keys not ful-filled'); - } - }); - - it('single-key and link test', function() { - var sql ,ast, info; - sql = "select * from a where id > 0 AND name < 0 and id = 3 and type = 't' and id in ('1', '2') AND (id = 4 OR id =5)", - //sql = "select * from a where id > 0 AND name < 0 and id = 3"; - ast = Parser.parse(sql); - inspect(ast); - info = Extractor.getKeyInfo(ast.where, options); - inspect(info); - info.should.eql({ - 'IN' : [3, '1', '2', 4, 5] - }) - }); - - it('single-key OR link test', function() { - var sql ,ast, info; - sql = "select * from a where id > 0 AND id = 3 OR (id = 4 OR id =5)", - //sql = "select * from a where id > 0 AND name < 0 and id = 3"; - ast = Parser.parse(sql); - inspect(ast); - info = Extractor.getKeyInfo(ast.where, options); - inspect(info); - info.should.eql({ - 'IN' : [3, 4, 5] - }) - }); - - it('single-key bind var test', function() { - var sql ,ast, info, env; - sql = "select * from a where id > 0 AND id = $id OR id = $id + 3 OR id = $arr"; - env = { - id : -1, - arr : [4, 5] - } - //sql = "select * from a where id > 0 AND name < 0 and id = 3"; - ast = Parser.parse(sql); - inspect(ast); - Context.setctx(env); - info = Extractor.getKeyInfo(ast.where, options); - inspect(info); - info.should.eql({ - 'IN' : [-1, 2, 4, 5] - }) - }); - - it('single-key range-query test', function() { - var sql ,ast, info, env; - sql = "select * from a where id = 2 OR id between 5 and 7"; - //sql = "select * from a where id > 0 AND name < 0 and id = 3"; - ast = Parser.parse(sql); - inspect(ast); - info = Extractor.getKeyInfo(ast.where, options, env); - inspect(info); - info.should.eql({ - 'IN' : [2], - 'BETWEEN' : [ - [5, 7] - ] - }) - }); - - it('single-key prefix-match test', function() { - var sql ,ast, info, env; - sql = "select * from a where id = 2 OR id LIKE 'hello%' OR id LIKE 'world%'"; - //sql = "select * from a where id > 0 AND name < 0 and id = 3"; - ast = Parser.parse(sql); - inspect(ast); - info = Extractor.getKeyInfo(ast.where, options, env); - inspect(info); - info.should.eql({ - 'IN' : [2], - 'LIKE' : [ - 'hello', 'world' - ] - }) - }); - -}); diff --git a/test/unit/groupby.js b/test/unit/groupby.js deleted file mode 100644 index 8a49c06..0000000 --- a/test/unit/groupby.js +++ /dev/null @@ -1,90 +0,0 @@ -var should = require('should'); -var doGroupby = require('../../base/groupby'); - -function inspect(obj){ - console.log(require('util').inspect(obj, false, 10)); -} - -describe('data filter test', function(){ - - var rawData = { - columns: [ - [{table : 'a', column : 'id'}, {table : 'b', column : 'id'}], - [{table : 'a', column : 'name'}], - [{table : 'b', column : 'type'}] - ], - data: [ - [ 1, 'a', 't1' ], - [ 2, 'b', 't2' ], - [ 2, 'b', 't3' ], - [ 3, 'c', 't3' ], - [ 3, 'c', 't4' ], - [ 5, 'b', 't3' ], - [ 6, 'b', 't4' ] - ] - }; - - it('groupb data test', function(){ - var gbArr = [{table : 'a', column : 'name'}, {table : 'b', column : 'id'}]; - var eData = { - 'string_a__number_1' : { - columns: [ - [{table : 'a', column : 'id'}, {table : 'b', column : 'id'}], - [{table : 'a', column : 'name'}], - [{table : 'b', column : 'type'}] - ], - data: [ - [ 1, 'a', 't1' ] - ] - }, - 'string_b__number_2' : { - columns: [ - [{table : 'a', column : 'id'}, {table : 'b', column : 'id'}], - [{table : 'a', column : 'name'}], - [{table : 'b', column : 'type'}] - ], - data: [ - [ 2, 'b', 't2' ], - [ 2, 'b', 't3' ], - ] - }, - 'string_c__number_3' : { - columns: [ - [{table : 'a', column : 'id'}, {table : 'b', column : 'id'}], - [{table : 'a', column : 'name'}], - [{table : 'b', column : 'type'}] - ], - data: [ - [ 3, 'c', 't3' ], - [ 3, 'c', 't4' ] - ] - }, - 'string_b__number_5' : { - columns: [ - [{table : 'a', column : 'id'}, {table : 'b', column : 'id'}], - [{table : 'a', column : 'name'}], - [{table : 'b', column : 'type'}] - ], - data: [ - [ 5, 'b', 't3' ], - ] - }, - 'string_b__number_6' : { - columns: [ - [{table : 'a', column : 'id'}, {table : 'b', column : 'id'}], - [{table : 'a', column : 'name'}], - [{table : 'b', column : 'type'}] - ], - data: [ - [ 6, 'b', 't4' ] - ] - } - }; - - var sData = doGroupby(rawData, gbArr); - //inspect(sData); - JSON.stringify(sData).should.eql(JSON.stringify(eData)); - }); - - -}); diff --git a/test/unit/jobs.js b/test/unit/jobs.js deleted file mode 100644 index bb6f8f2..0000000 --- a/test/unit/jobs.js +++ /dev/null @@ -1,81 +0,0 @@ -var should = require('should'); - -var Jobs = require(__dirname + '/../../lib/jobs'); - -function debug(str) { - //console.log(str); -} -function inspect(obj) { - //console.log(require('util').inspect(obj, false, 10, true)); -} - -function Task(fn) { - this._fn = fn; -} - -Task.prototype.run = function(cb) { - this._fn(cb); -} - -var t0 = new Task(function(cb) { - debug('task 0 init'); - debug('task 0 ok'); - cb(null); -}); - -var t1 = new Task(function(cb) { - debug('task1 init'); - setTimeout(function() { - debug('task 1 ok'); - cb(null); - }, 5); -}); - -var t2 = new Task(function(cb) { - debug('task2 init'); - setTimeout(function() { - debug('task 2 ok'); - cb(null); - }, 30); -}); - -var t3 = new Task(function(cb) { - debug('task3 init'); - setTimeout(function() { - debug('task 3 err'); - cb(new Error('Task3 Failed')); - }, 10); -}); - - -describe('jobs test', function(){ - - it('concurrent ok test', function(done) { - Jobs.doConcurrent([t0, t1, t2], function(err){ - should.equal(null, err); - done(); - }); - }); - - it('concurrent error test', function(done) { - Jobs.doConcurrent([t0, t3, t2], function(err){ - err.message.should.eql('Task3 Failed') - done(); - }); - }); - - it('sequential ok test', function(done) { - Jobs.doSequential([t0, t1, t2], function(err){ - should.equal(null, err); - done(); - }); - }); - - it('sequential error test', function(done) { - Jobs.doSequential([t0, t3, t2], function(err){ - err.message.should.eql('Task3 Failed') - done(); - }); - }); - -}); diff --git a/test/unit/join.js b/test/unit/join.js deleted file mode 100644 index 1b586b3..0000000 --- a/test/unit/join.js +++ /dev/null @@ -1,148 +0,0 @@ -/* vim: set expandtab tabstop=2 shiftwidth=2 foldmethod=marker: */ -// +--------------------------------------------------------------------+ -// | (C) 2011-2012 Alibaba Group Holding Limited. | -// | This program is free software; you can redistribute it and/or | -// | modify it under the terms of the GNU General Public License | -// | version 2 as published by the Free Software Foundation. | -// +--------------------------------------------------------------------+ -// Author: fengyin - -var should = require('should'); -var Join = require(__dirname + '/../../base/join'); - -var ta, tb; - -describe('join test', function() { - - before(function(){ - ta = { - columns : [ - [{table : 'a', column : 'id'}], - [{table : 'a', column : 'name'}], - [{table : 'a', column : 'text'}] - ], - data : [ - [1, 'a', 'ta'], - [2, 'b', 'tb'], - [5, 'e', 'te'], - [7, 'f', 'tf'] - ] - } - - tb = { - columns : [ - [{table : 'b', column : 'id'}], - [{table : 'b', column : 'name'}], - [{table : 'b', column : 'des'}] - ], - data : [ - [2, 'c', 'db'], - [2, 'd', 'db'], - [6, 'e', 'de'], - [7, 'f', 'df'], - [8, 'e', 'de'], - ] - } - - }); - - it('basic inner join ', function() { - - var on = { - left : [{table : 'a', column : 'id'}], - right : [{table : 'b', column : 'id'}] - } - - var res = Join.innerJoin(ta, tb ,on) - res.should.eql({ - columns : [ - [ - {table : 'a', column : 'id'}, - {table : 'b', column : 'id'} - ], - [{table : 'a', column : 'name'}], - [{table : 'a', column : 'text'}], - [{table : 'b', column : 'name'}], - [{table : 'b', column : 'des'}] - ], - data : [ - [2, 'b', 'tb', 'c', 'db'], - [2, 'b', 'tb', 'd', 'db'], - [7, 'f', 'tf', 'f', 'df'] - ] - }) - - }); - - it('multi-column inner join', function() { - var on = { - left : [{table : 'a', column : 'id'}, {table : 'a', column : 'name'}], - right : [{table : 'b', column : 'id'}, {table : 'b', column : 'name'}] - } - var res = Join.innerJoin(ta, tb ,on) - res.should.eql({ - columns : [ - [{table : 'a', column : 'id'}, {table : 'b', column : 'id'}], - [{table : 'a', column : 'name'}, {table : 'b', column : 'name'}], - [{table : 'a', column : 'text'}], - [{table : 'b', column : 'des'}] - ], - data : [ - [7, 'f', 'tf', 'df'] - ] - }) - }); - - it('basic left join ', function() { - - var on = { - left : [{table : 'a', column : 'id'}], - right : [{table : 'b', column : 'id'}] - } - - var res = Join.leftJoin(ta, tb ,on); - res.should.eql({ - columns : [ - [{table : 'a', column : 'id'}, {table : 'b', column : 'id'}], - [{table : 'a', column : 'name'}], - [{table : 'a', column : 'text'}], - [{table : 'b', column : 'name'}], - [{table : 'b', column : 'des'}] - ], - data : [ - [1, 'a', 'ta', null, null], - [2, 'b', 'tb', 'c', 'db'], - [2, 'b', 'tb', 'd', 'db'], - [5, 'e', 'te', null, null], - [7, 'f', 'tf', 'f', 'df'] - ] - }) - - }); - - it('multi-column left join ', function() { - - var on = { - left : [{table : 'a', column : 'id'}, {table : 'a', column : 'name'}], - right : [{table : 'b', column : 'id'}, {table : 'b', column : 'name'}] - } - - var res = Join.leftJoin(ta, tb ,on); - res.should.eql({ - columns : [ - [{table : 'a', column : 'id'}, {table : 'b', column : 'id'}], - [{table : 'a', column : 'name'}, {table : 'b', column : 'name'}], - [{table : 'a', column : 'text'}], - [{table : 'b', column : 'des'}] - ], - data : [ - [1, 'a', 'ta', null], - [2, 'b', 'tb', null], - [5, 'e', 'te', null], - [7, 'f', 'tf', 'df'] - ] - }) - - }); - -}); diff --git a/test/unit/limit.js b/test/unit/limit.js deleted file mode 100644 index 28ad053..0000000 --- a/test/unit/limit.js +++ /dev/null @@ -1,30 +0,0 @@ - -var should = require('should'); -var doLimitFilter = require('../../base/limit'); - -function inspect(obj) { - console.log(require('util').inspect(obj, false, 10, true)); -} - -describe('orderby test', function(){ - - it('basic test', function() { - var rawData = { - columns: [ ['id'], ['sex'] ], - data: [ - [ 3, 'a' ], - [ 4, 'f' ], - [ 4, 'b' ], - [ 8, 'f' ], - [ 10, 'c' ] - ] - }; - var ed = doLimitFilter(rawData, [1, 2]); - //inspect(ed); - ed.data.should.eql([ - [ 4, 'f' ], - [ 4, 'b' ] - ]); - }); - -}); diff --git a/test/unit/literal.js b/test/unit/literal.js deleted file mode 100644 index ecfc3d8..0000000 --- a/test/unit/literal.js +++ /dev/null @@ -1,51 +0,0 @@ -var should = require('should'); -var Parser = require(__dirname + '/../../lib/parser'); - -function inspect(obj) { - console.log(require('util').inspect(obj, false, 10, true)); -} - -describe('literal test',function(){ - - it('string literal test', function() { - var sql, ast; - - sql = "SELECT 'single str' ,\"double string \", ' escape \\n \\t \\u0002'"; - ast = Parser.parse(sql); - //inspect(ast.columns); - ast.columns.should.eql([ - { expr: { type: 'string', value: 'single str' }, as: '' }, - { expr: { type: 'string', value: 'double string ' }, as: '' }, - { expr: { type: 'string',value: ' escape \n \t \u0002' }, as: '' } - ]) - }); - - it('numeric literal test', function() { - var sql, ast; - - sql = "SELECT 1 ,2.5, -4.6, 1e2, 1e-10"; - ast = Parser.parse(sql); - //inspect(ast.columns); - ast.columns.should.eql([ - { expr: { type: 'number', value: 1 }, as: '' }, - { expr: { type: 'number', value: 2.5 }, as: '' }, - { expr: { type: 'number', value: -4.6 }, as: '' }, - { expr: { type: 'number', value: 100 }, as: '' }, - { expr: { type: 'number', value: 1e-10 }, as: '' } - ]) - }); - - it('bool&null literal test', function() { - var sql, ast; - - sql = "SELECT false, True, null"; - ast = Parser.parse(sql); - //inspect(ast.columns); - ast.columns.should.eql([ - { expr: { type: 'bool', value: false }, as: '' }, - { expr: { type: 'bool', value: true }, as: '' }, - { expr: { type: 'null', value: null }, as: '' } - ]) - }); -}) - diff --git a/test/unit/mcache.js b/test/unit/mcache.js deleted file mode 100644 index 61b3243..0000000 --- a/test/unit/mcache.js +++ /dev/null @@ -1,31 +0,0 @@ -var should = require('should'); -var MCache = require('../../base/mcache'); - -function inspect(obj) { - console.log(require('util').inspect(obj, false, 10, true)); -} - -describe('union test', function(){ - it('basic test', function(){ - var cache = new MCache(10000); - - for (var i = 0; i <=20000; i++) { - cache.set(i, i); - } - - should.not.exist(cache.get(9999)); - should.not.exist(cache.get(10000)); - should.not.exist(cache.get(2000001)); - - cache.get(7).should.eql(7); - cache.get(10).should.eql(10); - cache.get(9998).should.eql(9998); - - cache.get(20000).should.eql(20000); - - cache.top(12).should.eql([ - 0, 1, 2, 3, 4, 5, 7, 6, 8, 10, 9, 11 - ]) - }); - -}); diff --git a/test/unit/orderby.js b/test/unit/orderby.js deleted file mode 100644 index 8874403..0000000 --- a/test/unit/orderby.js +++ /dev/null @@ -1,58 +0,0 @@ -var should = require('should'); -var doOrderby = require('../../base/orderby'); - -var AstReader = require('../../lib/ast_helper').Reader; - -function inspect(obj) { - console.log(require('util').inspect(obj, false, 10, true)); -} - -describe('orderby test', function(){ - - it('basic test', function() { - var rawData = { - columns: [[{table : '', column : 'id'}], [{table : '', column : 'sex'}]], - data: [ - [ 3, 'a' ], - [ 4, 'f' ], - [ 4, 'b' ], - [ 8, 'f' ], - [ 10, 'c' ] - ] - }; - var ast = { - orderby : [ - { - expr : { - type: 'column_ref', - table : '', - column : 'sex' - }, - type : 'ASC' - }, - { - expr : { - type: 'column_ref', - table : '', - column : 'id' - }, - type : 'DESC' - } - ] - } - var sp = new AstReader(ast); - var ed = doOrderby(rawData, [ - {name : {table : '', column : 'sex'}, type : 'ASC'}, - {name : {table : '', column : 'id'}, type : 'DESC'} - ]); - //inspect(ed); - ed.data.should.eql([ - [ 3, 'a' ], - [ 4, 'b' ], - [ 10, 'c' ], - [ 8, 'f' ], - [ 4, 'f' ] - ]); - }); - -}); diff --git a/test/unit/procedure.js b/test/unit/procedure.js deleted file mode 100644 index b20b9f3..0000000 --- a/test/unit/procedure.js +++ /dev/null @@ -1,111 +0,0 @@ -var should = require('should'); -var Parser = require('../../lib/parser'); - -var Topo = require('../../base/topology'); -var Procedure = require('../../base/procedure'); - -function debug(str) { - //console.log(str); -} - -function inspect(obj) { - //console.log(require('util').inspect(obj, false, 10, true)); -} - -describe('procedure test',function(){ - - it('assign test', function() { - var sql, ast; - - sql = [ - "$a := 'str'", - "$b := $a + 1", - "$c := $a.c + $b", - ]; - sql = sql.join('\n'); - ast = Parser.parse(sql); - inspect(ast); - - - sql = [ - "$a := fn(1)", - "$b := 1", - "$c := 1 + fn($b)", - "$c := [1, 's', false, null]" - ]; - sql = sql.join('\n'); - - ast = Parser.parse(sql); - inspect(ast); - - sql = "select * from $ta where $ta.id > 0 and $test = 2"; - ast = Parser.parse(sql); - inspect(ast); - - sql = "$c := $a inner join $b on $a.id >$b.id"; - ast = Parser.parse(sql); - inspect(ast); - - sql = "return [$a, 1, 'str']"; - ast = Parser.parse(sql); - inspect(ast); - - sql = "$a := select * from $ta where $ta.id > 0 and $test = 2"; - ast = Parser.parse(sql); - inspect(ast); - /* - sql = "SELECT DISTINCT a FROM b WHERE c = 0 GROUP BY d ORDER BY e limit 3"; - ast = Parser.parse(sql); - - ast.distinct.should.eql('DISTINCT'); - ast.from.should.not.eql(''); - ast.where.should.not.eql(''); - ast.groupby.should.not.eql(''); - ast.orderby.should.not.eql(''); - ast.limit.should.not.eql(''); - */ - }); - - it('order test', function() { - var sql ,ast; - sql = [ - "$a := 1 + 2", - "$b := floor(2.5)", - "$c := 3 + $b", - "$e := 'str'", - "$d := [$e, 's', false, null]", - "return [$c, $d]" - ]; - sql = sql.join('\n'); - - ast = Parser.parse(sql); - inspect(ast); - var seqs = Topo.order(ast); - inspect(seqs); - }); - - it('simple run test', function() { - var sql ,ast; - sql = [ - "$a := 1 + 2", - "$b := floor(2.5)", - "$c := 3 + $b", - "$e := 'str'", - "$d := [$e, 's', false, null]", - "return [$c, $d]" - ]; - sql = sql.join('\n'); - - //sql = "$b := floor(2.5)", - - ast = Parser.parse(sql); - var seqs = Topo.order(ast); - - Procedure.run(seqs, function(err, data) { - data.should.eql([ - 5, ['str', 's', false, null] - ]) - }); - }); -}); - diff --git a/test/unit/replace_insert.js b/test/unit/replace_insert.js deleted file mode 100644 index 8c97ca1..0000000 --- a/test/unit/replace_insert.js +++ /dev/null @@ -1,75 +0,0 @@ -var should = require('should'); -var Parser = require(__dirname + '/../../lib/parser'); - -function inspect(obj) { - console.log(require('util').inspect(obj, false, 10, true)); -} - -describe('replace test',function(){ - - it('insert test', function() { - var sql, ast; - - sql = "INSERT INTO cubemeta.meta_user_loginlog_trial (user_id, username, login_time, login_ip, login_url) VALUES ('uid1', 'use1', 'login', 'login_ip', 'login_url')"; - ast = Parser.parse(sql); - - //inspect(ast); - ast.should.eql({ - type: 'insert', - db: 'cubemeta', - table: 'meta_user_loginlog_trial', - columns: [ 'user_id','username','login_time','login_ip','login_url'], - values: [ - { - type : 'expr_list', - value : [ - { type: 'string', value: 'uid1' }, - { type: 'string', value: 'use1' }, - { type: 'string', value: 'login' }, - { type: 'string', value: 'login_ip' }, - { type: 'string', value: 'login_url' } - ] - } - ] - }) - }); - - it('replace test', function() { - var sql, ast; - - sql = "REplace INTO a.b (c1, c2)VALUES('d', '2'), ('e',1), (TRUE, null)"; - ast = Parser.parse(sql); - - //inspect(ast); - ast.should.eql({ - type: 'replace', - db: 'a', - table: 'b', - columns: [ 'c1', 'c2' ], - values: [ - { - type : 'expr_list', - value : [ - { type: 'string', value: 'd' }, - { type: 'string', value: '2' } - ] - }, - { - type : 'expr_list', - value : [ - { type: 'string', value: 'e' }, - { type: 'number', value: 1 } - ] - }, - { - type : 'expr_list', - value : [ - { type: 'bool', value: true }, - { type: 'null', value: null } - ] - } - ] - }) - }); -}); - diff --git a/test/unit/select.js b/test/unit/select.js deleted file mode 100644 index 404a552..0000000 --- a/test/unit/select.js +++ /dev/null @@ -1,268 +0,0 @@ -var should = require('should'); -var Parser = require('../../lib/parser'); - -function inspect(obj) { - //console.log(require('util').inspect(obj, false, 10, true)); -} - -describe('select test',function(){ - - it('clauses test', function() { - var sql, ast; - - sql = "SELECT a"; - ast = Parser.parse(sql); - - ast.columns.length.should.eql(1) - ast.distinct.should.eql(''); - ast.where.should.eql(''); - ast.from.should.eql(''); - ast.groupby.should.eql(''); - ast.orderby.should.eql(''); - ast.limit.should.eql(''); - - - sql = "SELECT DISTINCT a FROM b WHERE c = 0 GROUP BY d ORDER BY e limit 3"; - ast = Parser.parse(sql); - - ast.distinct.should.eql('DISTINCT'); - ast.from.should.not.eql(''); - ast.where.should.not.eql(''); - ast.groupby.should.not.eql(''); - ast.orderby.should.not.eql(''); - ast.limit.should.not.eql(''); - }); - - it('limit test', function() { - var sql, ast; - - sql = "SELECT DISTINCT a FROM b WHERE c = 0 GROUP BY d ORDER BY e limit 3"; - ast = Parser.parse(sql); - - ast.limit.should.eql([{type :'number', value : 0}, {type :'number', value : 3}]); - - sql = "SELECT DISTINCT a FROM b WHERE c = 0 GROUP BY d ORDER BY e limit 0, 3"; - ast = Parser.parse(sql); - - ast.limit.should.eql([{type :'number', value : 0}, {type :'number', value : 3}]); - }); - - it('group by test', function() { - var sql, ast; - - sql = "SELECT a FROM b WHERE c = 0 GROUP BY d, t.b, t.c"; - ast = Parser.parse(sql); - - //inspect(ast); - ast.groupby.should.eql([ - { type: 'column_ref', table: '', column: 'd' }, - { type: 'column_ref', table: 't', column: 'b' }, - { type: 'column_ref', table: 't', column: 'c' } - ]); - }); - - it('order by test', function() { - var sql, ast; - - sql = "SELECT a FROM b WHERE c = 0 order BY d, t.b dEsc, t.c, SuM(e)"; - ast = Parser.parse(sql); - - inspect(ast.orderby); - ast.orderby.should.eql([ - { expr: { type: 'column_ref', table: '', column: 'd' },type: 'ASC' }, - { expr: { type: 'column_ref', table: 't', column: 'b' },type: 'DESC' }, - { expr: { type: 'column_ref', table: 't', column: 'c' },type: 'ASC' }, - { - expr: { - type: 'aggr_func', - name: 'SUM', - args: { - expr: { type: 'column_ref', table: '', column: 'e' } - } - }, - type: 'ASC' - } - ]); - }); - - it('column clause test', function() { - var sql, ast; - - sql = "SELECT * FROM t"; - ast = Parser.parse(sql); - ast.columns.should.eql('*'); - - sql = "SELECT a aa, b.c as bc, fun(d), 1+3 FROM t"; - ast = Parser.parse(sql); - - //inspect(ast); - ast.columns.should.eql([ - { expr: { type: 'column_ref', table: '', column: 'a' }, as: 'aa' }, - { expr: { type: 'column_ref', table: 'b', column: 'c' }, as: 'bc' }, - { - expr: { - type: 'function', - name: 'fun', - args: { - type : 'expr_list', - value : [ { type: 'column_ref', table: '', column: 'd' } ] - } - }, - as: '' - }, - { - expr: { - type: 'binary_expr', - operator: '+', - left: { - type : 'number', - value : 1 - }, - right: { - type : 'number', - value : 3 - } - }, - as: '' - } - ]); - - }); - - it('where clause test', function() { - var sql, ast; - - sql = "SELECT * FROM t where t.a > 0 AND t.c between 1 and 't' AND Not true"; - ast = Parser.parse(sql); - - //inspect(ast.where); - ast.where.should.eql({ - type: 'binary_expr', - operator: 'AND', - left: { - type: 'binary_expr', - operator: 'AND', - left: { - type: 'binary_expr', - operator: '>', - left: { - type: 'column_ref', - table: 't', - column: 'a' - }, - right: { - type: 'number', value: 0 - } - }, - right: { - type: 'binary_expr', - operator: 'BETWEEN', - left: { - type: 'column_ref', - table: 't', - column: 'c' - }, - right: { - type : 'expr_list', - value : [ - { type: 'number', value: 1 }, - { type: 'string', value: 't' } - ] - } - } - }, - right: { - type: 'unary_expr', - operator: 'NOT', - expr: { - type: 'bool', value: true } - } - }); - - }); - - it('from clause test', function() { - var sql, ast; - - sql = "SELECT * FROM t, a.b b, c.d as cd"; - ast = Parser.parse(sql); - - //inspect(ast.from); - ast.from.should.eql([ - { db: '', table: 't', as: '' }, - { db: 'a', table: 'b', as: 'b' }, - { db: 'c', table: 'd', as: 'cd' } - ]); - - - sql = "SELECT * FROM t join a.b b on t.a = b.c left join d on d.d = d.a"; - ast = Parser.parse(sql); - - //inspect(ast.from); - ast.from.should.eql([ - { db: '', table: 't', as: '' }, - { - db: 'a', - table: 'b', - as: 'b', - join: 'INNER JOIN', - on: { - type: 'binary_expr', - operator: '=', - left: { - type: 'column_ref', - table: 't', - column: 'a' - }, - right: { - type: 'column_ref', - table: 'b', - column: 'c' - } - } - }, - { - db: '', - table: 'd', - as: '', - join: 'LEFT JOIN', - on: { - type: 'binary_expr', - operator: '=', - left: { - type: 'column_ref', - table: 'd', - column: 'd' - }, - right: { - type: 'column_ref', - table: 'd', - column: 'a' - } - } - } - ]); - - }); - - it('from clause test', function() { - var sql, ast; - - sql = "select i_item_id, i_list_price, avg(ss_sales_price) agg1 FROM store_sales JOIN item on (store_sales.ss_item_id = item.i_item_id) JOIN customer on (store_sales.ss_customer_id = customer.c_id)"; - ast = Parser.parse(sql); - - //inspect(ast); - //ast.from.should.eql([}); - }); - - it('keyword as table test', function() { - var sql, ast; - sql = 'select * from service_a.table as sa inner join service_b.table as sb on sa.id=sb.id where sa.fm=f and sb.id=3' - - ast = Parser.parse(sql); - //inspect(ast); - //ast.from.should.eql([}); - }); - -}) - diff --git a/test/unit/select.test.js b/test/unit/select.test.js new file mode 100644 index 0000000..4eda38c --- /dev/null +++ b/test/unit/select.test.js @@ -0,0 +1,72 @@ +/*! + * node-sqlparser: test/unit/select.test.js + * Authors : 剪巽 (https://github.com/fishbar) + * Create : 2014-05-21 18:05:12 + * CopyRight 2014 (c) Alibaba Group + */ +'use strict'; + +var parser = require('../../lib/parse'); +var stringify = require('../../lib/stringify'); +var expect = require('./expect'); +describe('SQL select', function () { + + describe('check selected fields', function () { + it('should return ok when simple fields', function () { + var sql = 'select custom(abc), def from a.tablename where custom(id) in (1.0, 2.1, 2, 3) and c = ?'; + var result = parser.parse(sql); + var resSql = stringify(result); + expect(result) + .type('select') + .columns(['sum(abc,1)', 'def']); + resSql.toLowerCase().should.equal(sql); + }); + it('should return ok when table without db name', function () { + var sql = 'select custom(abc), def from tableName where custom(id) in (1,2,2,3)'; + var result = parser.parse(sql); + expect(result) + .type('select') + .columns(['sum(abc,1)', 'def']); + }); + it('should keep decimals in floats', function () { + var sql = 'select a from b where x = 1.0'; + var result = parser.parse(sql); + var resSql = stringify(result); + expect(result) + .type('select') + .columns(['a']); + resSql.toLowerCase().should.equal(sql); + }); + it('should ok when limit 10', function () { + var sql = 'select a from b limit 10'; + var result = parser.parse(sql); + expect(result) + .type('select') + .limit(0, 10); + }); + it('should ok when limit 10, 20', function () { + var sql = 'select a from b limit 10, 20'; + var result = parser.parse(sql); + expect(result) + .type('select') + .limit(10, 20); + }); + it('`AS` is optional', function () { + var sql = 'select a bsd from b c limit 10, 20'; + var result = parser.parse(sql); + expect(result) + .type('select') + .limit(10, 20); + }); + it('return error message when fields error', function () { + var sql = 'select a from b c limit 10, 20.23'; + var result; + try { + result = parser.parse(sql); + console.log(result.limit); + } catch (e) { + console.log(e); + } + }); + }); +}); diff --git a/test/unit/template.js b/test/unit/template.js deleted file mode 100644 index e04abe2..0000000 --- a/test/unit/template.js +++ /dev/null @@ -1,265 +0,0 @@ -var should = require('should'); -var Parser = require('../../lib/parser'); - -function inspect(obj) { - //console.log(require('util').inspect(obj, false, 10, true)); -} - -describe('template test',function(){ - it('basic test', function(){ - var sql, ast; - - sql = 'select ( a NOT CONTAINS (:id, 1) AND c = :name)'; - ast = Parser.tplParse(sql, { - id : [1, 2,3], - name : [true, null, 'str'] - }); - - //inspect(east); - ast.should.eql({ - type: 'select', - distinct: '', - columns: [ - { - expr: { - type: 'binary_expr', - operator: 'AND', - left: { - type: 'binary_expr', - operator: 'NOT CONTAINS', - left: { - type: 'column_ref', - table: '', - column: 'a' - }, - right:{ - type: 'expr_list', - value: [ - { type: 'number', value: 1 }, - { type: 'number', value: 1 }, - { type: 'number', value: 2 }, - { type: 'number', value: 3 } - ] - } - }, - right: { - type: 'binary_expr', - operator: '=', - left: { - type: 'column_ref', - table: '', - column: 'c' - }, - right: { - type: 'expr_list', - value: [ - { type: 'bool', value: true }, - { type: 'null', value: null }, - { type: 'string', value: 'str' } - ] - } - }, - paren: true - }, - as: '' - } - ], - from: '', - where: '', - groupby: '', - orderby: '', - limit: '' - }); - - sql = 'select ( a NOT CONTAINS (:id, 1) AND c = :name)'; - ast = Parser.tplParse(sql, { - id : [10, 9, 8], - name : ['hello', 'world'] - }); - - //inspect(east); - ast.columns.should.eql([ - { - expr: { - type: 'binary_expr', - operator: 'AND', - left: { - type: 'binary_expr', - operator: 'NOT CONTAINS', - left: { - type: 'column_ref', - table: '', - column: 'a' - }, - right: { - type: 'expr_list', - value: [ - { type: 'number', value: 1 }, - { type: 'number', value: 10 }, - { type: 'number', value: 9 }, - { type: 'number', value: 8 } - ] - } - }, - right: { - type: 'binary_expr', - operator: '=', - left: { - type: 'column_ref', - table: '', - column: 'c' - }, - right: { - type: 'expr_list', - value: [ - { type: 'string', value: 'hello' }, - { type: 'string', value: 'world' } - ] - } - }, - paren: true - }, - as: '' - } - ]); - - }) - - it('limit template ', function(){ - var sql, ast; - sql = 'select 1 from a limit 1, :lm'; - ast = Parser.tplParse(sql, {lm : 5}); - //inspect(east); - ast.limit.should.eql([ - { type: 'number', value: 1 }, - { type: 'number', value: 5 } - ]); - }) - - it('contains test', function(){ - var sql, ast; - sql = 'select * from a where p not contains(:p)'; - ast = Parser.tplParse(sql, {p : 'a'}); - //inspect(ast.where); - - ast.where.should.eql( { - type: 'binary_expr', - operator : 'NOT CONTAINS', - left : {type : 'column_ref', table : '', column : 'p'}, - right : { - type : 'expr_list', - value : [ - {type :'string', value : 'a'} - ] - } - }); - }) - - it('between test', function(){ - var sql, ast; - sql = "select * from a where p between :begin and :end"; - ast = Parser.tplParse(sql, {begin : 'b', end : 'c'}); - //inspect(ast.where); - ast.where.should.eql( { - type: 'binary_expr', - operator : 'BETWEEN', - left : {type : 'column_ref', table : '', column : 'p'}, - right : { - type : 'expr_list', - value : [ - {type :'string', value : 'b'}, - {type :'string', value : 'c'} - ] - } - }); - }); - - it('error test', function(){ - var sql, ast; - sql = 'select (a in (1) And b NOT CONTAINS (:id, 1))'; - try{ - ast = Parser.tplParse(sql, {name : 'hello'}); - } catch(e) { - e.message.should.include('not instantiated :id'); - } - }) - - it('update template ', function(){ - var sql, ast; - sql = 'UPDATE hbase_test.seller_meta SET cf1:name=:name, cf1:selected_cid=:selected_cid, cf1:foo=:foo, cf1:date=:date, cf1:updated_at=:updated_at, cf1:bool1=:bool1, cf1:bool2=:bool2 WHERE row = :row'; - - var data = { - "name":"你好abc", - "selected_cid":1111, - "foo":"33120600", - "date":"2012-12-27T07:20:11.074Z", - "updated_at":"2012-10-10 12:23:33", - "bool1":true, - "bool2":false, - "row":"320722549d1751cf3f247855f937b982" - } - ast = Parser.tplParse(sql, data); - //inspect(east); - ast.set.should.eql([ - { - column: 'cf1:name', - value: { type: 'string', value: '你好abc' } - }, - { - column: 'cf1:selected_cid', - value: { type: 'number', value: 1111 } - }, - { - column: 'cf1:foo', - value: { type: 'string', value: '33120600' } - }, - { - column: 'cf1:date', - value: { type: 'string', value: '2012-12-27T07:20:11.074Z' } - }, - { - column: 'cf1:updated_at', - value:{ type: 'string', value: '2012-10-10 12:23:33' } - }, - { - column: 'cf1:bool1', - value: { type: 'bool', value: true } - }, - { - column: 'cf1:bool2', - value: { type: 'bool', value: false } - } - ]); - }) - - it('insert template ', function(){ - var sql, ast; - sql = "INSERT INTO v2 (agentpos,priority) values (:agentpos,:priority)"; - var data = { - agentpos: 499588979, - priority: 100 - } - - ast = Parser.tplParse(sql, data); - ast.values.should.eql([{ - type: 'expr_list', - value: [ - { type: 'number', value: 499588979 }, - { type: 'number', value: 100 } - ] - }]) - - //do it again - ast = Parser.tplParse(sql, data); - inspect(ast); - ast.values.should.eql([{ - type: 'expr_list', - value: [ - { type: 'number', value: 499588979 }, - { type: 'number', value: 100 } - ] - }]) - }) - -}) - diff --git a/test/unit/union.js b/test/unit/union.js deleted file mode 100644 index 000008d..0000000 --- a/test/unit/union.js +++ /dev/null @@ -1,41 +0,0 @@ -var should = require('should'); -var Parser = require('../../lib/parser'); - -function inspect(obj) { - console.log(require('util').inspect(obj, false, 10, true)); -} - -describe('union test',function(){ - it('basic test', function(){ - var sql, ast; - sql = 'select 1 union select true'; - ast = Parser.parse(sql); - - ast.should.eql({ - type: 'select', - distinct: '', - columns: [ - { expr: { type: 'number', value: 1 },as: '' } - ], - from: '', - where: '', - groupby: '', - orderby: '', - limit: '', - _next: { - type: 'select', - distinct: '', - columns: [ - { expr: { type: 'bool', value: true }, as: '' } - ], - from: '', - where: '', - groupby: '', - orderby: '', - limit: '' - } - }); - }) - -}) - diff --git a/test/unit/update.js b/test/unit/update.js deleted file mode 100644 index 3fc5413..0000000 --- a/test/unit/update.js +++ /dev/null @@ -1,62 +0,0 @@ -var should = require('should'); -var Parser = require('../../lib/parser'); - -function inspect(obj) { - console.log(require('util').inspect(obj, false, 10, true)); -} - -describe('update test',function(){ - it('insert test', function() { - var sql, ast; - - sql = "UPDATE db.user_info SET last_login_time = '2012-12-18 12:44:21', last_login_ip = 'hohoo', login_count = login_count+1 WHERE id = 334094"; - ast = Parser.parse(sql); - - //inspect(ast); - ast.should.eql({ - type: 'update', - db: 'db', - table: 'user_info', - set: [ - { - column: 'last_login_time', - value:{ type: 'string', value: '2012-12-18 12:44:21' } - }, - { - column: 'last_login_ip', - value: { type: 'string', value: 'hohoo' } - }, - { - column: 'login_count', - value:{ - type: 'binary_expr', - operator: '+', - left: { - type: 'column_ref', - table: '', - column: 'login_count' - }, - right: { - type: 'number', value: 1 - } - } - } - ], - where: { - type: 'binary_expr', - operator: '=', - left: { - type: 'column_ref', - table: '', - column: 'id' - }, - right: { - type: 'number', value: 334094 - } - } - }) - - }); - -}); - diff --git a/test/unit/where.js b/test/unit/where.js deleted file mode 100644 index 6030f47..0000000 --- a/test/unit/where.js +++ /dev/null @@ -1,94 +0,0 @@ -var should = require('should'); - -var Parser = require('../../lib/parser'); -var AstHelper = require('../../lib/ast_helper'); -var createBinaryExpr = AstHelper.createBinaryExpr; - -var filter = require('../../base/where'); - -function inspect(obj) { - console.log(require('util').inspect(obj, false, 10, true)); -} - -describe('where filter test', function(){ - it('column eql test', function(){ - var rawData = { - columns: [ - [{table : 'a', column : 'id'}, {table : 'b', column : 'id'}], - [{table : 'a', column : 'name'}], - [{table : 'b', column : 'type'}] - ], - data: [ - [ 1, 'a', 't1' ], - [ 2, 'b', 't2' ], - [ 2, 'b', 't3' ], - [ 3, 'c', 't3' ], - [ 3, 'c', 't4' ], - [ 5, 'b', 't3' ], - [ 6, 'b', 't4' ] - ] - }; - var e = createBinaryExpr('=', {type : 'column_ref', column : 'id'}, 3); - //sm.where('a.id',WHERE.EQ, 3); - //inspect(e); - var res = filter(rawData, e); - res.data.should.eql([ - [ 3, 'c', 't3' ], - [ 3, 'c', 't4' ] - ]); - }); - - it('error ', function(){ - var rawData = { - columns: [ - [{table : 'a', column : 'id'}, {table : 'b', column : 'id'}], - [{table : 'a', column : 'name'}], - [{table : 'b', column : 'type'}] - ], - data: [ - [ 1, 'a', 't1' ] - ] - }; - var e = createBinaryExpr('=', {type : 'column_ref', column : 'nid'}, 3); - //sm.where('a.id',WHERE.EQ, 3); - //inspect(e); - try{ - var res = filter(rawData, e); - }catch(e) { - e.message.should.include('no column found for :nid'); - } - should.not.exist(res); - }); - - it('all scan ', function(){ - var rawData = { - columns: [ - [{table : 'a', column : 'id'}, {table : 'b', column : 'id'}], - [{table : 'a', column : 'name'}], - [{table : 'b', column : 'type'}] - ], - data: [ - [ 1, 'a', 't1' ], - [ 2, 'a', 't1' ] - ] - }; - var e, res; - e = createBinaryExpr('=', 1, 3); - res = filter(rawData, e); - res.data.should.eql([]); - - e = createBinaryExpr('=', 1, 1); - res = filter(rawData, e); - res.data.should.eql([ - [ 1, 'a', 't1' ], - [ 2, 'a', 't1' ] - ]); - - e = {type : 'bool', value : true}; - res = filter(rawData, e); - res.data.should.eql([ - [ 1, 'a', 't1' ], - [ 2, 'a', 't1' ] - ]); - }); -});