diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..7a52716 --- /dev/null +++ b/.babelrc @@ -0,0 +1,11 @@ +{ + "presets": [ + [ + "@babel/env", + { + "loose": true, + "modules": false + } + ] + ] +} \ No newline at end of file diff --git a/.github/dependabot.yml.bak b/.github/dependabot.yml.bak new file mode 100644 index 0000000..9dcd158 --- /dev/null +++ b/.github/dependabot.yml.bak @@ -0,0 +1,8 @@ +version: 2 +updates: +- package-ecosystem: npm + directory: "/" + schedule: + interval: daily + time: "04:00" + open-pull-requests-limit: 10 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..997f613 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,16 @@ +name: CI + +on: [push, pull_request] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + - name: build + run: | + npm install + npm run compile + npm run test diff --git a/.gitignore b/.gitignore index 2b747fa..3ac8dd7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ node_modules .DS_Store *.swp - +*.iml +.idea +yarn.lock diff --git a/Cakefile b/Cakefile deleted file mode 100644 index 1030a8b..0000000 --- a/Cakefile +++ /dev/null @@ -1,53 +0,0 @@ -{spawn, exec} = require 'child_process' -fs = require('fs') -require('coffee-script/register') - -run = (args, cb) -> - proc = spawn './node_modules/.bin/coffee', args - proc.stderr.on 'data', (buffer) -> console.log buffer.toString() - proc.on 'exit', (status) -> - process.exit(1) if status != 0 - cb() if typeof cb is 'function' - -build = (cb) -> - files = fs.readdirSync 'src' - files = ('src/' + file for file in files when file.match(/\.coffee$/)) - run ['-c', '-o', 'lib'].concat(files), cb - -task 'build', 'Run full build', -> - invoke 'build:compile' - invoke 'build:parser' - setTimeout (-> invoke 'build:browser'), 100 - -task 'build:compile', 'Compile all coffee files to js', - build - -task 'build:parser', 'rebuild the Jison parser', -> - parser = require('./src/grammar').parser - fs.writeFileSync 'lib/compiled_parser.js', parser.generate() - -task 'build:browser', 'Build a single JS file suitable for use in the browser', -> - code = '' - for name in ['lexer', 'compiled_parser', 'nodes', 'parser', 'sql_parser'] - code += """ - require['./#{name}'] = new function() { - var exports = this; - #{fs.readFileSync "lib/#{name}.js"} - }; - """ - code = """ - (function(root) { - var SQLParser = function() { - function require(path){ return require[path]; } - #{code} - return require['./sql_parser'] - }(); - - if(typeof define === 'function' && define.amd) { - define(function() { return SQLParser }); - } else { root.SQLParser = SQLParser } - }(this)); - """ - fs.writeFileSync './browser/sql-parser.js', code - - diff --git a/LICENSE b/LICENSE index 6953b00..688be38 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,5 @@ Copyright (c) 2012 Andrew Kent +Copyright (c) 2016-2019 Damien "Mistic" Sorel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/README.md b/README.md index a101bbb..839fe42 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,11 @@ SQL Parser ========== +[![NPM version](https://img.shields.io/npm/v/sql-parser-mistic.svg?style=flat-square)](https://www.npmjs.com/package/sql-parser-mistic) +[![jsDelivr CDN](https://data.jsdelivr.com/v1/package/npm/sql-parser-mistic/badge)](https://www.jsdelivr.com/package/npm/sql-parser-mistic) +[![GZIP size](https://img.shields.io/bundlephobia/minzip/sql-parser-mistic?label=gzip%20size)](https://bundlephobia.com/result?p=sql-parser-mistic) +[![Build Status](https://github.com/mistic100/sql-parser/workflows/CI/badge.svg)](https://github.com/mistic100/sql-parser/actions) + SQL Parser is a lexer, grammar and parser for SQL written in JS. Currently it is only capable of parsing fairly basic SELECT queries but full SQL support will hopefully come in time. See the specs for examples of currently supported queries. @@ -9,12 +14,12 @@ Installation The package is distributed on NPM and can be installed with... - npm install sql-parser + npm install sql-parser-mistic To build from source you'll need to run the following from the root of the project... npm install - cake build + npm run compile Tests are written using Mocha and can be run with... @@ -47,7 +52,7 @@ Parser The parser only currently supports SELECT queries but is able to produce a Select object with properties for where, group, order, limit. See lib/nodes.coffee for more info of the returned object structure. Calling .toString() on a Select object should give you back a well formatted version of the original SQL input. - tokens = lexer.tokenize('select * from my_table where foo = 'bar') + tokens = lexer.tokenize("select * from my_table where foo = 'bar'") parser.parse(tokens).toString() SELECT * @@ -55,13 +60,7 @@ The parser only currently supports SELECT queries but is able to produce a Selec WHERE `foo` = 'bar' -Credits -------- - -A lot of the boilerplate and compilation code in this project is borrowed from the CoffeeScript project as it was the best example of a project using JISON that I could find. Thanks. - - Contributions ------------- -Contributions in the form of pull requests that add syntax support are very welcome but should be supported by both Lexer and Parser level tests. \ No newline at end of file +Contributions in the form of pull requests that add syntax support are very welcome but should be supported by both Lexer and Parser level tests. diff --git a/browser/example.html b/browser/example.html index e7d513c..55cddab 100644 --- a/browser/example.html +++ b/browser/example.html @@ -1,8 +1,37 @@ - - + + +

SQLParser

+ +

Input

+ + + +

Tokens

+

+
+

Parsed

+

+
+

Output

+

+
+
+
+
+
+
 
\ No newline at end of file
diff --git a/browser/sql-parser.js b/browser/sql-parser.js
index 4ebe726..4603b4b 100644
--- a/browser/sql-parser.js
+++ b/browser/sql-parser.js
@@ -1,1270 +1,3143 @@
-(function(root) {
-  var SQLParser = function() {
-    function require(path){ return require[path]; }
-    require['./lexer'] = new function() {
-  var exports = this;
-  // Generated by CoffeeScript 1.8.0
-(function() {
-  var Lexer;
-
-  Lexer = (function() {
-    var BOOLEAN, DBLSTRING, LITERAL, MATH, MATH_MULTI, NUMBER, PARAMETER, SEPARATOR, SQL_BETWEENS, SQL_CONDITIONALS, SQL_FUNCTIONS, SQL_OPERATORS, SQL_SORT_ORDERS, STAR, STRING, SUB_SELECT_OP, SUB_SELECT_UNARY_OP, WHITESPACE;
-
-    function Lexer(sql, opts) {
-      var bytesConsumed, i;
-      if (opts == null) {
-        opts = {};
-      }
-      this.sql = sql;
-      this.preserveWhitespace = opts.preserveWhitespace || false;
-      this.tokens = [];
-      this.currentLine = 1;
-      i = 0;
-      while (this.chunk = sql.slice(i)) {
-        bytesConsumed = this.keywordToken() || this.starToken() || this.booleanToken() || this.functionToken() || this.windowExtension() || this.sortOrderToken() || this.seperatorToken() || this.operatorToken() || this.mathToken() || this.dotToken() || this.conditionalToken() || this.betweenToken() || this.subSelectOpToken() || this.subSelectUnaryOpToken() || this.numberToken() || this.stringToken() || this.parameterToken() || this.parensToken() || this.whitespaceToken() || this.literalToken();
-        if (bytesConsumed < 1) {
-          throw new Error("NOTHING CONSUMED: Stopped at - '" + (this.chunk.slice(0, 30)) + "'");
-        }
-        i += bytesConsumed;
-      }
-      this.token('EOF', '');
-      this.postProcess();
-    }
-
-    Lexer.prototype.postProcess = function() {
-      var i, next_token, token, _i, _len, _ref, _results;
-      _ref = this.tokens;
-      _results = [];
-      for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
-        token = _ref[i];
-        if (token[0] === 'STAR') {
-          next_token = this.tokens[i + 1];
-          if (!(next_token[0] === 'SEPARATOR' || next_token[0] === 'FROM')) {
-            _results.push(token[0] = 'MATH_MULTI');
-          } else {
-            _results.push(void 0);
-          }
-        } else {
-          _results.push(void 0);
-        }
-      }
-      return _results;
-    };
-
-    Lexer.prototype.token = function(name, value) {
-      return this.tokens.push([name, value, this.currentLine]);
-    };
-
-    Lexer.prototype.tokenizeFromRegex = function(name, regex, part, lengthPart, output) {
-      var match, partMatch;
-      if (part == null) {
-        part = 0;
-      }
-      if (lengthPart == null) {
-        lengthPart = part;
-      }
-      if (output == null) {
-        output = true;
-      }
-      if (!(match = regex.exec(this.chunk))) {
-        return 0;
-      }
-      partMatch = match[part];
-      if (output) {
-        this.token(name, partMatch);
-      }
-      return match[lengthPart].length;
-    };
-
-    Lexer.prototype.tokenizeFromWord = function(name, word) {
-      var match, matcher;
-      if (word == null) {
-        word = name;
-      }
-      word = this.regexEscape(word);
-      matcher = /^\w+$/.test(word) ? new RegExp("^(" + word + ")\\b", 'ig') : new RegExp("^(" + word + ")", 'ig');
-      match = matcher.exec(this.chunk);
-      if (!match) {
-        return 0;
-      }
-      this.token(name, match[1]);
-      return match[1].length;
-    };
-
-    Lexer.prototype.tokenizeFromList = function(name, list) {
-      var entry, ret, _i, _len;
-      ret = 0;
-      for (_i = 0, _len = list.length; _i < _len; _i++) {
-        entry = list[_i];
-        ret = this.tokenizeFromWord(name, entry);
-        if (ret > 0) {
-          break;
-        }
-      }
-      return ret;
-    };
-
-    Lexer.prototype.keywordToken = function() {
-      return this.tokenizeFromWord('SELECT') || this.tokenizeFromWord('DISTINCT') || this.tokenizeFromWord('FROM') || this.tokenizeFromWord('WHERE') || this.tokenizeFromWord('GROUP') || this.tokenizeFromWord('ORDER') || this.tokenizeFromWord('BY') || this.tokenizeFromWord('HAVING') || this.tokenizeFromWord('LIMIT') || this.tokenizeFromWord('JOIN') || this.tokenizeFromWord('LEFT') || this.tokenizeFromWord('RIGHT') || this.tokenizeFromWord('INNER') || this.tokenizeFromWord('OUTER') || this.tokenizeFromWord('ON') || this.tokenizeFromWord('AS') || this.tokenizeFromWord('UNION') || this.tokenizeFromWord('ALL') || this.tokenizeFromWord('LIMIT') || this.tokenizeFromWord('OFFSET') || this.tokenizeFromWord('FETCH') || this.tokenizeFromWord('ROW') || this.tokenizeFromWord('ROWS') || this.tokenizeFromWord('ONLY') || this.tokenizeFromWord('NEXT') || this.tokenizeFromWord('FIRST');
-    };
-
-    Lexer.prototype.dotToken = function() {
-      return this.tokenizeFromWord('DOT', '.');
-    };
-
-    Lexer.prototype.operatorToken = function() {
-      return this.tokenizeFromList('OPERATOR', SQL_OPERATORS);
-    };
-
-    Lexer.prototype.mathToken = function() {
-      return this.tokenizeFromList('MATH', MATH) || this.tokenizeFromList('MATH_MULTI', MATH_MULTI);
-    };
-
-    Lexer.prototype.conditionalToken = function() {
-      return this.tokenizeFromList('CONDITIONAL', SQL_CONDITIONALS);
-    };
-
-    Lexer.prototype.betweenToken = function() {
-      return this.tokenizeFromList('BETWEEN', SQL_BETWEENS);
-    };
-
-    Lexer.prototype.subSelectOpToken = function() {
-      return this.tokenizeFromList('SUB_SELECT_OP', SUB_SELECT_OP);
-    };
-
-    Lexer.prototype.subSelectUnaryOpToken = function() {
-      return this.tokenizeFromList('SUB_SELECT_UNARY_OP', SUB_SELECT_UNARY_OP);
-    };
-
-    Lexer.prototype.functionToken = function() {
-      return this.tokenizeFromList('FUNCTION', SQL_FUNCTIONS);
-    };
-
-    Lexer.prototype.sortOrderToken = function() {
-      return this.tokenizeFromList('DIRECTION', SQL_SORT_ORDERS);
-    };
-
-    Lexer.prototype.booleanToken = function() {
-      return this.tokenizeFromList('BOOLEAN', BOOLEAN);
-    };
-
-    Lexer.prototype.starToken = function() {
-      return this.tokenizeFromRegex('STAR', STAR);
-    };
-
-    Lexer.prototype.seperatorToken = function() {
-      return this.tokenizeFromRegex('SEPARATOR', SEPARATOR);
-    };
-
-    Lexer.prototype.literalToken = function() {
-      return this.tokenizeFromRegex('LITERAL', LITERAL, 1, 0);
-    };
-
-    Lexer.prototype.numberToken = function() {
-      return this.tokenizeFromRegex('NUMBER', NUMBER);
-    };
-
-    Lexer.prototype.parameterToken = function() {
-      return this.tokenizeFromRegex('PARAMETER', PARAMETER);
-    };
-
-    Lexer.prototype.stringToken = function() {
-      return this.tokenizeFromRegex('STRING', STRING, 1, 0) || this.tokenizeFromRegex('DBLSTRING', DBLSTRING, 1, 0);
-    };
-
-    Lexer.prototype.parensToken = function() {
-      return this.tokenizeFromRegex('LEFT_PAREN', /^\(/) || this.tokenizeFromRegex('RIGHT_PAREN', /^\)/);
-    };
-
-    Lexer.prototype.windowExtension = function() {
-      var match;
-      match = /^\.(win):(length|time)/i.exec(this.chunk);
-      if (!match) {
-        return 0;
-      }
-      this.token('WINDOW', match[1]);
-      this.token('WINDOW_FUNCTION', match[2]);
-      return match[0].length;
-    };
-
-    Lexer.prototype.whitespaceToken = function() {
-      var match, newlines, partMatch;
-      if (!(match = WHITESPACE.exec(this.chunk))) {
-        return 0;
-      }
-      partMatch = match[0];
-      newlines = partMatch.replace(/[^\n]/, '').length;
-      this.currentLine += newlines;
-      if (this.preserveWhitespace) {
-        this.token(name, partMatch);
-      }
-      return partMatch.length;
-    };
-
-    Lexer.prototype.regexEscape = function(str) {
-      return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
-    };
-
-    SQL_FUNCTIONS = ['AVG', 'COUNT', 'MIN', 'MAX', 'SUM'];
+/*!
+ * SQLParser (v1.3.0)
+ * @copyright 2012-2015 Andy Kent 
+ * @copyright 2015-2019 Damien "Mistic" Sorel 
+ * @licence MIT
+ */
+(function (global, factory) {
+	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+	typeof define === 'function' && define.amd ? define(['exports'], factory) :
+	(global = global || self, factory(global.SQLParser = {}));
+}(this, (function (exports) { 'use strict';
+
+	function createCommonjsModule(fn, module) {
+		return module = { exports: {} }, fn(module, module.exports), module.exports;
+	}
+
+	var SQL_FUNCTIONS = ['AVG', 'COUNT', 'MIN', 'MAX', 'SUM'];
+	var SQL_SORT_ORDERS = ['ASC', 'DESC'];
+	var SQL_OPERATORS = ['=', '!=', '>=', '>', '<=', '<>', '<', 'LIKE', 'NOT LIKE', 'ILIKE', 'NOT ILIKE', 'IS NOT', 'IS', 'REGEXP', 'NOT REGEXP'];
+	var SUB_SELECT_OP = ['IN', 'NOT IN', 'ANY', 'ALL', 'SOME'];
+	var SUB_SELECT_UNARY_OP = ['EXISTS'];
+	var SQL_CONDITIONALS = ['AND', 'OR'];
+	var SQL_BETWEENS = ['BETWEEN', 'NOT BETWEEN'];
+	var BOOLEAN = ['TRUE', 'FALSE', 'NULL'];
+	var MATH = ['+', '-', '||', '&&'];
+	var MATH_MULTI = ['/', '*'];
+	var STAR = /^\*/;
+	var SEPARATOR = /^,/;
+	var WHITESPACE = /^[ \n\r]+/;
+	var LITERAL = /^`?([a-z_][a-z0-9_]{0,}(\:(number|float|string|date|boolean))?)`?/i;
+	var PARAMETER = /^\$([a-z0-9_]+(\:(number|float|string|date|boolean))?)/;
+	var NUMBER = /^[+-]?[0-9]+(\.[0-9]+)?/;
+	var STRING = /^'((?:[^\\']+?|\\.|'')*)'(?!')/;
+	var DBLSTRING = /^"([^\\"]*(?:\\.[^\\"]*)*)"/;
+
+	var Lexer =
+	/*#__PURE__*/
+	function () {
+	  function Lexer(sql, opts) {
+	    if (opts === void 0) {
+	      opts = {};
+	    }
+
+	    this.sql = sql;
+	    this.preserveWhitespace = opts.preserveWhitespace || false;
+	    this.tokens = [];
+	    this.currentLine = 1;
+	    this.currentOffset = 0;
+	    var i = 0;
+
+	    while (!!(this.chunk = sql.slice(i))) {
+	      var bytesConsumed = this.keywordToken() || this.starToken() || this.booleanToken() || this.functionToken() || this.windowExtension() || this.sortOrderToken() || this.seperatorToken() || this.operatorToken() || this.numberToken() || this.mathToken() || this.dotToken() || this.conditionalToken() || this.betweenToken() || this.subSelectOpToken() || this.subSelectUnaryOpToken() || this.stringToken() || this.parameterToken() || this.parensToken() || this.whitespaceToken() || this.literalToken();
+
+	      if (bytesConsumed < 1) {
+	        throw new Error("NOTHING CONSUMED: Stopped at - '" + this.chunk.slice(0, 30) + "'");
+	      }
+
+	      i += bytesConsumed;
+	      this.currentOffset += bytesConsumed;
+	    }
+
+	    this.token('EOF', '');
+	    this.postProcess();
+	  }
+
+	  var _proto = Lexer.prototype;
+
+	  _proto.postProcess = function postProcess() {
+	    var results = [];
+
+	    for (var _i = 0, j = 0, len = this.tokens.length; j < len; _i = ++j) {
+	      var token = this.tokens[_i];
+
+	      if (token[0] === 'STAR') {
+	        var next_token = this.tokens[_i + 1];
+
+	        if (!(next_token[0] === 'SEPARATOR' || next_token[0] === 'FROM')) {
+	          results.push(token[0] = 'MATH_MULTI');
+	        } else {
+	          results.push(void 0);
+	        }
+	      } else {
+	        results.push(void 0);
+	      }
+	    }
+
+	    return results;
+	  };
+
+	  _proto.token = function token(name, value) {
+	    return this.tokens.push([name, value, this.currentLine, this.currentOffset]);
+	  };
+
+	  _proto.tokenizeFromStringRegex = function tokenizeFromStringRegex(name, regex, part, lengthPart, output) {
+	    if (part === void 0) {
+	      part = 0;
+	    }
+
+	    if (lengthPart === void 0) {
+	      lengthPart = part;
+	    }
+
+	    if (output === void 0) {
+	      output = true;
+	    }
+
+	    var match = regex.exec(this.chunk);
+
+	    if (!match) {
+	      return 0;
+	    }
+
+	    var partMatch = match[part].replace(/''/g, '\'');
+
+	    if (output) {
+	      this.token(name, partMatch);
+	    }
+
+	    return match[lengthPart].length;
+	  };
+
+	  _proto.tokenizeFromRegex = function tokenizeFromRegex(name, regex, part, lengthPart, output) {
+	    if (part === void 0) {
+	      part = 0;
+	    }
+
+	    if (lengthPart === void 0) {
+	      lengthPart = part;
+	    }
 
-    SQL_SORT_ORDERS = ['ASC', 'DESC'];
-
-    SQL_OPERATORS = ['=', '!=', '>=', '>', '<=', '<>', '<', 'LIKE', 'IS NOT', 'IS'];
-
-    SUB_SELECT_OP = ['IN', 'NOT IN', 'ANY', 'ALL', 'SOME'];
-
-    SUB_SELECT_UNARY_OP = ['EXISTS'];
+	    if (output === void 0) {
+	      output = true;
+	    }
 
-    SQL_CONDITIONALS = ['AND', 'OR'];
-
-    SQL_BETWEENS = ['BETWEEN', 'NOT BETWEEN'];
-
-    BOOLEAN = ['TRUE', 'FALSE', 'NULL'];
-
-    MATH = ['+', '-'];
-
-    MATH_MULTI = ['/', '*'];
-
-    STAR = /^\*/;
-
-    SEPARATOR = /^,/;
-
-    WHITESPACE = /^[ \n\r]+/;
-
-    LITERAL = /^`?([a-z_][a-z0-9_]{0,})`?/i;
-
-    PARAMETER = /^\$[0-9]+/;
-
-    NUMBER = /^[0-9]+(\.[0-9]+)?/;
-
-    STRING = /^'([^\\']*(?:\\.[^\\']*)*)'/;
-
-    DBLSTRING = /^"([^\\"]*(?:\\.[^\\"]*)*)"/;
-
-    return Lexer;
-
-  })();
-
-  exports.tokenize = function(sql, opts) {
-    return (new Lexer(sql, opts)).tokens;
-  };
-
-}).call(this);
-
-};require['./compiled_parser'] = new function() {
-  var exports = this;
-  /* parser generated by jison 0.4.15 */
-/*
-  Returns a Parser object of the following structure:
-
-  Parser: {
-    yy: {}
-  }
-
-  Parser.prototype: {
-    yy: {},
-    trace: function(),
-    symbols_: {associative list: name ==> number},
-    terminals_: {associative list: number ==> name},
-    productions_: [...],
-    performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$),
-    table: [...],
-    defaultActions: {...},
-    parseError: function(str, hash),
-    parse: function(input),
-
-    lexer: {
-        EOF: 1,
-        parseError: function(str, hash),
-        setInput: function(input),
-        input: function(),
-        unput: function(str),
-        more: function(),
-        less: function(n),
-        pastInput: function(),
-        upcomingInput: function(),
-        showPosition: function(),
-        test_match: function(regex_match_array, rule_index),
-        next: function(),
-        lex: function(),
-        begin: function(condition),
-        popState: function(),
-        _currentRules: function(),
-        topState: function(),
-        pushState: function(condition),
-
-        options: {
-            ranges: boolean           (optional: true ==> token location info will include a .range[] member)
-            flex: boolean             (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match)
-            backtrack_lexer: boolean  (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code)
-        },
-
-        performAction: function(yy, yy_, $avoiding_name_collisions, YY_START),
-        rules: [...],
-        conditions: {associative list: name ==> set},
-    }
-  }
-
-
-  token location info (@$, _$, etc.): {
-    first_line: n,
-    last_line: n,
-    first_column: n,
-    last_column: n,
-    range: [start_number, end_number]       (where the numbers are indexes into the input string, regular zero-based)
-  }
-
-
-  the parseError function receives a 'hash' object with these members for lexer and parser errors: {
-    text:        (matched text)
-    token:       (the produced terminal token, if any)
-    line:        (yylineno)
-  }
-  while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: {
-    loc:         (yylloc)
-    expected:    (string describing the set of expected tokens)
-    recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error)
-  }
-*/
-var parser = (function(){
-var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,8],$V1=[5,26],$V2=[1,14],$V3=[1,13],$V4=[5,26,31,42],$V5=[1,17],$V6=[5,26,31,42,45,62],$V7=[1,27],$V8=[1,29],$V9=[1,39],$Va=[1,43],$Vb=[1,44],$Vc=[1,40],$Vd=[1,41],$Ve=[1,38],$Vf=[1,42],$Vg=[1,25],$Vh=[5,26,31],$Vi=[5,26,31,42,45],$Vj=[1,56],$Vk=[18,43],$Vl=[1,59],$Vm=[1,60],$Vn=[1,61],$Vo=[1,62],$Vp=[1,63],$Vq=[5,18,23,26,31,34,37,38,41,42,43,45,62,64,65,66,67,68,70],$Vr=[5,18,23,26,31,34,37,38,41,42,43,44,45,51,62,64,65,66,67,68,70,71],$Vs=[1,69],$Vt=[2,83],$Vu=[1,83],$Vv=[1,84],$Vw=[1,102],$Vx=[5,26,31,42,43,44],$Vy=[1,110],$Vz=[5,26,31,42,43,45,64],$VA=[5,26,31,41,42,45,62],$VB=[1,113],$VC=[1,114],$VD=[1,115],$VE=[5,26,31,34,35,37,38,41,42,45,62],$VF=[5,18,23,26,31,34,37,38,41,42,43,45,62,64,70],$VG=[5,26,31,34,37,38,41,42,45,62],$VH=[5,26,31,42,56,58];
-var parser = {trace: function trace() { },
-yy: {},
-symbols_: {"error":2,"Root":3,"Query":4,"EOF":5,"SelectQuery":6,"Unions":7,"SelectWithLimitQuery":8,"BasicSelectQuery":9,"Select":10,"OrderClause":11,"GroupClause":12,"LimitClause":13,"SelectClause":14,"WhereClause":15,"SELECT":16,"Fields":17,"FROM":18,"Table":19,"DISTINCT":20,"Joins":21,"Literal":22,"AS":23,"LEFT_PAREN":24,"List":25,"RIGHT_PAREN":26,"WINDOW":27,"WINDOW_FUNCTION":28,"Number":29,"Union":30,"UNION":31,"ALL":32,"Join":33,"JOIN":34,"ON":35,"Expression":36,"LEFT":37,"RIGHT":38,"INNER":39,"OUTER":40,"WHERE":41,"LIMIT":42,"SEPARATOR":43,"OFFSET":44,"ORDER":45,"BY":46,"OrderArgs":47,"OffsetClause":48,"OrderArg":49,"Value":50,"DIRECTION":51,"OffsetRows":52,"FetchClause":53,"ROW":54,"ROWS":55,"FETCH":56,"FIRST":57,"ONLY":58,"NEXT":59,"GroupBasicClause":60,"HavingClause":61,"GROUP":62,"ArgumentList":63,"HAVING":64,"MATH":65,"MATH_MULTI":66,"OPERATOR":67,"BETWEEN":68,"BetweenExpression":69,"CONDITIONAL":70,"SUB_SELECT_OP":71,"SubSelectExpression":72,"SUB_SELECT_UNARY_OP":73,"String":74,"Function":75,"UserFunction":76,"Boolean":77,"Parameter":78,"NUMBER":79,"BOOLEAN":80,"PARAMETER":81,"STRING":82,"DBLSTRING":83,"LITERAL":84,"DOT":85,"FUNCTION":86,"AggregateArgumentList":87,"Field":88,"STAR":89,"$accept":0,"$end":1},
-terminals_: {2:"error",5:"EOF",16:"SELECT",18:"FROM",20:"DISTINCT",23:"AS",24:"LEFT_PAREN",26:"RIGHT_PAREN",27:"WINDOW",28:"WINDOW_FUNCTION",31:"UNION",32:"ALL",34:"JOIN",35:"ON",37:"LEFT",38:"RIGHT",39:"INNER",40:"OUTER",41:"WHERE",42:"LIMIT",43:"SEPARATOR",44:"OFFSET",45:"ORDER",46:"BY",51:"DIRECTION",54:"ROW",55:"ROWS",56:"FETCH",57:"FIRST",58:"ONLY",59:"NEXT",62:"GROUP",64:"HAVING",65:"MATH",66:"MATH_MULTI",67:"OPERATOR",68:"BETWEEN",70:"CONDITIONAL",71:"SUB_SELECT_OP",73:"SUB_SELECT_UNARY_OP",79:"NUMBER",80:"BOOLEAN",81:"PARAMETER",82:"STRING",83:"DBLSTRING",84:"LITERAL",85:"DOT",86:"FUNCTION",89:"STAR"},
-productions_: [0,[3,2],[4,1],[4,2],[6,1],[6,1],[9,1],[9,2],[9,2],[9,3],[8,2],[10,1],[10,2],[14,4],[14,5],[14,5],[14,6],[19,1],[19,2],[19,3],[19,3],[19,3],[19,4],[19,6],[7,1],[7,2],[30,2],[30,3],[21,1],[21,2],[33,4],[33,5],[33,5],[33,6],[33,6],[33,6],[33,6],[15,2],[13,2],[13,4],[13,4],[11,3],[11,4],[47,1],[47,3],[49,1],[49,2],[48,2],[48,3],[52,2],[52,2],[53,4],[53,4],[12,1],[12,2],[60,3],[61,2],[36,3],[36,3],[36,3],[36,3],[36,3],[36,3],[36,5],[36,3],[36,2],[36,1],[36,1],[69,3],[72,3],[50,1],[50,1],[50,1],[50,1],[50,1],[50,1],[50,1],[25,1],[29,1],[77,1],[78,1],[74,1],[74,1],[22,1],[22,3],[75,4],[76,3],[76,4],[87,1],[87,2],[63,1],[63,3],[17,1],[17,3],[88,1],[88,1],[88,3]],
-performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
-/* this == yyval */
-
-var $0 = $$.length - 1;
-switch (yystate) {
-case 1:
-return this.$ = $$[$0-1];
-break;
-case 2: case 4: case 5: case 6: case 11: case 53: case 66: case 67: case 70: case 71: case 72: case 73: case 74: case 75: case 76:
-this.$ = $$[$0];
-break;
-case 3:
-this.$ = (function () {
-        $$[$0-1].unions = $$[$0];
-        return $$[$0-1];
-      }());
-break;
-case 7:
-this.$ = (function () {
-        $$[$0-1].order = $$[$0];
-        return $$[$0-1];
-      }());
-break;
-case 8:
-this.$ = (function () {
-        $$[$0-1].group = $$[$0];
-        return $$[$0-1];
-      }());
-break;
-case 9:
-this.$ = (function () {
-        $$[$0-2].group = $$[$0-1];
-        $$[$0-2].order = $$[$0];
-        return $$[$0-2];
-      }());
-break;
-case 10:
-this.$ = (function () {
-        $$[$0-1].limit = $$[$0];
-        return $$[$0-1];
-      }());
-break;
-case 12:
-this.$ = (function () {
-        $$[$0-1].where = $$[$0];
-        return $$[$0-1];
-      }());
-break;
-case 13:
-this.$ = new yy.Select($$[$0-2], $$[$0], false);
-break;
-case 14:
-this.$ = new yy.Select($$[$0-2], $$[$0], true);
-break;
-case 15:
-this.$ = new yy.Select($$[$0-3], $$[$0-1], false, $$[$0]);
-break;
-case 16:
-this.$ = new yy.Select($$[$0-3], $$[$0-1], true, $$[$0]);
-break;
-case 17:
-this.$ = new yy.Table($$[$0]);
-break;
-case 18:
-this.$ = new yy.Table($$[$0-1], $$[$0]);
-break;
-case 19:
-this.$ = new yy.Table($$[$0-2], $$[$0]);
-break;
-case 20: case 49: case 50: case 51: case 52: case 57:
-this.$ = $$[$0-1];
-break;
-case 21: case 69:
-this.$ = new yy.SubSelect($$[$0-1]);
-break;
-case 22:
-this.$ = new yy.SubSelect($$[$0-2], $$[$0]);
-break;
-case 23:
-this.$ = new yy.Table($$[$0-5], null, $$[$0-4], $$[$0-3], $$[$0-1]);
-break;
-case 24: case 28: case 43: case 90: case 92:
-this.$ = [$$[$0]];
-break;
-case 25:
-this.$ = $$[$0-1].concat($$[$01]);
-break;
-case 26:
-this.$ = new yy.Union($$[$0]);
-break;
-case 27:
-this.$ = new yy.Union($$[$0], true);
-break;
-case 29:
-this.$ = $$[$0-1].concat($$[$0]);
-break;
-case 30:
-this.$ = new yy.Join($$[$0-2], $$[$0]);
-break;
-case 31:
-this.$ = new yy.Join($$[$0-2], $$[$0], 'LEFT');
-break;
-case 32:
-this.$ = new yy.Join($$[$0-2], $$[$0], 'RIGHT');
-break;
-case 33:
-this.$ = new yy.Join($$[$0-2], $$[$0], 'LEFT', 'INNER');
-break;
-case 34:
-this.$ = new yy.Join($$[$0-2], $$[$0], 'RIGHT', 'INNER');
-break;
-case 35:
-this.$ = new yy.Join($$[$0-2], $$[$0], 'LEFT', 'OUTER');
-break;
-case 36:
-this.$ = new yy.Join($$[$0-2], $$[$0], 'RIGHT', 'OUTER');
-break;
-case 37:
-this.$ = new yy.Where($$[$0]);
-break;
-case 38:
-this.$ = new yy.Limit($$[$0]);
-break;
-case 39:
-this.$ = new yy.Limit($$[$0], $$[$0-2]);
-break;
-case 40:
-this.$ = new yy.Limit($$[$0-2], $$[$0]);
-break;
-case 41:
-this.$ = new yy.Order($$[$0]);
-break;
-case 42:
-this.$ = new yy.Order($$[$0-1], $$[$0]);
-break;
-case 44: case 91: case 93:
-this.$ = $$[$0-2].concat($$[$0]);
-break;
-case 45:
-this.$ = new yy.OrderArgument($$[$0], 'ASC');
-break;
-case 46:
-this.$ = new yy.OrderArgument($$[$0-1], $$[$0]);
-break;
-case 47:
-this.$ = new yy.Offset($$[$0]);
-break;
-case 48:
-this.$ = new yy.Offset($$[$0-1], $$[$0]);
-break;
-case 54:
-this.$ = (function () {
-        $$[$0-1].having = $$[$0];
-        return $$[$0-1];
-      }());
-break;
-case 55:
-this.$ = new yy.Group($$[$0]);
-break;
-case 56:
-this.$ = new yy.Having($$[$0]);
-break;
-case 58: case 59: case 60: case 61: case 62: case 64:
-this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]);
-break;
-case 63:
-this.$ = new yy.Op($$[$0-3], $$[$0-4], $$[$0-1]);
-break;
-case 65:
-this.$ = new yy.UnaryOp($$[$0-1], $$[$0]);
-break;
-case 68:
-this.$ = new yy.BetweenOp([$$[$0-2], $$[$0]]);
-break;
-case 77:
-this.$ = new yy.ListValue($$[$0]);
-break;
-case 78:
-this.$ = new yy.NumberValue($$[$0]);
-break;
-case 79:
-this.$ = new yy.BooleanValue($$[$0]);
-break;
-case 80:
-this.$ = new yy.ParameterValue($$[$0]);
-break;
-case 81:
-this.$ = new yy.StringValue($$[$0], "'");
-break;
-case 82:
-this.$ = new yy.StringValue($$[$0], '"');
-break;
-case 83:
-this.$ = new yy.LiteralValue($$[$0]);
-break;
-case 84:
-this.$ = new yy.LiteralValue($$[$0-2], $$[$0]);
-break;
-case 85:
-this.$ = new yy.FunctionValue($$[$0-3], $$[$0-1]);
-break;
-case 86:
-this.$ = new yy.FunctionValue($$[$0-2], null, true);
-break;
-case 87:
-this.$ = new yy.FunctionValue($$[$0-3], $$[$0-1], true);
-break;
-case 88:
-this.$ = new yy.ArgumentListValue($$[$0]);
-break;
-case 89:
-this.$ = new yy.ArgumentListValue($$[$0], true);
-break;
-case 94:
-this.$ = new yy.Star();
-break;
-case 95:
-this.$ = new yy.Field($$[$0]);
-break;
-case 96:
-this.$ = new yy.Field($$[$0-2], $$[$0]);
-break;
-}
-},
-table: [{3:1,4:2,6:3,8:4,9:5,10:6,14:7,16:$V0},{1:[3]},{5:[1,9]},o($V1,[2,2],{7:10,13:11,30:12,31:$V2,42:$V3}),o($V4,[2,4]),o($V4,[2,5]),o($V4,[2,6],{11:15,12:16,60:18,45:$V5,62:[1,19]}),o($V6,[2,11],{15:20,41:[1,21]}),{17:22,20:[1,23],22:31,24:$V7,29:32,36:26,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf,88:24,89:$Vg},{1:[2,1]},o($V1,[2,3],{30:45,31:$V2}),o($V4,[2,10]),o($Vh,[2,24]),{29:46,79:$V9},{6:47,8:4,9:5,10:6,14:7,16:$V0,32:[1,48]},o($V4,[2,7]),o($V4,[2,8],{11:49,45:$V5}),{46:[1,50]},o($Vi,[2,53],{61:51,64:[1,52]}),{46:[1,53]},o($V6,[2,12]),{22:31,24:$V7,29:32,36:54,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{18:[1,55],43:$Vj},{17:57,22:31,24:$V7,29:32,36:26,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf,88:24,89:$Vg},o($Vk,[2,92]),o($Vk,[2,94]),o($Vk,[2,95],{23:[1,58],65:$Vl,66:$Vm,67:$Vn,68:$Vo,70:$Vp}),{4:65,6:3,8:4,9:5,10:6,14:7,16:$V0,22:31,24:$V7,29:32,36:64,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},o($Vq,[2,67],{71:[1,66]}),{24:[1,68],72:67},o($Vq,[2,66]),o($Vr,[2,70],{85:$Vs}),o($Vr,[2,71]),o($Vr,[2,72]),o($Vr,[2,73]),o($Vr,[2,74]),o($Vr,[2,75]),o($Vr,[2,76]),o([5,18,23,26,31,34,37,38,41,42,43,44,45,51,62,64,65,66,67,68,70,71,85],$Vt,{24:[1,70]}),o([5,18,23,26,31,34,37,38,41,42,43,44,45,51,54,55,62,64,65,66,67,68,70,71],[2,78]),o($Vr,[2,81]),o($Vr,[2,82]),{24:[1,71]},o($Vr,[2,79]),o($Vr,[2,80]),o($Vh,[2,25]),o($V4,[2,38],{43:[1,72],44:[1,73]}),o($Vh,[2,26],{13:11,42:$V3}),{6:74,8:4,9:5,10:6,14:7,16:$V0},o($V4,[2,9]),{22:31,29:32,47:75,49:76,50:77,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},o($Vi,[2,54]),{22:31,24:$V7,29:32,36:78,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{22:31,24:$V7,29:32,36:80,50:28,63:79,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},o($V6,[2,37],{65:$Vl,66:$Vm,67:$Vn,68:$Vo,70:$Vp}),{19:81,22:82,24:$Vu,84:$Vv},{22:31,24:$V7,29:32,36:26,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf,88:85,89:$Vg},{18:[1,86],43:$Vj},{22:87,84:$Vv},{22:31,24:$V7,29:32,36:88,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{22:31,24:$V7,29:32,36:89,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{22:31,24:$V7,29:32,36:90,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{22:31,24:$V7,29:32,36:92,50:28,69:91,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{22:31,24:$V7,29:32,36:93,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{26:[1,94],65:$Vl,66:$Vm,67:$Vn,68:$Vo,70:$Vp},{26:[1,95]},{24:[1,96],72:97},o($Vq,[2,65]),{4:65,6:3,8:4,9:5,10:6,14:7,16:$V0},{84:[1,98]},{20:$Vw,22:31,24:$V7,26:[1,99],29:32,36:80,50:28,63:101,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf,87:100},{20:$Vw,22:31,24:$V7,29:32,36:80,50:28,63:101,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf,87:103},{29:104,79:$V9},{29:105,79:$V9},o($Vh,[2,27],{13:11,42:$V3}),o($V4,[2,41],{48:106,43:[1,107],44:[1,108]}),o($Vx,[2,43]),o($Vx,[2,45],{51:[1,109]}),o($Vi,[2,56],{65:$Vl,66:$Vm,67:$Vn,68:$Vo,70:$Vp}),o([5,26,31,42,45,64],[2,55],{43:$Vy}),o($Vz,[2,90],{65:$Vl,66:$Vm,67:$Vn,68:$Vo,70:$Vp}),o($VA,[2,13],{21:111,33:112,34:$VB,37:$VC,38:$VD}),o($VE,[2,17],{22:116,23:[1,117],27:[1,118],84:$Vv,85:$Vs}),{4:120,6:3,8:4,9:5,10:6,14:7,16:$V0,22:31,24:$V7,25:119,29:32,36:80,50:28,63:121,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},o([5,18,23,26,27,31,34,35,37,38,41,42,43,45,62,84,85],$Vt),o($Vk,[2,93]),{19:122,22:82,24:$Vu,84:$Vv},o($Vk,[2,96],{85:$Vs}),o([5,18,23,26,31,34,37,38,41,42,43,45,62,64,65,67,70],[2,58],{66:$Vm,68:$Vo}),o([5,18,23,26,31,34,37,38,41,42,43,45,62,64,65,66,67,70],[2,59],{68:$Vo}),o([5,18,23,26,31,34,37,38,41,42,43,45,62,64,67,70],[2,60],{65:$Vl,66:$Vm,68:$Vo}),o($Vq,[2,61]),{65:$Vl,66:$Vm,67:$Vn,68:$Vo,70:[1,123]},o($VF,[2,62],{65:$Vl,66:$Vm,67:$Vn,68:$Vo}),o($Vq,[2,57]),o($Vq,[2,69]),{4:65,6:3,8:4,9:5,10:6,14:7,16:$V0,22:31,24:$V7,25:124,29:32,36:80,50:28,63:121,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},o($Vq,[2,64]),o([5,18,23,26,27,31,34,35,37,38,41,42,43,44,45,51,62,64,65,66,67,68,70,71,84,85],[2,84]),o($Vr,[2,86]),{26:[1,125]},{26:[2,88],43:$Vy},{22:31,24:$V7,29:32,36:80,50:28,63:126,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{26:[1,127]},o($V4,[2,39]),o($V4,[2,40]),o($V4,[2,42]),{22:31,29:32,49:128,50:77,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{29:130,52:129,79:$V9},o($Vx,[2,46]),{22:31,29:32,50:131,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},o($VA,[2,15],{33:132,34:$VB,37:$VC,38:$VD}),o($VG,[2,28]),{19:133,22:82,24:$Vu,84:$Vv},{34:[1,134],39:[1,135],40:[1,136]},{34:[1,137],39:[1,138],40:[1,139]},o($VE,[2,18],{85:$Vs}),{22:140,84:$Vv},{28:[1,141]},{26:[1,142]},{26:[1,143]},{26:[2,77],43:$Vy},o($VA,[2,14],{33:112,21:144,34:$VB,37:$VC,38:$VD}),{22:31,24:$V7,29:32,36:145,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{26:[1,146]},o($Vr,[2,87]),{26:[2,89],43:$Vy},o($Vr,[2,85]),o($Vx,[2,44]),o($V4,[2,47],{53:147,56:[1,148]}),{54:[1,149],55:[1,150]},o($Vz,[2,91]),o($VG,[2,29]),{35:[1,151]},{19:152,22:82,24:$Vu,84:$Vv},{34:[1,153]},{34:[1,154]},{19:155,22:82,24:$Vu,84:$Vv},{34:[1,156]},{34:[1,157]},o($VE,[2,19],{85:$Vs}),{24:[1,158]},o($VE,[2,20]),o($VE,[2,21],{22:159,84:$Vv}),o($VA,[2,16],{33:132,34:$VB,37:$VC,38:$VD}),o($VF,[2,68],{65:$Vl,66:$Vm,67:$Vn,68:$Vo}),o($Vq,[2,63]),o($V4,[2,48]),{57:[1,160],59:[1,161]},o($VH,[2,49]),o($VH,[2,50]),{22:31,24:$V7,29:32,36:162,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{35:[1,163]},{19:164,22:82,24:$Vu,84:$Vv},{19:165,22:82,24:$Vu,84:$Vv},{35:[1,166]},{19:167,22:82,24:$Vu,84:$Vv},{19:168,22:82,24:$Vu,84:$Vv},{29:169,79:$V9},o($VE,[2,22],{85:$Vs}),{29:130,52:170,79:$V9},{29:130,52:171,79:$V9},o($VG,[2,30],{65:$Vl,66:$Vm,67:$Vn,68:$Vo,70:$Vp}),{22:31,24:$V7,29:32,36:172,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{35:[1,173]},{35:[1,174]},{22:31,24:$V7,29:32,36:175,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{35:[1,176]},{35:[1,177]},{26:[1,178]},{58:[1,179]},{58:[1,180]},o($VG,[2,31],{65:$Vl,66:$Vm,67:$Vn,68:$Vo,70:$Vp}),{22:31,24:$V7,29:32,36:181,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{22:31,24:$V7,29:32,36:182,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},o($VG,[2,32],{65:$Vl,66:$Vm,67:$Vn,68:$Vo,70:$Vp}),{22:31,24:$V7,29:32,36:183,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{22:31,24:$V7,29:32,36:184,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},o($VE,[2,23]),o($V4,[2,51]),o($V4,[2,52]),o($VG,[2,33],{65:$Vl,66:$Vm,67:$Vn,68:$Vo,70:$Vp}),o($VG,[2,35],{65:$Vl,66:$Vm,67:$Vn,68:$Vo,70:$Vp}),o($VG,[2,34],{65:$Vl,66:$Vm,67:$Vn,68:$Vo,70:$Vp}),o($VG,[2,36],{65:$Vl,66:$Vm,67:$Vn,68:$Vo,70:$Vp})],
-defaultActions: {9:[2,1]},
-parseError: function parseError(str, hash) {
-    if (hash.recoverable) {
-        this.trace(str);
-    } else {
-        throw new Error(str);
-    }
-},
-parse: function parse(input) {
-    var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
-    var args = lstack.slice.call(arguments, 1);
-    var lexer = Object.create(this.lexer);
-    var sharedState = { yy: {} };
-    for (var k in this.yy) {
-        if (Object.prototype.hasOwnProperty.call(this.yy, k)) {
-            sharedState.yy[k] = this.yy[k];
-        }
-    }
-    lexer.setInput(input, sharedState.yy);
-    sharedState.yy.lexer = lexer;
-    sharedState.yy.parser = this;
-    if (typeof lexer.yylloc == 'undefined') {
-        lexer.yylloc = {};
-    }
-    var yyloc = lexer.yylloc;
-    lstack.push(yyloc);
-    var ranges = lexer.options && lexer.options.ranges;
-    if (typeof sharedState.yy.parseError === 'function') {
-        this.parseError = sharedState.yy.parseError;
-    } else {
-        this.parseError = Object.getPrototypeOf(this).parseError;
-    }
-    function popStack(n) {
-        stack.length = stack.length - 2 * n;
-        vstack.length = vstack.length - n;
-        lstack.length = lstack.length - n;
-    }
-    _token_stack:
-        function lex() {
-            var token;
-            token = lexer.lex() || EOF;
-            if (typeof token !== 'number') {
-                token = self.symbols_[token] || token;
-            }
-            return token;
-        }
-    var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
-    while (true) {
-        state = stack[stack.length - 1];
-        if (this.defaultActions[state]) {
-            action = this.defaultActions[state];
-        } else {
-            if (symbol === null || typeof symbol == 'undefined') {
-                symbol = lex();
-            }
-            action = table[state] && table[state][symbol];
-        }
-                    if (typeof action === 'undefined' || !action.length || !action[0]) {
-                var errStr = '';
-                expected = [];
-                for (p in table[state]) {
-                    if (this.terminals_[p] && p > TERROR) {
-                        expected.push('\'' + this.terminals_[p] + '\'');
-                    }
-                }
-                if (lexer.showPosition) {
-                    errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\'';
-                } else {
-                    errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\'');
-                }
-                this.parseError(errStr, {
-                    text: lexer.match,
-                    token: this.terminals_[symbol] || symbol,
-                    line: lexer.yylineno,
-                    loc: yyloc,
-                    expected: expected
-                });
-            }
-        if (action[0] instanceof Array && action.length > 1) {
-            throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol);
-        }
-        switch (action[0]) {
-        case 1:
-            stack.push(symbol);
-            vstack.push(lexer.yytext);
-            lstack.push(lexer.yylloc);
-            stack.push(action[1]);
-            symbol = null;
-            if (!preErrorSymbol) {
-                yyleng = lexer.yyleng;
-                yytext = lexer.yytext;
-                yylineno = lexer.yylineno;
-                yyloc = lexer.yylloc;
-                if (recovering > 0) {
-                    recovering--;
-                }
-            } else {
-                symbol = preErrorSymbol;
-                preErrorSymbol = null;
-            }
-            break;
-        case 2:
-            len = this.productions_[action[1]][1];
-            yyval.$ = vstack[vstack.length - len];
-            yyval._$ = {
-                first_line: lstack[lstack.length - (len || 1)].first_line,
-                last_line: lstack[lstack.length - 1].last_line,
-                first_column: lstack[lstack.length - (len || 1)].first_column,
-                last_column: lstack[lstack.length - 1].last_column
-            };
-            if (ranges) {
-                yyval._$.range = [
-                    lstack[lstack.length - (len || 1)].range[0],
-                    lstack[lstack.length - 1].range[1]
-                ];
-            }
-            r = this.performAction.apply(yyval, [
-                yytext,
-                yyleng,
-                yylineno,
-                sharedState.yy,
-                action[1],
-                vstack,
-                lstack
-            ].concat(args));
-            if (typeof r !== 'undefined') {
-                return r;
-            }
-            if (len) {
-                stack = stack.slice(0, -1 * len * 2);
-                vstack = vstack.slice(0, -1 * len);
-                lstack = lstack.slice(0, -1 * len);
-            }
-            stack.push(this.productions_[action[1]][0]);
-            vstack.push(yyval.$);
-            lstack.push(yyval._$);
-            newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
-            stack.push(newState);
-            break;
-        case 3:
-            return true;
-        }
-    }
-    return true;
-}};
-
-function Parser () {
-  this.yy = {};
-}
-Parser.prototype = parser;parser.Parser = Parser;
-return new Parser;
-})();
-
-
-if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
-exports.parser = parser;
-exports.Parser = parser.Parser;
-exports.parse = function () { return parser.parse.apply(parser, arguments); };
-exports.main = function commonjsMain(args) {
-    if (!args[1]) {
-        console.log('Usage: '+args[0]+' FILE');
-        process.exit(1);
-    }
-    var source = require('fs').readFileSync(require('path').normalize(args[1]), "utf8");
-    return exports.parser.parse(source);
-};
-if (typeof module !== 'undefined' && require.main === module) {
-  exports.main(process.argv.slice(1));
-}
-}
-};require['./nodes'] = new function() {
-  var exports = this;
-  // Generated by CoffeeScript 1.8.0
-(function() {
-  var ArgumentListValue, BetweenOp, Field, FunctionValue, Group, Having, Join, Limit, ListValue, LiteralValue, Offset, Op, Order, OrderArgument, ParameterValue, Select, Star, StringValue, SubSelect, Table, UnaryOp, Union, Where, indent;
-
-  indent = function(str) {
-    var line;
-    return ((function() {
-      var _i, _len, _ref, _results;
-      _ref = str.split("\n");
-      _results = [];
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        line = _ref[_i];
-        _results.push("  " + line);
-      }
-      return _results;
-    })()).join("\n");
-  };
-
-  exports.Select = Select = (function() {
-    function Select(fields, source, distinct, joins, unions) {
-      this.fields = fields;
-      this.source = source;
-      this.distinct = distinct != null ? distinct : false;
-      this.joins = joins != null ? joins : [];
-      this.unions = unions != null ? unions : [];
-      this.order = null;
-      this.group = null;
-      this.where = null;
-      this.limit = null;
-    }
-
-    Select.prototype.toString = function() {
-      var join, ret, union, _i, _j, _len, _len1, _ref, _ref1;
-      ret = ["SELECT " + (this.fields.join(', '))];
-      ret.push(indent("FROM " + this.source));
-      _ref = this.joins;
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        join = _ref[_i];
-        ret.push(indent(join.toString()));
-      }
-      if (this.where) {
-        ret.push(indent(this.where.toString()));
-      }
-      if (this.group) {
-        ret.push(indent(this.group.toString()));
-      }
-      if (this.order) {
-        ret.push(indent(this.order.toString()));
-      }
-      if (this.limit) {
-        ret.push(indent(this.limit.toString()));
-      }
-      _ref1 = this.unions;
-      for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
-        union = _ref1[_j];
-        ret.push(union.toString());
-      }
-      return ret.join("\n");
-    };
-
-    return Select;
-
-  })();
-
-  exports.SubSelect = SubSelect = (function() {
-    function SubSelect(select, name) {
-      this.select = select;
-      this.name = name != null ? name : null;
-      null;
-    }
-
-    SubSelect.prototype.toString = function() {
-      var ret;
-      ret = [];
-      ret.push('(');
-      ret.push(indent(this.select.toString()));
-      ret.push(this.name ? ") " + (this.name.toString()) : ")");
-      return ret.join("\n");
-    };
-
-    return SubSelect;
-
-  })();
-
-  exports.Join = Join = (function() {
-    function Join(right, conditions, side, mode) {
-      this.right = right;
-      this.conditions = conditions != null ? conditions : null;
-      this.side = side != null ? side : null;
-      this.mode = mode != null ? mode : null;
-      null;
-    }
-
-    Join.prototype.toString = function() {
-      var ret;
-      ret = '';
-      if (this.side != null) {
-        ret += "" + this.side + " ";
-      }
-      if (this.mode != null) {
-        ret += "" + this.mode + " ";
-      }
-      return ret + ("JOIN " + this.right + "\n") + indent("ON " + this.conditions);
-    };
-
-    return Join;
-
-  })();
-
-  exports.Union = Union = (function() {
-    function Union(query, all) {
-      this.query = query;
-      this.all = all != null ? all : false;
-      null;
-    }
-
-    Union.prototype.toString = function() {
-      var all;
-      all = this.all ? ' ALL' : '';
-      return "UNION" + all + "\n" + (this.query.toString());
-    };
-
-    return Union;
-
-  })();
-
-  exports.LiteralValue = LiteralValue = (function() {
-    function LiteralValue(value, value2) {
-      this.value = value;
-      this.value2 = value2 != null ? value2 : null;
-      if (this.value2) {
-        this.nested = true;
-        this.values = this.value.values;
-        this.values.push(value2);
-      } else {
-        this.nested = false;
-        this.values = [this.value];
-      }
-    }
-
-    LiteralValue.prototype.toString = function() {
-      return "`" + (this.values.join('.')) + "`";
-    };
-
-    return LiteralValue;
-
-  })();
-
-  exports.StringValue = StringValue = (function() {
-    function StringValue(value, quoteType) {
-      this.value = value;
-      this.quoteType = quoteType != null ? quoteType : "''";
-      null;
-    }
-
-    StringValue.prototype.toString = function() {
-      return "" + this.quoteType + this.value + this.quoteType;
-    };
-
-    return StringValue;
-
-  })();
-
-  exports.NumberValue = LiteralValue = (function() {
-    function LiteralValue(value) {
-      this.value = Number(value);
-    }
-
-    LiteralValue.prototype.toString = function() {
-      return this.value.toString();
-    };
-
-    return LiteralValue;
-
-  })();
-
-  exports.ListValue = ListValue = (function() {
-    function ListValue(value) {
-      this.value = value;
-    }
-
-    ListValue.prototype.toString = function() {
-      return "(" + (this.value.join(', ')) + ")";
-    };
-
-    return ListValue;
-
-  })();
-
-  exports.ParameterValue = ParameterValue = (function() {
-    function ParameterValue(value) {
-      this.value = value;
-      this.index = parseInt(value.substr(1), 10) - 1;
-    }
-
-    ParameterValue.prototype.toString = function() {
-      return "" + this.value;
-    };
-
-    return ParameterValue;
-
-  })();
-
-  exports.ArgumentListValue = ArgumentListValue = (function() {
-    function ArgumentListValue(value, distinct) {
-      this.value = value;
-      this.distinct = distinct != null ? distinct : false;
-      null;
-    }
-
-    ArgumentListValue.prototype.toString = function() {
-      if (this.distinct) {
-        return "DISTINCT " + (this.value.join(', '));
-      } else {
-        return "" + (this.value.join(', '));
-      }
-    };
-
-    return ArgumentListValue;
-
-  })();
-
-  exports.BooleanValue = LiteralValue = (function() {
-    function LiteralValue(value) {
-      this.value = (function() {
-        switch (value.toLowerCase()) {
-          case 'true':
-            return true;
-          case 'false':
-            return false;
-          default:
-            return null;
-        }
-      })();
-    }
-
-    LiteralValue.prototype.toString = function() {
-      if (this.value != null) {
-        return this.value.toString().toUpperCase();
-      } else {
-        return 'NULL';
-      }
-    };
-
-    return LiteralValue;
-
-  })();
-
-  exports.FunctionValue = FunctionValue = (function() {
-    function FunctionValue(name, _arguments, udf) {
-      this.name = name;
-      this["arguments"] = _arguments != null ? _arguments : null;
-      this.udf = udf != null ? udf : false;
-      null;
-    }
-
-    FunctionValue.prototype.toString = function() {
-      if (this["arguments"]) {
-        return "" + (this.name.toUpperCase()) + "(" + (this["arguments"].toString()) + ")";
-      } else {
-        return "" + (this.name.toUpperCase()) + "()";
-      }
-    };
-
-    return FunctionValue;
-
-  })();
-
-  exports.Order = Order = (function() {
-    function Order(orderings, offset) {
-      this.orderings = orderings;
-      this.offset = offset;
-    }
-
-    Order.prototype.toString = function() {
-      return ("ORDER BY " + (this.orderings.join(', '))) + (this.offset ? "\n" + this.offset.toString() : "");
-    };
-
-    return Order;
-
-  })();
-
-  exports.OrderArgument = OrderArgument = (function() {
-    function OrderArgument(value, direction) {
-      this.value = value;
-      this.direction = direction != null ? direction : 'ASC';
-      null;
-    }
-
-    OrderArgument.prototype.toString = function() {
-      return "" + this.value + " " + this.direction;
-    };
-
-    return OrderArgument;
-
-  })();
-
-  exports.Offset = Offset = (function() {
-    function Offset(row_count, limit) {
-      this.row_count = row_count;
-      this.limit = limit;
-      null;
-    }
-
-    Offset.prototype.toString = function() {
-      return ("OFFSET " + this.row_count + " ROWS") + (this.limit ? "\nFETCH NEXT " + this.limit + " ROWS ONLY" : "");
-    };
-
-    return Offset;
-
-  })();
-
-  exports.Limit = Limit = (function() {
-    function Limit(value, offset) {
-      this.value = value;
-      this.offset = offset;
-      null;
-    }
-
-    Limit.prototype.toString = function() {
-      return ("LIMIT " + this.value) + (this.offset ? "\nOFFSET " + this.offset : "");
-    };
-
-    return Limit;
-
-  })();
-
-  exports.Table = Table = (function() {
-    function Table(name, alias, win, winFn, winArg) {
-      this.name = name;
-      this.alias = alias != null ? alias : null;
-      this.win = win != null ? win : null;
-      this.winFn = winFn != null ? winFn : null;
-      this.winArg = winArg != null ? winArg : null;
-      null;
-    }
-
-    Table.prototype.toString = function() {
-      if (this.win) {
-        return "" + this.name + "." + this.win + ":" + this.winFn + "(" + this.winArg + ")";
-      } else if (this.alias) {
-        return "" + this.name + " AS " + this.alias;
-      } else {
-        return this.name.toString();
-      }
-    };
-
-    return Table;
-
-  })();
-
-  exports.Group = Group = (function() {
-    function Group(fields) {
-      this.fields = fields;
-      this.having = null;
-    }
-
-    Group.prototype.toString = function() {
-      var ret;
-      ret = ["GROUP BY " + (this.fields.join(', '))];
-      if (this.having) {
-        ret.push(this.having.toString());
-      }
-      return ret.join("\n");
-    };
+	    var match = regex.exec(this.chunk);
 
-    return Group;
+	    if (!match) {
+	      return 0;
+	    }
 
-  })();
-
-  exports.Where = Where = (function() {
-    function Where(conditions) {
-      this.conditions = conditions;
-      null;
-    }
+	    var partMatch = match[part];
 
-    Where.prototype.toString = function() {
-      return "WHERE " + this.conditions;
-    };
+	    if (output) {
+	      this.token(name, partMatch);
+	    }
 
-    return Where;
+	    return match[lengthPart].length;
+	  };
 
-  })();
+	  _proto.tokenizeFromWord = function tokenizeFromWord(name, word) {
+	    if (word === void 0) {
+	      word = name;
+	    }
 
-  exports.Having = Having = (function() {
-    function Having(conditions) {
-      this.conditions = conditions;
-      null;
-    }
+	    word = this.regexEscape(word);
+	    var matcher = /^\w+$/.test(word) ? new RegExp("^(" + word + ")\\b", 'ig') : new RegExp("^(" + word + ")", 'ig');
+	    var match = matcher.exec(this.chunk);
 
-    Having.prototype.toString = function() {
-      return "HAVING " + this.conditions;
-    };
-
-    return Having;
-
-  })();
-
-  exports.Op = Op = (function() {
-    function Op(operation, left, right) {
-      this.operation = operation;
-      this.left = left;
-      this.right = right;
-      null;
-    }
-
-    Op.prototype.toString = function() {
-      return "(" + this.left + " " + (this.operation.toUpperCase()) + " " + this.right + ")";
-    };
-
-    return Op;
-
-  })();
-
-  exports.UnaryOp = UnaryOp = (function() {
-    function UnaryOp(operator, operand) {
-      this.operator = operator;
-      this.operand = operand;
-      null;
-    }
-
-    UnaryOp.prototype.toString = function() {
-      return "(" + (this.operator.toUpperCase()) + " " + this.operand + ")";
-    };
-
-    return UnaryOp;
-
-  })();
-
-  exports.BetweenOp = BetweenOp = (function() {
-    function BetweenOp(value) {
-      this.value = value;
-      null;
-    }
-
-    BetweenOp.prototype.toString = function() {
-      return "" + (this.value.join(' AND '));
-    };
-
-    return BetweenOp;
-
-  })();
-
-  exports.Field = Field = (function() {
-    function Field(field, name) {
-      this.field = field;
-      this.name = name != null ? name : null;
-      null;
-    }
-
-    Field.prototype.toString = function() {
-      if (this.name) {
-        return "" + this.field + " AS " + this.name;
-      } else {
-        return this.field.toString();
-      }
-    };
-
-    return Field;
+	    if (!match) {
+	      return 0;
+	    }
 
-  })();
+	    this.token(name, match[1]);
+	    return match[1].length;
+	  };
 
-  exports.Star = Star = (function() {
-    function Star() {
-      null;
-    }
+	  _proto.tokenizeFromList = function tokenizeFromList(name, list) {
+	    var ret = 0;
 
-    Star.prototype.toString = function() {
-      return '*';
-    };
-
-    Star.prototype.star = true;
+	    for (var j = 0, len = list.length; j < len; j++) {
+	      var entry = list[j];
+	      ret = this.tokenizeFromWord(name, entry);
 
-    return Star;
+	      if (ret > 0) {
+	        break;
+	      }
+	    }
 
-  })();
+	    return ret;
+	  };
 
-}).call(this);
+	  _proto.keywordToken = function keywordToken() {
+	    return this.tokenizeFromWord('SELECT') || this.tokenizeFromWord('INSERT') || this.tokenizeFromWord('INTO') || this.tokenizeFromWord('DEFAULT') || this.tokenizeFromWord('VALUES') || this.tokenizeFromWord('DISTINCT') || this.tokenizeFromWord('FROM') || this.tokenizeFromWord('WHERE') || this.tokenizeFromWord('GROUP') || this.tokenizeFromWord('ORDER') || this.tokenizeFromWord('BY') || this.tokenizeFromWord('HAVING') || this.tokenizeFromWord('LIMIT') || this.tokenizeFromWord('JOIN') || this.tokenizeFromWord('LEFT') || this.tokenizeFromWord('RIGHT') || this.tokenizeFromWord('INNER') || this.tokenizeFromWord('OUTER') || this.tokenizeFromWord('ON') || this.tokenizeFromWord('AS') || this.tokenizeFromWord('CASE') || this.tokenizeFromWord('WHEN') || this.tokenizeFromWord('THEN') || this.tokenizeFromWord('ELSE') || this.tokenizeFromWord('END') || this.tokenizeFromWord('UNION') || this.tokenizeFromWord('ALL') || this.tokenizeFromWord('LIMIT') || this.tokenizeFromWord('OFFSET') || this.tokenizeFromWord('FETCH') || this.tokenizeFromWord('ROW') || this.tokenizeFromWord('ROWS') || this.tokenizeFromWord('ONLY') || this.tokenizeFromWord('NEXT') || this.tokenizeFromWord('FIRST');
+	  };
 
-};require['./parser'] = new function() {
-  var exports = this;
-  // Generated by CoffeeScript 1.8.0
-(function() {
-  var buildParser;
-
-  buildParser = function() {
-    var parser;
-    parser = require('./compiled_parser').parser;
-    parser.lexer = {
-      lex: function() {
-        var tag, _ref;
-        _ref = this.tokens[this.pos++] || [''], tag = _ref[0], this.yytext = _ref[1], this.yylineno = _ref[2];
-        return tag;
-      },
-      setInput: function(tokens) {
-        this.tokens = tokens;
-        return this.pos = 0;
-      },
-      upcomingInput: function() {
-        return "";
-      }
-    };
-    parser.yy = require('./nodes');
-    return parser;
-  };
+	  _proto.dotToken = function dotToken() {
+	    return this.tokenizeFromWord('DOT', '.');
+	  };
 
-  exports.parser = buildParser();
+	  _proto.operatorToken = function operatorToken() {
+	    return this.tokenizeFromList('OPERATOR', SQL_OPERATORS);
+	  };
 
-  exports.parse = function(str) {
-    return buildParser().parse(str);
-  };
+	  _proto.mathToken = function mathToken() {
+	    return this.tokenizeFromList('MATH', MATH) || this.tokenizeFromList('MATH_MULTI', MATH_MULTI);
+	  };
 
-}).call(this);
-
-};require['./sql_parser'] = new function() {
-  var exports = this;
-  // Generated by CoffeeScript 1.8.0
-(function() {
-  exports.lexer = require('./lexer');
+	  _proto.conditionalToken = function conditionalToken() {
+	    return this.tokenizeFromList('CONDITIONAL', SQL_CONDITIONALS);
+	  };
 
-  exports.parser = require('./parser');
-
-  exports.nodes = require('./nodes');
+	  _proto.betweenToken = function betweenToken() {
+	    return this.tokenizeFromList('BETWEEN', SQL_BETWEENS);
+	  };
 
-  exports.parse = function(sql) {
-    return exports.parser.parse(exports.lexer.tokenize(sql));
-  };
-
-}).call(this);
-
-};
-    return require['./sql_parser']
-  }();
-
-  if(typeof define === 'function' && define.amd) {
-    define(function() { return SQLParser });
-  } else { root.SQLParser = SQLParser }
-}(this));
\ No newline at end of file
+	  _proto.subSelectOpToken = function subSelectOpToken() {
+	    return this.tokenizeFromList('SUB_SELECT_OP', SUB_SELECT_OP);
+	  };
+
+	  _proto.subSelectUnaryOpToken = function subSelectUnaryOpToken() {
+	    return this.tokenizeFromList('SUB_SELECT_UNARY_OP', SUB_SELECT_UNARY_OP);
+	  };
+
+	  _proto.functionToken = function functionToken() {
+	    return this.tokenizeFromList('FUNCTION', SQL_FUNCTIONS);
+	  };
+
+	  _proto.sortOrderToken = function sortOrderToken() {
+	    return this.tokenizeFromList('DIRECTION', SQL_SORT_ORDERS);
+	  };
+
+	  _proto.booleanToken = function booleanToken() {
+	    return this.tokenizeFromList('BOOLEAN', BOOLEAN);
+	  };
+
+	  _proto.starToken = function starToken() {
+	    return this.tokenizeFromRegex('STAR', STAR);
+	  };
+
+	  _proto.seperatorToken = function seperatorToken() {
+	    return this.tokenizeFromRegex('SEPARATOR', SEPARATOR);
+	  };
+
+	  _proto.literalToken = function literalToken() {
+	    return this.tokenizeFromRegex('LITERAL', LITERAL, 1, 0);
+	  };
+
+	  _proto.numberToken = function numberToken() {
+	    return this.tokenizeFromRegex('NUMBER', NUMBER);
+	  };
+
+	  _proto.parameterToken = function parameterToken() {
+	    return this.tokenizeFromRegex('PARAMETER', PARAMETER, 1, 0);
+	  };
+
+	  _proto.stringToken = function stringToken() {
+	    return this.tokenizeFromStringRegex('STRING', STRING, 1, 0) || this.tokenizeFromRegex('DBLSTRING', DBLSTRING, 1, 0);
+	  };
+
+	  _proto.parensToken = function parensToken() {
+	    return this.tokenizeFromRegex('LEFT_PAREN', /^\(/) || this.tokenizeFromRegex('RIGHT_PAREN', /^\)/);
+	  };
+
+	  _proto.windowExtension = function windowExtension() {
+	    var match = /^\.(win):(length|time)/i.exec(this.chunk);
+
+	    if (!match) {
+	      return 0;
+	    }
+
+	    this.token('WINDOW', match[1]);
+	    this.token('WINDOW_FUNCTION', match[2]);
+	    return match[0].length;
+	  };
+
+	  _proto.whitespaceToken = function whitespaceToken() {
+	    var match = WHITESPACE.exec(this.chunk);
+
+	    if (!match) {
+	      return 0;
+	    }
+
+	    var partMatch = match[0];
+
+	    if (this.preserveWhitespace) {
+	      this.token('WHITESPACE', partMatch);
+	    }
+
+	    var newlines = partMatch.match(/\n/g, '');
+	    this.currentLine += (newlines != null ? newlines.length : void 0) || 0;
+	    return partMatch.length;
+	  };
+
+	  _proto.regexEscape = function regexEscape(str) {
+	    return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
+	  };
+
+	  return Lexer;
+	}();
+
+	var tokenize = function tokenize(sql, opts) {
+	  return new Lexer(sql, opts).tokens;
+	};
+
+	var lexer = {
+	  tokenize: tokenize
+	};
+
+	/* parser generated by jison 0.4.18 */
+
+	/*
+	  Returns a Parser object of the following structure:
+
+	  Parser: {
+	    yy: {}
+	  }
+
+	  Parser.prototype: {
+	    yy: {},
+	    trace: function(),
+	    symbols_: {associative list: name ==> number},
+	    terminals_: {associative list: number ==> name},
+	    productions_: [...],
+	    performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$),
+	    table: [...],
+	    defaultActions: {...},
+	    parseError: function(str, hash),
+	    parse: function(input),
+
+	    lexer: {
+	        EOF: 1,
+	        parseError: function(str, hash),
+	        setInput: function(input),
+	        input: function(),
+	        unput: function(str),
+	        more: function(),
+	        less: function(n),
+	        pastInput: function(),
+	        upcomingInput: function(),
+	        showPosition: function(),
+	        test_match: function(regex_match_array, rule_index),
+	        next: function(),
+	        lex: function(),
+	        begin: function(condition),
+	        popState: function(),
+	        _currentRules: function(),
+	        topState: function(),
+	        pushState: function(condition),
+
+	        options: {
+	            ranges: boolean           (optional: true ==> token location info will include a .range[] member)
+	            flex: boolean             (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match)
+	            backtrack_lexer: boolean  (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code)
+	        },
+
+	        performAction: function(yy, yy_, $avoiding_name_collisions, YY_START),
+	        rules: [...],
+	        conditions: {associative list: name ==> set},
+	    }
+	  }
+
+
+	  token location info (@$, _$, etc.): {
+	    first_line: n,
+	    last_line: n,
+	    first_column: n,
+	    last_column: n,
+	    range: [start_number, end_number]       (where the numbers are indexes into the input string, regular zero-based)
+	  }
+
+
+	  the parseError function receives a 'hash' object with these members for lexer and parser errors: {
+	    text:        (matched text)
+	    token:       (the produced terminal token, if any)
+	    line:        (yylineno)
+	  }
+	  while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: {
+	    loc:         (yylloc)
+	    expected:    (string describing the set of expected tokens)
+	    recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error)
+	  }
+	*/
+	var parser = function () {
+	  var o = function o(k, v, _o, l) {
+	    for (_o = _o || {}, l = k.length; l--; _o[k[l]] = v) {
+	    }
+
+	    return _o;
+	  },
+	      $V0 = [1, 8],
+	      $V1 = [5, 26],
+	      $V2 = [1, 14],
+	      $V3 = [1, 13],
+	      $V4 = [5, 26, 31, 42],
+	      $V5 = [1, 17],
+	      $V6 = [5, 26, 31, 42, 45, 62],
+	      $V7 = [1, 27],
+	      $V8 = [1, 29],
+	      $V9 = [1, 40],
+	      $Va = [1, 42],
+	      $Vb = [1, 46],
+	      $Vc = [1, 47],
+	      $Vd = [1, 43],
+	      $Ve = [1, 44],
+	      $Vf = [1, 41],
+	      $Vg = [1, 45],
+	      $Vh = [1, 25],
+	      $Vi = [5, 26, 31],
+	      $Vj = [5, 26, 31, 42, 45],
+	      $Vk = [1, 59],
+	      $Vl = [18, 43],
+	      $Vm = [1, 62],
+	      $Vn = [1, 63],
+	      $Vo = [1, 64],
+	      $Vp = [1, 65],
+	      $Vq = [1, 66],
+	      $Vr = [5, 18, 23, 26, 31, 34, 37, 38, 41, 42, 43, 45, 62, 64, 65, 66, 67, 68, 70, 78, 81, 82, 83],
+	      $Vs = [5, 18, 23, 26, 31, 34, 37, 38, 41, 42, 43, 44, 45, 51, 62, 64, 65, 66, 67, 68, 70, 71, 78, 81, 82, 83, 89, 90, 91, 92, 93, 94, 96],
+	      $Vt = [1, 74],
+	      $Vu = [1, 77],
+	      $Vv = [2, 93],
+	      $Vw = [1, 91],
+	      $Vx = [1, 92],
+	      $Vy = [5, 18, 23, 26, 31, 34, 37, 38, 41, 42, 43, 45, 62, 64, 65, 66, 67, 68, 70, 78, 81, 82, 83, 89, 90, 91, 92, 93, 94, 96],
+	      $Vz = [78, 81, 83],
+	      $VA = [1, 116],
+	      $VB = [5, 26, 31, 42, 43, 44],
+	      $VC = [1, 124],
+	      $VD = [5, 26, 31, 42, 43, 45, 64],
+	      $VE = [5, 26, 31, 41, 42, 45, 62],
+	      $VF = [1, 127],
+	      $VG = [1, 128],
+	      $VH = [1, 129],
+	      $VI = [5, 26, 31, 34, 35, 37, 38, 41, 42, 45, 62],
+	      $VJ = [5, 18, 23, 26, 31, 34, 37, 38, 41, 42, 43, 45, 62, 64, 70, 78, 81, 82, 83],
+	      $VK = [5, 26, 31, 34, 37, 38, 41, 42, 45, 62],
+	      $VL = [5, 26, 31, 42, 56, 58];
+
+	  var parser = {
+	    trace: function trace() {},
+	    yy: {},
+	    symbols_: {
+	      "error": 2,
+	      "Root": 3,
+	      "Query": 4,
+	      "EOF": 5,
+	      "SelectQuery": 6,
+	      "Unions": 7,
+	      "SelectWithLimitQuery": 8,
+	      "BasicSelectQuery": 9,
+	      "Select": 10,
+	      "OrderClause": 11,
+	      "GroupClause": 12,
+	      "LimitClause": 13,
+	      "SelectClause": 14,
+	      "WhereClause": 15,
+	      "SELECT": 16,
+	      "Fields": 17,
+	      "FROM": 18,
+	      "Table": 19,
+	      "DISTINCT": 20,
+	      "Joins": 21,
+	      "Literal": 22,
+	      "AS": 23,
+	      "LEFT_PAREN": 24,
+	      "List": 25,
+	      "RIGHT_PAREN": 26,
+	      "WINDOW": 27,
+	      "WINDOW_FUNCTION": 28,
+	      "Number": 29,
+	      "Union": 30,
+	      "UNION": 31,
+	      "ALL": 32,
+	      "Join": 33,
+	      "JOIN": 34,
+	      "ON": 35,
+	      "Expression": 36,
+	      "LEFT": 37,
+	      "RIGHT": 38,
+	      "INNER": 39,
+	      "OUTER": 40,
+	      "WHERE": 41,
+	      "LIMIT": 42,
+	      "SEPARATOR": 43,
+	      "OFFSET": 44,
+	      "ORDER": 45,
+	      "BY": 46,
+	      "OrderArgs": 47,
+	      "OffsetClause": 48,
+	      "OrderArg": 49,
+	      "Value": 50,
+	      "DIRECTION": 51,
+	      "OffsetRows": 52,
+	      "FetchClause": 53,
+	      "ROW": 54,
+	      "ROWS": 55,
+	      "FETCH": 56,
+	      "FIRST": 57,
+	      "ONLY": 58,
+	      "NEXT": 59,
+	      "GroupBasicClause": 60,
+	      "HavingClause": 61,
+	      "GROUP": 62,
+	      "ArgumentList": 63,
+	      "HAVING": 64,
+	      "MATH": 65,
+	      "MATH_MULTI": 66,
+	      "OPERATOR": 67,
+	      "BETWEEN": 68,
+	      "BetweenExpression": 69,
+	      "CONDITIONAL": 70,
+	      "SUB_SELECT_OP": 71,
+	      "SubSelectExpression": 72,
+	      "SUB_SELECT_UNARY_OP": 73,
+	      "WhitepaceList": 74,
+	      "CaseStatement": 75,
+	      "CASE": 76,
+	      "CaseWhens": 77,
+	      "END": 78,
+	      "CaseElse": 79,
+	      "CaseWhen": 80,
+	      "WHEN": 81,
+	      "THEN": 82,
+	      "ELSE": 83,
+	      "String": 84,
+	      "Function": 85,
+	      "UserFunction": 86,
+	      "Boolean": 87,
+	      "Parameter": 88,
+	      "NUMBER": 89,
+	      "BOOLEAN": 90,
+	      "PARAMETER": 91,
+	      "STRING": 92,
+	      "DBLSTRING": 93,
+	      "LITERAL": 94,
+	      "DOT": 95,
+	      "FUNCTION": 96,
+	      "AggregateArgumentList": 97,
+	      "Case": 98,
+	      "Field": 99,
+	      "STAR": 100,
+	      "$accept": 0,
+	      "$end": 1
+	    },
+	    terminals_: {
+	      2: "error",
+	      5: "EOF",
+	      16: "SELECT",
+	      18: "FROM",
+	      20: "DISTINCT",
+	      23: "AS",
+	      24: "LEFT_PAREN",
+	      26: "RIGHT_PAREN",
+	      27: "WINDOW",
+	      28: "WINDOW_FUNCTION",
+	      31: "UNION",
+	      32: "ALL",
+	      34: "JOIN",
+	      35: "ON",
+	      37: "LEFT",
+	      38: "RIGHT",
+	      39: "INNER",
+	      40: "OUTER",
+	      41: "WHERE",
+	      42: "LIMIT",
+	      43: "SEPARATOR",
+	      44: "OFFSET",
+	      45: "ORDER",
+	      46: "BY",
+	      51: "DIRECTION",
+	      54: "ROW",
+	      55: "ROWS",
+	      56: "FETCH",
+	      57: "FIRST",
+	      58: "ONLY",
+	      59: "NEXT",
+	      62: "GROUP",
+	      64: "HAVING",
+	      65: "MATH",
+	      66: "MATH_MULTI",
+	      67: "OPERATOR",
+	      68: "BETWEEN",
+	      70: "CONDITIONAL",
+	      71: "SUB_SELECT_OP",
+	      73: "SUB_SELECT_UNARY_OP",
+	      76: "CASE",
+	      78: "END",
+	      81: "WHEN",
+	      82: "THEN",
+	      83: "ELSE",
+	      89: "NUMBER",
+	      90: "BOOLEAN",
+	      91: "PARAMETER",
+	      92: "STRING",
+	      93: "DBLSTRING",
+	      94: "LITERAL",
+	      95: "DOT",
+	      96: "FUNCTION",
+	      98: "Case",
+	      100: "STAR"
+	    },
+	    productions_: [0, [3, 2], [4, 1], [4, 2], [6, 1], [6, 1], [9, 1], [9, 2], [9, 2], [9, 3], [8, 2], [10, 1], [10, 2], [14, 4], [14, 5], [14, 5], [14, 6], [19, 1], [19, 2], [19, 3], [19, 3], [19, 3], [19, 4], [19, 6], [7, 1], [7, 2], [30, 2], [30, 3], [21, 1], [21, 2], [33, 4], [33, 5], [33, 5], [33, 6], [33, 6], [33, 6], [33, 6], [15, 2], [13, 2], [13, 4], [13, 4], [11, 3], [11, 4], [47, 1], [47, 3], [49, 1], [49, 2], [48, 2], [48, 3], [52, 2], [52, 2], [53, 4], [53, 4], [12, 1], [12, 2], [60, 3], [61, 2], [36, 3], [36, 3], [36, 3], [36, 3], [36, 3], [36, 3], [36, 5], [36, 3], [36, 2], [36, 1], [36, 1], [36, 1], [36, 1], [69, 3], [75, 3], [75, 4], [80, 4], [77, 2], [77, 1], [79, 2], [72, 3], [50, 1], [50, 1], [50, 1], [50, 1], [50, 1], [50, 1], [50, 1], [74, 2], [74, 2], [25, 1], [29, 1], [87, 1], [88, 1], [84, 1], [84, 1], [22, 1], [22, 3], [85, 4], [86, 3], [86, 4], [86, 4], [97, 1], [97, 2], [63, 1], [63, 3], [17, 1], [17, 3], [99, 1], [99, 1], [99, 3]],
+	    performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate
+	    /* action[1] */
+	    , $$
+	    /* vstack */
+	    , _$
+	    /* lstack */
+	    ) {
+	      /* this == yyval */
+	      var $0 = $$.length - 1;
+
+	      switch (yystate) {
+	        case 1:
+	          return this.$ = $$[$0 - 1];
+
+	        case 2:
+	        case 4:
+	        case 5:
+	        case 6:
+	        case 11:
+	        case 53:
+	        case 66:
+	        case 68:
+	        case 69:
+	        case 78:
+	        case 79:
+	        case 80:
+	        case 81:
+	        case 82:
+	        case 83:
+	        case 84:
+	          this.$ = $$[$0];
+	          break;
+
+	        case 3:
+	          this.$ = function () {
+	            $$[$0 - 1].unions = $$[$0];
+	            return $$[$0 - 1];
+	          }();
+
+	          break;
+
+	        case 7:
+	          this.$ = function () {
+	            $$[$0 - 1].order = $$[$0];
+	            return $$[$0 - 1];
+	          }();
+
+	          break;
+
+	        case 8:
+	          this.$ = function () {
+	            $$[$0 - 1].group = $$[$0];
+	            return $$[$0 - 1];
+	          }();
+
+	          break;
+
+	        case 9:
+	          this.$ = function () {
+	            $$[$0 - 2].group = $$[$0 - 1];
+	            $$[$0 - 2].order = $$[$0];
+	            return $$[$0 - 2];
+	          }();
+
+	          break;
+
+	        case 10:
+	          this.$ = function () {
+	            $$[$0 - 1].limit = $$[$0];
+	            return $$[$0 - 1];
+	          }();
+
+	          break;
+
+	        case 12:
+	          this.$ = function () {
+	            $$[$0 - 1].where = $$[$0];
+	            return $$[$0 - 1];
+	          }();
+
+	          break;
+
+	        case 13:
+	          this.$ = new yy.Select($$[$0 - 2], $$[$0], false);
+	          break;
+
+	        case 14:
+	          this.$ = new yy.Select($$[$0 - 2], $$[$0], true);
+	          break;
+
+	        case 15:
+	          this.$ = new yy.Select($$[$0 - 3], $$[$0 - 1], false, $$[$0]);
+	          break;
+
+	        case 16:
+	          this.$ = new yy.Select($$[$0 - 3], $$[$0 - 1], true, $$[$0]);
+	          break;
+
+	        case 17:
+	          this.$ = new yy.Table($$[$0]);
+	          break;
+
+	        case 18:
+	          this.$ = new yy.Table($$[$0 - 1], $$[$0]);
+	          break;
+
+	        case 19:
+	          this.$ = new yy.Table($$[$0 - 2], $$[$0]);
+	          break;
+
+	        case 20:
+	        case 49:
+	        case 50:
+	        case 51:
+	        case 52:
+	        case 57:
+	          this.$ = $$[$0 - 1];
+	          break;
+
+	        case 21:
+	        case 77:
+	          this.$ = new yy.SubSelect($$[$0 - 1]);
+	          break;
+
+	        case 22:
+	          this.$ = new yy.SubSelect($$[$0 - 2], $$[$0]);
+	          break;
+
+	        case 23:
+	          this.$ = new yy.Table($$[$0 - 5], null, $$[$0 - 4], $$[$0 - 3], $$[$0 - 1]);
+	          break;
+
+	        case 24:
+	        case 28:
+	        case 43:
+	        case 75:
+	        case 101:
+	        case 103:
+	          this.$ = [$$[$0]];
+	          break;
+
+	        case 25:
+	        case 29:
+	        case 74:
+	          this.$ = $$[$0 - 1].concat($$[$0]);
+	          break;
+
+	        case 26:
+	          this.$ = new yy.Union($$[$0]);
+	          break;
+
+	        case 27:
+	          this.$ = new yy.Union($$[$0], true);
+	          break;
+
+	        case 30:
+	          this.$ = new yy.Join($$[$0 - 2], $$[$0]);
+	          break;
+
+	        case 31:
+	          this.$ = new yy.Join($$[$0 - 2], $$[$0], 'LEFT');
+	          break;
+
+	        case 32:
+	          this.$ = new yy.Join($$[$0 - 2], $$[$0], 'RIGHT');
+	          break;
+
+	        case 33:
+	          this.$ = new yy.Join($$[$0 - 2], $$[$0], 'LEFT', 'INNER');
+	          break;
+
+	        case 34:
+	          this.$ = new yy.Join($$[$0 - 2], $$[$0], 'RIGHT', 'INNER');
+	          break;
+
+	        case 35:
+	          this.$ = new yy.Join($$[$0 - 2], $$[$0], 'LEFT', 'OUTER');
+	          break;
+
+	        case 36:
+	          this.$ = new yy.Join($$[$0 - 2], $$[$0], 'RIGHT', 'OUTER');
+	          break;
+
+	        case 37:
+	          this.$ = new yy.Where($$[$0]);
+	          break;
+
+	        case 38:
+	          this.$ = new yy.Limit($$[$0]);
+	          break;
+
+	        case 39:
+	          this.$ = new yy.Limit($$[$0], $$[$0 - 2]);
+	          break;
+
+	        case 40:
+	          this.$ = new yy.Limit($$[$0 - 2], $$[$0]);
+	          break;
+
+	        case 41:
+	          this.$ = new yy.Order($$[$0]);
+	          break;
+
+	        case 42:
+	          this.$ = new yy.Order($$[$0 - 1], $$[$0]);
+	          break;
+
+	        case 44:
+	        case 102:
+	        case 104:
+	          this.$ = $$[$0 - 2].concat($$[$0]);
+	          break;
+
+	        case 45:
+	          this.$ = new yy.OrderArgument($$[$0], 'ASC');
+	          break;
+
+	        case 46:
+	          this.$ = new yy.OrderArgument($$[$0 - 1], $$[$0]);
+	          break;
+
+	        case 47:
+	          this.$ = new yy.Offset($$[$0]);
+	          break;
+
+	        case 48:
+	          this.$ = new yy.Offset($$[$0 - 1], $$[$0]);
+	          break;
+
+	        case 54:
+	          this.$ = function () {
+	            $$[$0 - 1].having = $$[$0];
+	            return $$[$0 - 1];
+	          }();
+
+	          break;
+
+	        case 55:
+	          this.$ = new yy.Group($$[$0]);
+	          break;
+
+	        case 56:
+	          this.$ = new yy.Having($$[$0]);
+	          break;
+
+	        case 58:
+	        case 59:
+	        case 60:
+	        case 61:
+	        case 62:
+	        case 64:
+	          this.$ = new yy.Op($$[$0 - 1], $$[$0 - 2], $$[$0]);
+	          break;
+
+	        case 63:
+	          this.$ = new yy.Op($$[$0 - 3], $$[$0 - 4], $$[$0 - 1]);
+	          break;
+
+	        case 65:
+	          this.$ = new yy.UnaryOp($$[$0 - 1], $$[$0]);
+	          break;
+
+	        case 67:
+	          this.$ = new yy.WhitepaceList($$[$0]);
+	          break;
+
+	        case 70:
+	          this.$ = new yy.BetweenOp([$$[$0 - 2], $$[$0]]);
+	          break;
+
+	        case 71:
+	          this.$ = new yy.Case($$[$0 - 1]);
+	          break;
+
+	        case 72:
+	          this.$ = new yy.Case($$[$0 - 2], $$[$0 - 1]);
+	          break;
+
+	        case 73:
+	          this.$ = new yy.CaseWhen($$[$0 - 2], $$[$0]);
+	          break;
+
+	        case 76:
+	          this.$ = new yy.CaseElse($$[$0]);
+	          break;
+
+	        case 85:
+	          this.$ = [$$[$0 - 1], $$[$0]];
+	          break;
+
+	        case 86:
+	          this.$ = function () {
+	            $$[$0 - 1].push($$[$0]);
+	            return $$[$0 - 1];
+	          }();
+
+	          break;
+
+	        case 87:
+	          this.$ = new yy.ListValue($$[$0]);
+	          break;
+
+	        case 88:
+	          this.$ = new yy.NumberValue($$[$0]);
+	          break;
+
+	        case 89:
+	          this.$ = new yy.BooleanValue($$[$0]);
+	          break;
+
+	        case 90:
+	          this.$ = new yy.ParameterValue($$[$0]);
+	          break;
+
+	        case 91:
+	          this.$ = new yy.StringValue($$[$0], "'");
+	          break;
+
+	        case 92:
+	          this.$ = new yy.StringValue($$[$0], '"');
+	          break;
+
+	        case 93:
+	          this.$ = new yy.LiteralValue($$[$0]);
+	          break;
+
+	        case 94:
+	          this.$ = new yy.LiteralValue($$[$0 - 2], $$[$0]);
+	          break;
+
+	        case 95:
+	          this.$ = new yy.FunctionValue($$[$0 - 3], $$[$0 - 1]);
+	          break;
+
+	        case 96:
+	          this.$ = new yy.FunctionValue($$[$0 - 2], null, true);
+	          break;
+
+	        case 97:
+	        case 98:
+	          this.$ = new yy.FunctionValue($$[$0 - 3], $$[$0 - 1], true);
+	          break;
+
+	        case 99:
+	          this.$ = new yy.ArgumentListValue($$[$0]);
+	          break;
+
+	        case 100:
+	          this.$ = new yy.ArgumentListValue($$[$0], true);
+	          break;
+
+	        case 105:
+	          this.$ = new yy.Star();
+	          break;
+
+	        case 106:
+	          this.$ = new yy.Field($$[$0]);
+	          break;
+
+	        case 107:
+	          this.$ = new yy.Field($$[$0 - 2], $$[$0]);
+	          break;
+	      }
+	    },
+	    table: [{
+	      3: 1,
+	      4: 2,
+	      6: 3,
+	      8: 4,
+	      9: 5,
+	      10: 6,
+	      14: 7,
+	      16: $V0
+	    }, {
+	      1: [3]
+	    }, {
+	      5: [1, 9]
+	    }, o($V1, [2, 2], {
+	      7: 10,
+	      13: 11,
+	      30: 12,
+	      31: $V2,
+	      42: $V3
+	    }), o($V4, [2, 4]), o($V4, [2, 5]), o($V4, [2, 6], {
+	      11: 15,
+	      12: 16,
+	      60: 18,
+	      45: $V5,
+	      62: [1, 19]
+	    }), o($V6, [2, 11], {
+	      15: 20,
+	      41: [1, 21]
+	    }), {
+	      17: 22,
+	      20: [1, 23],
+	      22: 33,
+	      24: $V7,
+	      29: 34,
+	      36: 26,
+	      50: 28,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg,
+	      99: 24,
+	      100: $Vh
+	    }, {
+	      1: [2, 1]
+	    }, o($V1, [2, 3], {
+	      30: 48,
+	      31: $V2
+	    }), o($V4, [2, 10]), o($Vi, [2, 24]), {
+	      29: 49,
+	      89: $Va
+	    }, {
+	      6: 50,
+	      8: 4,
+	      9: 5,
+	      10: 6,
+	      14: 7,
+	      16: $V0,
+	      32: [1, 51]
+	    }, o($V4, [2, 7]), o($V4, [2, 8], {
+	      11: 52,
+	      45: $V5
+	    }), {
+	      46: [1, 53]
+	    }, o($Vj, [2, 53], {
+	      61: 54,
+	      64: [1, 55]
+	    }), {
+	      46: [1, 56]
+	    }, o($V6, [2, 12]), {
+	      22: 33,
+	      24: $V7,
+	      29: 34,
+	      36: 57,
+	      50: 28,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }, {
+	      18: [1, 58],
+	      43: $Vk
+	    }, {
+	      17: 60,
+	      22: 33,
+	      24: $V7,
+	      29: 34,
+	      36: 26,
+	      50: 28,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg,
+	      99: 24,
+	      100: $Vh
+	    }, o($Vl, [2, 103]), o($Vl, [2, 105]), o($Vl, [2, 106], {
+	      23: [1, 61],
+	      65: $Vm,
+	      66: $Vn,
+	      67: $Vo,
+	      68: $Vp,
+	      70: $Vq
+	    }), {
+	      4: 68,
+	      6: 3,
+	      8: 4,
+	      9: 5,
+	      10: 6,
+	      14: 7,
+	      16: $V0,
+	      22: 33,
+	      24: $V7,
+	      29: 34,
+	      36: 67,
+	      50: 28,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }, o($Vr, [2, 69], {
+	      22: 33,
+	      29: 34,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      50: 70,
+	      71: [1, 69],
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }), {
+	      24: [1, 72],
+	      72: 71
+	    }, o($Vr, [2, 66]), o($Vr, [2, 67], {
+	      22: 33,
+	      29: 34,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      50: 73,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }), o($Vr, [2, 68]), o($Vs, [2, 78], {
+	      95: $Vt
+	    }), o($Vs, [2, 79]), o($Vs, [2, 80]), o($Vs, [2, 81]), o($Vs, [2, 82]), o($Vs, [2, 83]), o($Vs, [2, 84]), {
+	      77: 75,
+	      80: 76,
+	      81: $Vu
+	    }, o([5, 18, 23, 26, 31, 34, 37, 38, 41, 42, 43, 44, 45, 51, 62, 64, 65, 66, 67, 68, 70, 71, 78, 81, 82, 83, 89, 90, 91, 92, 93, 94, 95, 96], $Vv, {
+	      24: [1, 78]
+	    }), o([5, 18, 23, 26, 31, 34, 37, 38, 41, 42, 43, 44, 45, 51, 54, 55, 62, 64, 65, 66, 67, 68, 70, 71, 78, 81, 82, 83, 89, 90, 91, 92, 93, 94, 96], [2, 88]), o($Vs, [2, 91]), o($Vs, [2, 92]), {
+	      24: [1, 79]
+	    }, o($Vs, [2, 89]), o($Vs, [2, 90]), o($Vi, [2, 25]), o($V4, [2, 38], {
+	      43: [1, 80],
+	      44: [1, 81]
+	    }), o($Vi, [2, 26], {
+	      13: 11,
+	      42: $V3
+	    }), {
+	      6: 82,
+	      8: 4,
+	      9: 5,
+	      10: 6,
+	      14: 7,
+	      16: $V0
+	    }, o($V4, [2, 9]), {
+	      22: 33,
+	      29: 34,
+	      47: 83,
+	      49: 84,
+	      50: 85,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }, o($Vj, [2, 54]), {
+	      22: 33,
+	      24: $V7,
+	      29: 34,
+	      36: 86,
+	      50: 28,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }, {
+	      22: 33,
+	      24: $V7,
+	      29: 34,
+	      36: 88,
+	      50: 28,
+	      63: 87,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }, o($V6, [2, 37], {
+	      65: $Vm,
+	      66: $Vn,
+	      67: $Vo,
+	      68: $Vp,
+	      70: $Vq
+	    }), {
+	      19: 89,
+	      22: 90,
+	      24: $Vw,
+	      94: $Vx
+	    }, {
+	      22: 33,
+	      24: $V7,
+	      29: 34,
+	      36: 26,
+	      50: 28,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg,
+	      99: 93,
+	      100: $Vh
+	    }, {
+	      18: [1, 94],
+	      43: $Vk
+	    }, {
+	      22: 95,
+	      94: $Vx
+	    }, {
+	      22: 33,
+	      24: $V7,
+	      29: 34,
+	      36: 96,
+	      50: 28,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }, {
+	      22: 33,
+	      24: $V7,
+	      29: 34,
+	      36: 97,
+	      50: 28,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }, {
+	      22: 33,
+	      24: $V7,
+	      29: 34,
+	      36: 98,
+	      50: 28,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }, {
+	      22: 33,
+	      24: $V7,
+	      29: 34,
+	      36: 100,
+	      50: 28,
+	      69: 99,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }, {
+	      22: 33,
+	      24: $V7,
+	      29: 34,
+	      36: 101,
+	      50: 28,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }, {
+	      26: [1, 102],
+	      65: $Vm,
+	      66: $Vn,
+	      67: $Vo,
+	      68: $Vp,
+	      70: $Vq
+	    }, {
+	      26: [1, 103]
+	    }, {
+	      24: [1, 104],
+	      72: 105
+	    }, o($Vy, [2, 85]), o($Vr, [2, 65]), {
+	      4: 68,
+	      6: 3,
+	      8: 4,
+	      9: 5,
+	      10: 6,
+	      14: 7,
+	      16: $V0
+	    }, o($Vy, [2, 86]), {
+	      94: [1, 106]
+	    }, {
+	      78: [1, 107],
+	      79: 108,
+	      80: 109,
+	      81: $Vu,
+	      83: [1, 110]
+	    }, o($Vz, [2, 75]), {
+	      22: 33,
+	      24: $V7,
+	      29: 34,
+	      36: 111,
+	      50: 28,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }, {
+	      20: $VA,
+	      22: 33,
+	      24: $V7,
+	      26: [1, 112],
+	      29: 34,
+	      36: 88,
+	      50: 28,
+	      63: 115,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg,
+	      97: 113,
+	      98: [1, 114]
+	    }, {
+	      20: $VA,
+	      22: 33,
+	      24: $V7,
+	      29: 34,
+	      36: 88,
+	      50: 28,
+	      63: 115,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg,
+	      97: 117
+	    }, {
+	      29: 118,
+	      89: $Va
+	    }, {
+	      29: 119,
+	      89: $Va
+	    }, o($Vi, [2, 27], {
+	      13: 11,
+	      42: $V3
+	    }), o($V4, [2, 41], {
+	      48: 120,
+	      43: [1, 121],
+	      44: [1, 122]
+	    }), o($VB, [2, 43]), o($VB, [2, 45], {
+	      51: [1, 123]
+	    }), o($Vj, [2, 56], {
+	      65: $Vm,
+	      66: $Vn,
+	      67: $Vo,
+	      68: $Vp,
+	      70: $Vq
+	    }), o([5, 26, 31, 42, 45, 64], [2, 55], {
+	      43: $VC
+	    }), o($VD, [2, 101], {
+	      65: $Vm,
+	      66: $Vn,
+	      67: $Vo,
+	      68: $Vp,
+	      70: $Vq
+	    }), o($VE, [2, 13], {
+	      21: 125,
+	      33: 126,
+	      34: $VF,
+	      37: $VG,
+	      38: $VH
+	    }), o($VI, [2, 17], {
+	      22: 130,
+	      23: [1, 131],
+	      27: [1, 132],
+	      94: $Vx,
+	      95: $Vt
+	    }), {
+	      4: 134,
+	      6: 3,
+	      8: 4,
+	      9: 5,
+	      10: 6,
+	      14: 7,
+	      16: $V0,
+	      22: 33,
+	      24: $V7,
+	      25: 133,
+	      29: 34,
+	      36: 88,
+	      50: 28,
+	      63: 135,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }, o([5, 18, 23, 26, 27, 31, 34, 35, 37, 38, 41, 42, 43, 45, 62, 94, 95], $Vv), o($Vl, [2, 104]), {
+	      19: 136,
+	      22: 90,
+	      24: $Vw,
+	      94: $Vx
+	    }, o($Vl, [2, 107], {
+	      95: $Vt
+	    }), o([5, 18, 23, 26, 31, 34, 37, 38, 41, 42, 43, 45, 62, 64, 65, 67, 70, 78, 81, 82, 83], [2, 58], {
+	      66: $Vn,
+	      68: $Vp
+	    }), o([5, 18, 23, 26, 31, 34, 37, 38, 41, 42, 43, 45, 62, 64, 65, 66, 67, 70, 78, 81, 82, 83], [2, 59], {
+	      68: $Vp
+	    }), o([5, 18, 23, 26, 31, 34, 37, 38, 41, 42, 43, 45, 62, 64, 67, 70, 78, 81, 82, 83], [2, 60], {
+	      65: $Vm,
+	      66: $Vn,
+	      68: $Vp
+	    }), o($Vr, [2, 61]), {
+	      65: $Vm,
+	      66: $Vn,
+	      67: $Vo,
+	      68: $Vp,
+	      70: [1, 137]
+	    }, o($VJ, [2, 62], {
+	      65: $Vm,
+	      66: $Vn,
+	      67: $Vo,
+	      68: $Vp
+	    }), o($Vr, [2, 57]), o($Vr, [2, 77]), {
+	      4: 68,
+	      6: 3,
+	      8: 4,
+	      9: 5,
+	      10: 6,
+	      14: 7,
+	      16: $V0,
+	      22: 33,
+	      24: $V7,
+	      25: 138,
+	      29: 34,
+	      36: 88,
+	      50: 28,
+	      63: 135,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }, o($Vr, [2, 64]), o([5, 18, 23, 26, 27, 31, 34, 35, 37, 38, 41, 42, 43, 44, 45, 51, 62, 64, 65, 66, 67, 68, 70, 71, 78, 81, 82, 83, 89, 90, 91, 92, 93, 94, 95, 96], [2, 94]), o($Vr, [2, 71]), {
+	      78: [1, 139]
+	    }, o($Vz, [2, 74]), {
+	      22: 33,
+	      24: $V7,
+	      29: 34,
+	      36: 140,
+	      50: 28,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }, {
+	      65: $Vm,
+	      66: $Vn,
+	      67: $Vo,
+	      68: $Vp,
+	      70: $Vq,
+	      82: [1, 141]
+	    }, o($Vs, [2, 96]), {
+	      26: [1, 142]
+	    }, {
+	      26: [1, 143]
+	    }, {
+	      26: [2, 99],
+	      43: $VC
+	    }, {
+	      22: 33,
+	      24: $V7,
+	      29: 34,
+	      36: 88,
+	      50: 28,
+	      63: 144,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }, {
+	      26: [1, 145]
+	    }, o($V4, [2, 39]), o($V4, [2, 40]), o($V4, [2, 42]), {
+	      22: 33,
+	      29: 34,
+	      49: 146,
+	      50: 85,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }, {
+	      29: 148,
+	      52: 147,
+	      89: $Va
+	    }, o($VB, [2, 46]), {
+	      22: 33,
+	      24: $V7,
+	      29: 34,
+	      36: 149,
+	      50: 28,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }, o($VE, [2, 15], {
+	      33: 150,
+	      34: $VF,
+	      37: $VG,
+	      38: $VH
+	    }), o($VK, [2, 28]), {
+	      19: 151,
+	      22: 90,
+	      24: $Vw,
+	      94: $Vx
+	    }, {
+	      34: [1, 152],
+	      39: [1, 153],
+	      40: [1, 154]
+	    }, {
+	      34: [1, 155],
+	      39: [1, 156],
+	      40: [1, 157]
+	    }, o($VI, [2, 18], {
+	      95: $Vt
+	    }), {
+	      22: 158,
+	      94: $Vx
+	    }, {
+	      28: [1, 159]
+	    }, {
+	      26: [1, 160]
+	    }, {
+	      26: [1, 161]
+	    }, {
+	      26: [2, 87],
+	      43: $VC
+	    }, o($VE, [2, 14], {
+	      33: 126,
+	      21: 162,
+	      34: $VF,
+	      37: $VG,
+	      38: $VH
+	    }), {
+	      22: 33,
+	      24: $V7,
+	      29: 34,
+	      36: 163,
+	      50: 28,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }, {
+	      26: [1, 164]
+	    }, o($Vr, [2, 72]), {
+	      65: $Vm,
+	      66: $Vn,
+	      67: $Vo,
+	      68: $Vp,
+	      70: $Vq,
+	      78: [2, 76]
+	    }, {
+	      22: 33,
+	      24: $V7,
+	      29: 34,
+	      36: 165,
+	      50: 28,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }, o($Vs, [2, 97]), o($Vs, [2, 98]), {
+	      26: [2, 100],
+	      43: $VC
+	    }, o($Vs, [2, 95]), o($VB, [2, 44]), o($V4, [2, 47], {
+	      53: 166,
+	      56: [1, 167]
+	    }), {
+	      54: [1, 168],
+	      55: [1, 169]
+	    }, o($VD, [2, 102], {
+	      65: $Vm,
+	      66: $Vn,
+	      67: $Vo,
+	      68: $Vp,
+	      70: $Vq
+	    }), o($VK, [2, 29]), {
+	      35: [1, 170]
+	    }, {
+	      19: 171,
+	      22: 90,
+	      24: $Vw,
+	      94: $Vx
+	    }, {
+	      34: [1, 172]
+	    }, {
+	      34: [1, 173]
+	    }, {
+	      19: 174,
+	      22: 90,
+	      24: $Vw,
+	      94: $Vx
+	    }, {
+	      34: [1, 175]
+	    }, {
+	      34: [1, 176]
+	    }, o($VI, [2, 19], {
+	      95: $Vt
+	    }), {
+	      24: [1, 177]
+	    }, o($VI, [2, 20]), o($VI, [2, 21], {
+	      22: 178,
+	      94: $Vx
+	    }), o($VE, [2, 16], {
+	      33: 150,
+	      34: $VF,
+	      37: $VG,
+	      38: $VH
+	    }), o($VJ, [2, 70], {
+	      65: $Vm,
+	      66: $Vn,
+	      67: $Vo,
+	      68: $Vp
+	    }), o($Vr, [2, 63]), o($Vz, [2, 73], {
+	      65: $Vm,
+	      66: $Vn,
+	      67: $Vo,
+	      68: $Vp,
+	      70: $Vq
+	    }), o($V4, [2, 48]), {
+	      57: [1, 179],
+	      59: [1, 180]
+	    }, o($VL, [2, 49]), o($VL, [2, 50]), {
+	      22: 33,
+	      24: $V7,
+	      29: 34,
+	      36: 181,
+	      50: 28,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }, {
+	      35: [1, 182]
+	    }, {
+	      19: 183,
+	      22: 90,
+	      24: $Vw,
+	      94: $Vx
+	    }, {
+	      19: 184,
+	      22: 90,
+	      24: $Vw,
+	      94: $Vx
+	    }, {
+	      35: [1, 185]
+	    }, {
+	      19: 186,
+	      22: 90,
+	      24: $Vw,
+	      94: $Vx
+	    }, {
+	      19: 187,
+	      22: 90,
+	      24: $Vw,
+	      94: $Vx
+	    }, {
+	      29: 188,
+	      89: $Va
+	    }, o($VI, [2, 22], {
+	      95: $Vt
+	    }), {
+	      29: 148,
+	      52: 189,
+	      89: $Va
+	    }, {
+	      29: 148,
+	      52: 190,
+	      89: $Va
+	    }, o($VK, [2, 30], {
+	      65: $Vm,
+	      66: $Vn,
+	      67: $Vo,
+	      68: $Vp,
+	      70: $Vq
+	    }), {
+	      22: 33,
+	      24: $V7,
+	      29: 34,
+	      36: 191,
+	      50: 28,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }, {
+	      35: [1, 192]
+	    }, {
+	      35: [1, 193]
+	    }, {
+	      22: 33,
+	      24: $V7,
+	      29: 34,
+	      36: 194,
+	      50: 28,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }, {
+	      35: [1, 195]
+	    }, {
+	      35: [1, 196]
+	    }, {
+	      26: [1, 197]
+	    }, {
+	      58: [1, 198]
+	    }, {
+	      58: [1, 199]
+	    }, o($VK, [2, 31], {
+	      65: $Vm,
+	      66: $Vn,
+	      67: $Vo,
+	      68: $Vp,
+	      70: $Vq
+	    }), {
+	      22: 33,
+	      24: $V7,
+	      29: 34,
+	      36: 200,
+	      50: 28,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }, {
+	      22: 33,
+	      24: $V7,
+	      29: 34,
+	      36: 201,
+	      50: 28,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }, o($VK, [2, 32], {
+	      65: $Vm,
+	      66: $Vn,
+	      67: $Vo,
+	      68: $Vp,
+	      70: $Vq
+	    }), {
+	      22: 33,
+	      24: $V7,
+	      29: 34,
+	      36: 202,
+	      50: 28,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }, {
+	      22: 33,
+	      24: $V7,
+	      29: 34,
+	      36: 203,
+	      50: 28,
+	      72: 30,
+	      73: $V8,
+	      74: 31,
+	      75: 32,
+	      76: $V9,
+	      84: 35,
+	      85: 36,
+	      86: 37,
+	      87: 38,
+	      88: 39,
+	      89: $Va,
+	      90: $Vb,
+	      91: $Vc,
+	      92: $Vd,
+	      93: $Ve,
+	      94: $Vf,
+	      96: $Vg
+	    }, o($VI, [2, 23]), o($V4, [2, 51]), o($V4, [2, 52]), o($VK, [2, 33], {
+	      65: $Vm,
+	      66: $Vn,
+	      67: $Vo,
+	      68: $Vp,
+	      70: $Vq
+	    }), o($VK, [2, 35], {
+	      65: $Vm,
+	      66: $Vn,
+	      67: $Vo,
+	      68: $Vp,
+	      70: $Vq
+	    }), o($VK, [2, 34], {
+	      65: $Vm,
+	      66: $Vn,
+	      67: $Vo,
+	      68: $Vp,
+	      70: $Vq
+	    }), o($VK, [2, 36], {
+	      65: $Vm,
+	      66: $Vn,
+	      67: $Vo,
+	      68: $Vp,
+	      70: $Vq
+	    })],
+	    defaultActions: {
+	      9: [2, 1]
+	    },
+	    parseError: function parseError(str, hash) {
+	      if (hash.recoverable) {
+	        this.trace(str);
+	      } else {
+	        var error = new Error(str);
+	        error.hash = hash;
+	        throw error;
+	      }
+	    },
+	    parse: function parse(input) {
+	      var self = this,
+	          stack = [0],
+	          vstack = [null],
+	          lstack = [],
+	          table = this.table,
+	          yytext = '',
+	          yylineno = 0,
+	          yyleng = 0,
+	          TERROR = 2,
+	          EOF = 1;
+	      var args = lstack.slice.call(arguments, 1);
+	      var lexer = Object.create(this.lexer);
+	      var sharedState = {
+	        yy: {}
+	      };
+
+	      for (var k in this.yy) {
+	        if (Object.prototype.hasOwnProperty.call(this.yy, k)) {
+	          sharedState.yy[k] = this.yy[k];
+	        }
+	      }
+
+	      lexer.setInput(input, sharedState.yy);
+	      sharedState.yy.lexer = lexer;
+	      sharedState.yy.parser = this;
+
+	      if (typeof lexer.yylloc == 'undefined') {
+	        lexer.yylloc = {};
+	      }
+
+	      var yyloc = lexer.yylloc;
+	      lstack.push(yyloc);
+	      var ranges = lexer.options && lexer.options.ranges;
+
+	      if (typeof sharedState.yy.parseError === 'function') {
+	        this.parseError = sharedState.yy.parseError;
+	      } else {
+	        this.parseError = Object.getPrototypeOf(this).parseError;
+	      }
+
+	       var lex = function lex() {
+	        var token;
+	        token = lexer.lex() || EOF;
+
+	        if (typeof token !== 'number') {
+	          token = self.symbols_[token] || token;
+	        }
+
+	        return token;
+	      };
+
+	      var symbol,
+	          preErrorSymbol,
+	          state,
+	          action,
+	          r,
+	          yyval = {},
+	          p,
+	          len,
+	          newState,
+	          expected;
+
+	      while (true) {
+	        state = stack[stack.length - 1];
+
+	        if (this.defaultActions[state]) {
+	          action = this.defaultActions[state];
+	        } else {
+	          if (symbol === null || typeof symbol == 'undefined') {
+	            symbol = lex();
+	          }
+
+	          action = table[state] && table[state][symbol];
+	        }
+
+	        if (typeof action === 'undefined' || !action.length || !action[0]) {
+	          var errStr = '';
+	          expected = [];
+
+	          for (p in table[state]) {
+	            if (this.terminals_[p] && p > TERROR) {
+	              expected.push('\'' + this.terminals_[p] + '\'');
+	            }
+	          }
+
+	          if (lexer.showPosition) {
+	            errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\'';
+	          } else {
+	            errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\'');
+	          }
+
+	          this.parseError(errStr, {
+	            text: lexer.match,
+	            token: this.terminals_[symbol] || symbol,
+	            line: lexer.yylineno,
+	            loc: yyloc,
+	            expected: expected
+	          });
+	        }
+
+	        if (action[0] instanceof Array && action.length > 1) {
+	          throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol);
+	        }
+
+	        switch (action[0]) {
+	          case 1:
+	            stack.push(symbol);
+	            vstack.push(lexer.yytext);
+	            lstack.push(lexer.yylloc);
+	            stack.push(action[1]);
+	            symbol = null;
+
+	            if (!preErrorSymbol) {
+	              yyleng = lexer.yyleng;
+	              yytext = lexer.yytext;
+	              yylineno = lexer.yylineno;
+	              yyloc = lexer.yylloc;
+	            } else {
+	              symbol = preErrorSymbol;
+	              preErrorSymbol = null;
+	            }
+
+	            break;
+
+	          case 2:
+	            len = this.productions_[action[1]][1];
+	            yyval.$ = vstack[vstack.length - len];
+	            yyval._$ = {
+	              first_line: lstack[lstack.length - (len || 1)].first_line,
+	              last_line: lstack[lstack.length - 1].last_line,
+	              first_column: lstack[lstack.length - (len || 1)].first_column,
+	              last_column: lstack[lstack.length - 1].last_column
+	            };
+
+	            if (ranges) {
+	              yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
+	            }
+
+	            r = this.performAction.apply(yyval, [yytext, yyleng, yylineno, sharedState.yy, action[1], vstack, lstack].concat(args));
+
+	            if (typeof r !== 'undefined') {
+	              return r;
+	            }
+
+	            if (len) {
+	              stack = stack.slice(0, -1 * len * 2);
+	              vstack = vstack.slice(0, -1 * len);
+	              lstack = lstack.slice(0, -1 * len);
+	            }
+
+	            stack.push(this.productions_[action[1]][0]);
+	            vstack.push(yyval.$);
+	            lstack.push(yyval._$);
+	            newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
+	            stack.push(newState);
+	            break;
+
+	          case 3:
+	            return true;
+	        }
+	      }
+
+	      return true;
+	    }
+	  };
+
+	  function Parser() {
+	    this.yy = {};
+	  }
+
+	  Parser.prototype = parser;
+	  parser.Parser = Parser;
+	  return new Parser();
+	}();
+
+	var parser_1 = parser;
+	var compiled_parser = {
+	  parser: parser_1
+	};
+
+	var nodes = createCommonjsModule(function (module, exports) {
+	  function indent(str) {
+	    return function () {
+	      var ref = str.split('\n');
+	      var results = [];
+
+	      for (var i = 0, len = ref.length; i < len; i++) {
+	        results.push("  " + ref[i]);
+	      }
+
+	      return results;
+	    }().join('\n');
+	  }
+
+	  exports.Select =
+	  /*#__PURE__*/
+	  function () {
+	    function Select(fields, source, distinct, joins, unions) {
+	      if (distinct === void 0) {
+	        distinct = false;
+	      }
+
+	      if (joins === void 0) {
+	        joins = [];
+	      }
+
+	      if (unions === void 0) {
+	        unions = [];
+	      }
+
+	      this.fields = fields;
+	      this.source = source;
+	      this.distinct = distinct;
+	      this.joins = joins;
+	      this.unions = unions;
+	      this.order = null;
+	      this.group = null;
+	      this.where = null;
+	      this.limit = null;
+	    }
+
+	    var _proto = Select.prototype;
+
+	    _proto.toString = function toString() {
+	      var ret = ["SELECT " + this.fields.join(', ')];
+	      ret.push(indent("FROM " + this.source));
+
+	      for (var i = 0, len = this.joins.length; i < len; i++) {
+	        ret.push(indent(this.joins[i].toString()));
+	      }
+
+	      if (this.where) {
+	        ret.push(indent(this.where.toString()));
+	      }
+
+	      if (this.group) {
+	        ret.push(indent(this.group.toString()));
+	      }
+
+	      if (this.order) {
+	        ret.push(indent(this.order.toString()));
+	      }
+
+	      if (this.limit) {
+	        ret.push(indent(this.limit.toString()));
+	      }
+
+	      for (var j = 0, len1 = this.unions.length; j < len1; j++) {
+	        ret.push(this.unions[j].toString());
+	      }
+
+	      return ret.join('\n');
+	    };
+
+	    return Select;
+	  }();
+
+	  exports.SubSelect =
+	  /*#__PURE__*/
+	  function () {
+	    function SubSelect(select, name) {
+	      if (name === void 0) {
+	        name = null;
+	      }
+
+	      this.select = select;
+	      this.name = name;
+	    }
+
+	    var _proto2 = SubSelect.prototype;
+
+	    _proto2.toString = function toString() {
+	      var ret = [];
+	      ret.push('(');
+	      ret.push(indent(this.select.toString()));
+	      ret.push(this.name ? ") " + this.name.toString() : ')');
+	      return ret.join('\n');
+	    };
+
+	    return SubSelect;
+	  }();
+
+	  exports.Join =
+	  /*#__PURE__*/
+	  function () {
+	    function Join(right, conditions, side, mode) {
+	      if (conditions === void 0) {
+	        conditions = null;
+	      }
+
+	      if (side === void 0) {
+	        side = null;
+	      }
+
+	      if (mode === void 0) {
+	        mode = null;
+	      }
+
+	      this.right = right;
+	      this.conditions = conditions;
+	      this.side = side;
+	      this.mode = mode;
+	    }
+
+	    var _proto3 = Join.prototype;
+
+	    _proto3.toString = function toString() {
+	      var ret = '';
+
+	      if (this.side != null) {
+	        ret += this.side + " ";
+	      }
+
+	      if (this.mode != null) {
+	        ret += this.mode + " ";
+	      }
+
+	      return ret + ("JOIN " + this.right + "\n") + indent("ON " + this.conditions);
+	    };
+
+	    return Join;
+	  }();
+
+	  exports.Union =
+	  /*#__PURE__*/
+	  function () {
+	    function Union(query, all1) {
+	      if (all1 === void 0) {
+	        all1 = false;
+	      }
+
+	      this.query = query;
+	      this.all = all1;
+	    }
+
+	    var _proto4 = Union.prototype;
+
+	    _proto4.toString = function toString() {
+	      var all = this.all ? ' ALL' : '';
+	      return "UNION" + all + "\n" + this.query.toString();
+	    };
+
+	    return Union;
+	  }();
+
+	  exports.LiteralValue =
+	  /*#__PURE__*/
+	  function () {
+	    function LiteralValue(value1, value2) {
+	      if (value2 === void 0) {
+	        value2 = null;
+	      }
+
+	      this.value = value1;
+	      this.value2 = value2;
+
+	      if (this.value2) {
+	        this.nested = true;
+	        this.values = this.value.values;
+	        this.values.push(this.value2);
+	      } else {
+	        this.nested = false;
+	        this.values = [this.value];
+	      }
+	    } // TODO: Backtick quotes only supports MySQL, Postgres uses double-quotes
+
+
+	    var _proto5 = LiteralValue.prototype;
+
+	    _proto5.toString = function toString(quote) {
+	      if (quote === void 0) {
+	        quote = true;
+	      }
+
+	      if (quote) {
+	        return "`" + this.values.join('`.`') + "`";
+	      } else {
+	        return "" + this.values.join('.');
+	      }
+	    };
+
+	    return LiteralValue;
+	  }();
+
+	  exports.StringValue =
+	  /*#__PURE__*/
+	  function () {
+	    function StringValue(value1, quoteType) {
+	      if (quoteType === void 0) {
+	        quoteType = '\'\'';
+	      }
+
+	      this.value = value1;
+	      this.quoteType = quoteType;
+	    }
+
+	    var _proto6 = StringValue.prototype;
+
+	    _proto6.toString = function toString() {
+	      var escaped = this.quoteType === '\'' ? this.value.replace(/(^|[^\\])'/g, '$1\'\'') : this.value;
+	      return "" + this.quoteType + escaped + this.quoteType;
+	    };
+
+	    return StringValue;
+	  }();
+
+	  exports.NumberValue =
+	  /*#__PURE__*/
+	  function () {
+	    function NumberValue(value) {
+	      this.value = Number(value);
+	    }
+
+	    var _proto7 = NumberValue.prototype;
+
+	    _proto7.toString = function toString() {
+	      return this.value.toString();
+	    };
+
+	    return NumberValue;
+	  }();
+
+	  exports.ListValue =
+	  /*#__PURE__*/
+	  function () {
+	    function ListValue(value1) {
+	      this.value = value1;
+	    }
+
+	    var _proto8 = ListValue.prototype;
+
+	    _proto8.toString = function toString() {
+	      return "(" + this.value.join(', ') + ")";
+	    };
+
+	    return ListValue;
+	  }();
+
+	  exports.WhitepaceList =
+	  /*#__PURE__*/
+	  function () {
+	    function WhitepaceList(value1) {
+	      this.value = value1;
+	    }
+
+	    var _proto9 = WhitepaceList.prototype;
+
+	    _proto9.toString = function toString() {
+	      // not backtick for literals
+	      return this.value.map(function (value) {
+	        if (value instanceof exports.LiteralValue) {
+	          return value.toString(false);
+	        } else {
+	          return value.toString();
+	        }
+	      }).join(' ');
+	    };
+
+	    return WhitepaceList;
+	  }();
+
+	  exports.ParameterValue =
+	  /*#__PURE__*/
+	  function () {
+	    function ParameterValue(value) {
+	      this.value = value;
+	      this.index = parseInt(value.substr(1), 10) - 1;
+	    }
+
+	    var _proto10 = ParameterValue.prototype;
+
+	    _proto10.toString = function toString() {
+	      return "$" + this.value;
+	    };
+
+	    return ParameterValue;
+	  }();
+
+	  exports.ArgumentListValue =
+	  /*#__PURE__*/
+	  function () {
+	    function ArgumentListValue(value1, distinct) {
+	      if (distinct === void 0) {
+	        distinct = false;
+	      }
+
+	      this.value = value1;
+	      this.distinct = distinct;
+	    }
+
+	    var _proto11 = ArgumentListValue.prototype;
+
+	    _proto11.toString = function toString() {
+	      if (this.distinct) {
+	        return "DISTINCT " + this.value.join(', ');
+	      } else {
+	        return "" + this.value.join(', ');
+	      }
+	    };
+
+	    return ArgumentListValue;
+	  }();
+
+	  exports.BooleanValue =
+	  /*#__PURE__*/
+	  function () {
+	    function LiteralValue(value) {
+	      this.value = function () {
+	        switch (value.toLowerCase()) {
+	          case 'true':
+	            return true;
+
+	          case 'false':
+	            return false;
+
+	          default:
+	            return null;
+	        }
+	      }();
+	    }
+
+	    var _proto12 = LiteralValue.prototype;
+
+	    _proto12.toString = function toString() {
+	      if (this.value != null) {
+	        return this.value.toString().toUpperCase();
+	      } else {
+	        return 'NULL';
+	      }
+	    };
+
+	    return LiteralValue;
+	  }();
+
+	  exports.FunctionValue =
+	  /*#__PURE__*/
+	  function () {
+	    function FunctionValue(name, _arguments, udf) {
+	      if (_arguments === void 0) {
+	        _arguments = null;
+	      }
+
+	      if (udf === void 0) {
+	        udf = false;
+	      }
+
+	      this.name = name;
+	      this.arguments = _arguments;
+	      this.udf = udf;
+	    }
+
+	    var _proto13 = FunctionValue.prototype;
+
+	    _proto13.toString = function toString() {
+	      if (this.arguments) {
+	        return this.name.toUpperCase() + "(" + this.arguments.toString() + ")";
+	      } else {
+	        return this.name.toUpperCase() + "()";
+	      }
+	    };
+
+	    return FunctionValue;
+	  }();
+
+	  exports.Case =
+	  /*#__PURE__*/
+	  function () {
+	    function Case(whens, _else) {
+	      this.whens = whens;
+	      this["else"] = _else;
+	    }
+
+	    var _proto14 = Case.prototype;
+
+	    _proto14.toString = function toString() {
+	      var whensStr = this.whens.map(function (w) {
+	        return w.toString();
+	      }).join(' ');
+
+	      if (this["else"]) {
+	        return "CASE " + whensStr + " " + this["else"].toString() + " END";
+	      } else {
+	        return "CASE " + whensStr + " END";
+	      }
+	    };
+
+	    return Case;
+	  }();
+
+	  exports.CaseWhen =
+	  /*#__PURE__*/
+	  function () {
+	    function CaseWhen(whenCondition, resCondition) {
+	      this.whenCondition = whenCondition;
+	      this.resCondition = resCondition;
+	    }
+
+	    var _proto15 = CaseWhen.prototype;
+
+	    _proto15.toString = function toString() {
+	      return "WHEN " + this.whenCondition + " THEN " + this.resCondition;
+	    };
+
+	    return CaseWhen;
+	  }();
+
+	  exports.CaseElse =
+	  /*#__PURE__*/
+	  function () {
+	    function CaseElse(elseCondition) {
+	      this.elseCondition = elseCondition;
+	    }
+
+	    var _proto16 = CaseElse.prototype;
+
+	    _proto16.toString = function toString() {
+	      return "ELSE " + this.elseCondition;
+	    };
+
+	    return CaseElse;
+	  }();
+
+	  exports.Order =
+	  /*#__PURE__*/
+	  function () {
+	    function Order(orderings, offset) {
+	      this.orderings = orderings;
+	      this.offset = offset;
+	    }
+
+	    var _proto17 = Order.prototype;
+
+	    _proto17.toString = function toString() {
+	      return "ORDER BY " + this.orderings.join(', ') + (this.offset ? '\n' + this.offset.toString() : '');
+	    };
+
+	    return Order;
+	  }();
+
+	  exports.OrderArgument =
+	  /*#__PURE__*/
+	  function () {
+	    function OrderArgument(value, direction) {
+	      if (direction === void 0) {
+	        direction = 'ASC';
+	      }
+
+	      this.value = value;
+	      this.direction = direction;
+	    }
+
+	    var _proto18 = OrderArgument.prototype;
+
+	    _proto18.toString = function toString() {
+	      return this.value + " " + this.direction;
+	    };
+
+	    return OrderArgument;
+	  }();
+
+	  exports.Offset =
+	  /*#__PURE__*/
+	  function () {
+	    function Offset(row_count, limit) {
+	      this.row_count = row_count;
+	      this.limit = limit;
+	    }
+
+	    var _proto19 = Offset.prototype;
+
+	    _proto19.toString = function toString() {
+	      return "OFFSET " + this.row_count + " ROWS" + (this.limit ? "\nFETCH NEXT " + this.limit + " ROWS ONLY" : '');
+	    };
+
+	    return Offset;
+	  }();
+
+	  exports.Limit =
+	  /*#__PURE__*/
+	  function () {
+	    function Limit(value1, offset) {
+	      this.value = value1;
+	      this.offset = offset;
+	    }
+
+	    var _proto20 = Limit.prototype;
+
+	    _proto20.toString = function toString() {
+	      return "LIMIT " + this.value + (this.offset ? "\nOFFSET " + this.offset : '');
+	    };
+
+	    return Limit;
+	  }();
+
+	  exports.Table =
+	  /*#__PURE__*/
+	  function () {
+	    function Table(name, alias, win, winFn, winArg) {
+	      if (alias === void 0) {
+	        alias = null;
+	      }
+
+	      if (win === void 0) {
+	        win = null;
+	      }
+
+	      if (winFn === void 0) {
+	        winFn = null;
+	      }
+
+	      if (winArg === void 0) {
+	        winArg = null;
+	      }
+
+	      this.name = name;
+	      this.alias = alias;
+	      this.win = win;
+	      this.winFn = winFn;
+	      this.winArg = winArg;
+	    }
+
+	    var _proto21 = Table.prototype;
+
+	    _proto21.toString = function toString() {
+	      if (this.win) {
+	        return this.name + "." + this.win + ":" + this.winFn + "(" + this.winArg + ")";
+	      } else if (this.alias) {
+	        return this.name + " AS " + this.alias;
+	      } else {
+	        return this.name.toString();
+	      }
+	    };
+
+	    return Table;
+	  }();
+
+	  exports.Group =
+	  /*#__PURE__*/
+	  function () {
+	    function Group(fields) {
+	      this.fields = fields;
+	      this.having = null;
+	    }
+
+	    var _proto22 = Group.prototype;
+
+	    _proto22.toString = function toString() {
+	      var ret = ["GROUP BY " + this.fields.join(', ')];
+
+	      if (this.having) {
+	        ret.push(this.having.toString());
+	      }
+
+	      return ret.join('\n');
+	    };
+
+	    return Group;
+	  }();
+
+	  exports.Where =
+	  /*#__PURE__*/
+	  function () {
+	    function Where(conditions) {
+	      this.conditions = conditions;
+	    }
+
+	    var _proto23 = Where.prototype;
+
+	    _proto23.toString = function toString() {
+	      return "WHERE " + this.conditions;
+	    };
+
+	    return Where;
+	  }();
+
+	  exports.Having =
+	  /*#__PURE__*/
+	  function () {
+	    function Having(conditions) {
+	      this.conditions = conditions;
+	    }
+
+	    var _proto24 = Having.prototype;
+
+	    _proto24.toString = function toString() {
+	      return "HAVING " + this.conditions;
+	    };
+
+	    return Having;
+	  }();
+
+	  exports.Op =
+	  /*#__PURE__*/
+	  function () {
+	    function Op(operation, left, right) {
+	      this.operation = operation;
+	      this.left = left;
+	      this.right = right;
+	    }
+
+	    var _proto25 = Op.prototype;
+
+	    _proto25.toString = function toString() {
+	      return "(" + this.left + " " + this.operation.toUpperCase() + " " + this.right + ")";
+	    };
+
+	    return Op;
+	  }();
+
+	  exports.UnaryOp =
+	  /*#__PURE__*/
+	  function () {
+	    function UnaryOp(operator, operand) {
+	      this.operator = operator;
+	      this.operand = operand;
+	    }
+
+	    var _proto26 = UnaryOp.prototype;
+
+	    _proto26.toString = function toString() {
+	      return "(" + this.operator.toUpperCase() + " " + this.operand + ")";
+	    };
+
+	    return UnaryOp;
+	  }();
+
+	  exports.BetweenOp =
+	  /*#__PURE__*/
+	  function () {
+	    function BetweenOp(value) {
+	      this.value = value;
+	    }
+
+	    var _proto27 = BetweenOp.prototype;
+
+	    _proto27.toString = function toString() {
+	      return "" + this.value.join(' AND ');
+	    };
+
+	    return BetweenOp;
+	  }();
+
+	  exports.Field =
+	  /*#__PURE__*/
+	  function () {
+	    function Field(field, name) {
+	      if (name === void 0) {
+	        name = null;
+	      }
+
+	      this.field = field;
+	      this.name = name;
+	    }
+
+	    var _proto28 = Field.prototype;
+
+	    _proto28.toString = function toString() {
+	      if (this.name) {
+	        return this.field + " AS " + this.name;
+	      } else {
+	        return this.field.toString();
+	      }
+	    };
+
+	    return Field;
+	  }();
+
+	  exports.Star =
+	  /*#__PURE__*/
+	  function () {
+	    function Star() {}
+
+	    var _proto29 = Star.prototype;
+
+	    _proto29.toString = function toString() {
+	      return '*';
+	    };
+
+	    return Star;
+	  }();
+	});
+	var nodes_1 = nodes.Select;
+	var nodes_2 = nodes.SubSelect;
+	var nodes_3 = nodes.Join;
+	var nodes_4 = nodes.Union;
+	var nodes_5 = nodes.LiteralValue;
+	var nodes_6 = nodes.StringValue;
+	var nodes_7 = nodes.NumberValue;
+	var nodes_8 = nodes.ListValue;
+	var nodes_9 = nodes.WhitepaceList;
+	var nodes_10 = nodes.ParameterValue;
+	var nodes_11 = nodes.ArgumentListValue;
+	var nodes_12 = nodes.BooleanValue;
+	var nodes_13 = nodes.FunctionValue;
+	var nodes_14 = nodes.Case;
+	var nodes_15 = nodes.CaseWhen;
+	var nodes_16 = nodes.CaseElse;
+	var nodes_17 = nodes.Order;
+	var nodes_18 = nodes.OrderArgument;
+	var nodes_19 = nodes.Offset;
+	var nodes_20 = nodes.Limit;
+	var nodes_21 = nodes.Table;
+	var nodes_22 = nodes.Group;
+	var nodes_23 = nodes.Where;
+	var nodes_24 = nodes.Having;
+	var nodes_25 = nodes.Op;
+	var nodes_26 = nodes.UnaryOp;
+	var nodes_27 = nodes.BetweenOp;
+	var nodes_28 = nodes.Field;
+	var nodes_29 = nodes.Star;
+
+	var parser$1 = compiled_parser.parser;
+	parser$1.lexer = {
+	  lex: function lex() {
+	    var tag;
+
+	    var _ref = this.tokens[this.pos++] || [''];
+
+	    tag = _ref[0];
+	    this.yytext = _ref[1];
+	    this.yylineno = _ref[2];
+	    return tag;
+	  },
+	  setInput: function setInput(tokens) {
+	    this.tokens = tokens;
+	    return this.pos = 0;
+	  },
+	  upcomingInput: function upcomingInput() {
+	    return '';
+	  }
+	};
+	parser$1.yy = nodes;
+	var parser_2 = parser$1;
+
+	var parse = function parse(str) {
+	  return parser$1.parse(str);
+	};
+
+	var parser_1$1 = {
+	  parser: parser_2,
+	  parse: parse
+	};
+
+	var sql_parser = createCommonjsModule(function (module, exports) {
+	  exports.lexer = lexer;
+	  exports.parser = parser_1$1;
+	  exports.nodes = nodes;
+
+	  exports.parse = function (sql) {
+	    return exports.parser.parse(exports.lexer.tokenize(sql));
+	  };
+	});
+	var sql_parser_1 = sql_parser.lexer;
+	var sql_parser_2 = sql_parser.parser;
+	var sql_parser_3 = sql_parser.nodes;
+	var sql_parser_4 = sql_parser.parse;
+
+	exports.default = sql_parser;
+	exports.lexer = sql_parser_1;
+	exports.nodes = sql_parser_3;
+	exports.parse = sql_parser_4;
+	exports.parser = sql_parser_2;
+
+	Object.defineProperty(exports, '__esModule', { value: true });
+
+})));
+//# sourceMappingURL=sql-parser.js.map
diff --git a/browser/sql-parser.js.map b/browser/sql-parser.js.map
new file mode 100644
index 0000000..941ec07
--- /dev/null
+++ b/browser/sql-parser.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"sql-parser.js","sources":["../src/lexer.js","../src/compiled_parser.js","../src/nodes.js","../src/parser.js","../src/sql_parser.js"],"sourcesContent":["const SQL_FUNCTIONS = ['AVG', 'COUNT', 'MIN', 'MAX', 'SUM'];\nconst SQL_SORT_ORDERS = ['ASC', 'DESC'];\nconst SQL_OPERATORS = ['=', '!=', '>=', '>', '<=', '<>', '<', 'LIKE', 'NOT LIKE', 'ILIKE', 'NOT ILIKE', 'IS NOT', 'IS', 'REGEXP', 'NOT REGEXP'];\nconst SUB_SELECT_OP = ['IN', 'NOT IN', 'ANY', 'ALL', 'SOME'];\nconst SUB_SELECT_UNARY_OP = ['EXISTS'];\nconst SQL_CONDITIONALS = ['AND', 'OR'];\nconst SQL_BETWEENS = ['BETWEEN', 'NOT BETWEEN'];\nconst BOOLEAN = ['TRUE', 'FALSE', 'NULL'];\nconst MATH = ['+', '-', '||', '&&'];\nconst MATH_MULTI = ['/', '*'];\nconst STAR = /^\\*/;\nconst SEPARATOR = /^,/;\nconst WHITESPACE = /^[ \\n\\r]+/;\nconst LITERAL = /^`?([a-z_][a-z0-9_]{0,}(\\:(number|float|string|date|boolean))?)`?/i;\nconst PARAMETER = /^\\$([a-z0-9_]+(\\:(number|float|string|date|boolean))?)/;\nconst NUMBER = /^[+-]?[0-9]+(\\.[0-9]+)?/;\nconst STRING = /^'((?:[^\\\\']+?|\\\\.|'')*)'(?!')/;\nconst DBLSTRING = /^\"([^\\\\\"]*(?:\\\\.[^\\\\\"]*)*)\"/;\n\nclass Lexer {\n\n    constructor(sql, opts = {}) {\n        this.sql = sql;\n        this.preserveWhitespace = opts.preserveWhitespace || false;\n        this.tokens = [];\n        this.currentLine = 1;\n        this.currentOffset = 0;\n\n        let i = 0;\n        while (!!(this.chunk = sql.slice(i))) {\n            const bytesConsumed = this.keywordToken() ||\n                this.starToken() ||\n                this.booleanToken() ||\n                this.functionToken() ||\n                this.windowExtension() ||\n                this.sortOrderToken() ||\n                this.seperatorToken() ||\n                this.operatorToken() ||\n                this.numberToken() ||\n                this.mathToken() ||\n                this.dotToken() ||\n                this.conditionalToken() ||\n                this.betweenToken() ||\n                this.subSelectOpToken() ||\n                this.subSelectUnaryOpToken() ||\n                this.stringToken() ||\n                this.parameterToken() ||\n                this.parensToken() ||\n                this.whitespaceToken() ||\n                this.literalToken();\n\n            if (bytesConsumed < 1) {\n                throw new Error(`NOTHING CONSUMED: Stopped at - '${this.chunk.slice(0, 30)}'`);\n            }\n\n            i += bytesConsumed;\n            this.currentOffset += bytesConsumed;\n        }\n\n        this.token('EOF', '');\n        this.postProcess();\n    }\n\n    postProcess() {\n        const results = [];\n        for (let i =0, j = 0, len = this.tokens.length; j < len; i = ++j) {\n            const token = this.tokens[i];\n            if (token[0] === 'STAR') {\n                const next_token = this.tokens[i + 1];\n                if (!(next_token[0] === 'SEPARATOR' || next_token[0] === 'FROM')) {\n                    results.push(token[0] = 'MATH_MULTI');\n                }\n                else {\n                    results.push(void 0);\n                }\n            }\n            else {\n                results.push(void 0);\n            }\n        }\n        return results;\n    }\n\n    token(name, value) {\n        return this.tokens.push([name, value, this.currentLine, this.currentOffset]);\n    }\n\n    tokenizeFromStringRegex(name, regex, part = 0, lengthPart = part, output = true) {\n        const match = regex.exec(this.chunk);\n        if (!match) {\n            return 0;\n        }\n        const partMatch = match[part].replace(/''/g, '\\'');\n        if (output) {\n            this.token(name, partMatch);\n        }\n        return match[lengthPart].length;\n    }\n\n    tokenizeFromRegex(name, regex, part = 0, lengthPart = part, output = true) {\n        const match = regex.exec(this.chunk);\n        if (!match) {\n            return 0;\n        }\n        const partMatch = match[part];\n        if (output) {\n            this.token(name, partMatch);\n        }\n        return match[lengthPart].length;\n    }\n\n    tokenizeFromWord(name, word = name) {\n        word = this.regexEscape(word);\n        const matcher = /^\\w+$/.test(word) ? new RegExp(`^(${word})\\\\b`, 'ig') : new RegExp(`^(${word})`, 'ig');\n        const match = matcher.exec(this.chunk);\n        if (!match) {\n            return 0;\n        }\n        this.token(name, match[1]);\n        return match[1].length;\n    }\n\n    tokenizeFromList(name, list) {\n        let ret = 0;\n        for (let j = 0, len = list.length; j < len; j++) {\n            const entry = list[j];\n            ret = this.tokenizeFromWord(name, entry);\n            if (ret > 0) {\n                break;\n            }\n        }\n        return ret;\n    }\n\n    keywordToken() {\n        return this.tokenizeFromWord('SELECT') ||\n            this.tokenizeFromWord('INSERT') ||\n            this.tokenizeFromWord('INTO') ||\n            this.tokenizeFromWord('DEFAULT') ||\n            this.tokenizeFromWord('VALUES') ||\n            this.tokenizeFromWord('DISTINCT') ||\n            this.tokenizeFromWord('FROM') ||\n            this.tokenizeFromWord('WHERE') ||\n            this.tokenizeFromWord('GROUP') ||\n            this.tokenizeFromWord('ORDER') ||\n            this.tokenizeFromWord('BY') ||\n            this.tokenizeFromWord('HAVING') ||\n            this.tokenizeFromWord('LIMIT') ||\n            this.tokenizeFromWord('JOIN') ||\n            this.tokenizeFromWord('LEFT') ||\n            this.tokenizeFromWord('RIGHT') ||\n            this.tokenizeFromWord('INNER') ||\n            this.tokenizeFromWord('OUTER') ||\n            this.tokenizeFromWord('ON') ||\n            this.tokenizeFromWord('AS') ||\n            this.tokenizeFromWord('CASE') ||\n            this.tokenizeFromWord('WHEN') ||\n            this.tokenizeFromWord('THEN') ||\n            this.tokenizeFromWord('ELSE') ||\n            this.tokenizeFromWord('END') ||\n            this.tokenizeFromWord('UNION') ||\n            this.tokenizeFromWord('ALL') ||\n            this.tokenizeFromWord('LIMIT') ||\n            this.tokenizeFromWord('OFFSET') ||\n            this.tokenizeFromWord('FETCH') ||\n            this.tokenizeFromWord('ROW') ||\n            this.tokenizeFromWord('ROWS') ||\n            this.tokenizeFromWord('ONLY') ||\n            this.tokenizeFromWord('NEXT') ||\n            this.tokenizeFromWord('FIRST');\n    }\n\n    dotToken() {\n        return this.tokenizeFromWord('DOT', '.');\n    }\n\n    operatorToken() {\n        return this.tokenizeFromList('OPERATOR', SQL_OPERATORS);\n    }\n\n    mathToken() {\n        return this.tokenizeFromList('MATH', MATH) || this.tokenizeFromList('MATH_MULTI', MATH_MULTI);\n    }\n\n    conditionalToken() {\n        return this.tokenizeFromList('CONDITIONAL', SQL_CONDITIONALS);\n    }\n\n    betweenToken() {\n        return this.tokenizeFromList('BETWEEN', SQL_BETWEENS);\n    }\n\n    subSelectOpToken() {\n        return this.tokenizeFromList('SUB_SELECT_OP', SUB_SELECT_OP);\n    }\n\n    subSelectUnaryOpToken() {\n        return this.tokenizeFromList('SUB_SELECT_UNARY_OP', SUB_SELECT_UNARY_OP);\n    }\n\n    functionToken() {\n        return this.tokenizeFromList('FUNCTION', SQL_FUNCTIONS);\n    }\n\n    sortOrderToken() {\n        return this.tokenizeFromList('DIRECTION', SQL_SORT_ORDERS);\n    }\n\n    booleanToken() {\n        return this.tokenizeFromList('BOOLEAN', BOOLEAN);\n    }\n\n    starToken() {\n        return this.tokenizeFromRegex('STAR', STAR);\n    }\n\n    seperatorToken() {\n        return this.tokenizeFromRegex('SEPARATOR', SEPARATOR);\n    }\n\n    literalToken() {\n        return this.tokenizeFromRegex('LITERAL', LITERAL, 1, 0);\n    }\n\n    numberToken() {\n        return this.tokenizeFromRegex('NUMBER', NUMBER);\n    }\n\n    parameterToken() {\n        return this.tokenizeFromRegex('PARAMETER', PARAMETER, 1, 0);\n    }\n\n    stringToken() {\n        return this.tokenizeFromStringRegex('STRING', STRING, 1, 0) || this.tokenizeFromRegex('DBLSTRING', DBLSTRING, 1, 0);\n    }\n\n    parensToken() {\n        return this.tokenizeFromRegex('LEFT_PAREN', /^\\(/) || this.tokenizeFromRegex('RIGHT_PAREN', /^\\)/);\n    }\n\n    windowExtension() {\n        const match = /^\\.(win):(length|time)/i.exec(this.chunk);\n        if (!match) {\n            return 0;\n        }\n        this.token('WINDOW', match[1]);\n        this.token('WINDOW_FUNCTION', match[2]);\n        return match[0].length;\n    }\n\n    whitespaceToken() {\n        const match = WHITESPACE.exec(this.chunk);\n        if (!match) {\n            return 0;\n        }\n        const partMatch = match[0];\n        if (this.preserveWhitespace) {\n            this.token('WHITESPACE', partMatch);\n        }\n        const newlines = partMatch.match(/\\n/g, '');\n        this.currentLine += (newlines != null ? newlines.length : void 0) || 0;\n        return partMatch.length;\n    }\n\n    regexEscape(str) {\n        return str.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&');\n    }\n\n}\n\nexports.tokenize = function (sql, opts) {\n    return (new Lexer(sql, opts)).tokens;\n};\n","/* parser generated by jison 0.4.18 */\n/*\n  Returns a Parser object of the following structure:\n\n  Parser: {\n    yy: {}\n  }\n\n  Parser.prototype: {\n    yy: {},\n    trace: function(),\n    symbols_: {associative list: name ==> number},\n    terminals_: {associative list: number ==> name},\n    productions_: [...],\n    performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$),\n    table: [...],\n    defaultActions: {...},\n    parseError: function(str, hash),\n    parse: function(input),\n\n    lexer: {\n        EOF: 1,\n        parseError: function(str, hash),\n        setInput: function(input),\n        input: function(),\n        unput: function(str),\n        more: function(),\n        less: function(n),\n        pastInput: function(),\n        upcomingInput: function(),\n        showPosition: function(),\n        test_match: function(regex_match_array, rule_index),\n        next: function(),\n        lex: function(),\n        begin: function(condition),\n        popState: function(),\n        _currentRules: function(),\n        topState: function(),\n        pushState: function(condition),\n\n        options: {\n            ranges: boolean           (optional: true ==> token location info will include a .range[] member)\n            flex: boolean             (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match)\n            backtrack_lexer: boolean  (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code)\n        },\n\n        performAction: function(yy, yy_, $avoiding_name_collisions, YY_START),\n        rules: [...],\n        conditions: {associative list: name ==> set},\n    }\n  }\n\n\n  token location info (@$, _$, etc.): {\n    first_line: n,\n    last_line: n,\n    first_column: n,\n    last_column: n,\n    range: [start_number, end_number]       (where the numbers are indexes into the input string, regular zero-based)\n  }\n\n\n  the parseError function receives a 'hash' object with these members for lexer and parser errors: {\n    text:        (matched text)\n    token:       (the produced terminal token, if any)\n    line:        (yylineno)\n  }\n  while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: {\n    loc:         (yylloc)\n    expected:    (string describing the set of expected tokens)\n    recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error)\n  }\n*/\nvar parser = (function(){\nvar o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,8],$V1=[5,26],$V2=[1,14],$V3=[1,13],$V4=[5,26,31,42],$V5=[1,17],$V6=[5,26,31,42,45,62],$V7=[1,27],$V8=[1,29],$V9=[1,40],$Va=[1,42],$Vb=[1,46],$Vc=[1,47],$Vd=[1,43],$Ve=[1,44],$Vf=[1,41],$Vg=[1,45],$Vh=[1,25],$Vi=[5,26,31],$Vj=[5,26,31,42,45],$Vk=[1,59],$Vl=[18,43],$Vm=[1,62],$Vn=[1,63],$Vo=[1,64],$Vp=[1,65],$Vq=[1,66],$Vr=[5,18,23,26,31,34,37,38,41,42,43,45,62,64,65,66,67,68,70,78,81,82,83],$Vs=[5,18,23,26,31,34,37,38,41,42,43,44,45,51,62,64,65,66,67,68,70,71,78,81,82,83,89,90,91,92,93,94,96],$Vt=[1,74],$Vu=[1,77],$Vv=[2,93],$Vw=[1,91],$Vx=[1,92],$Vy=[5,18,23,26,31,34,37,38,41,42,43,45,62,64,65,66,67,68,70,78,81,82,83,89,90,91,92,93,94,96],$Vz=[78,81,83],$VA=[1,116],$VB=[5,26,31,42,43,44],$VC=[1,124],$VD=[5,26,31,42,43,45,64],$VE=[5,26,31,41,42,45,62],$VF=[1,127],$VG=[1,128],$VH=[1,129],$VI=[5,26,31,34,35,37,38,41,42,45,62],$VJ=[5,18,23,26,31,34,37,38,41,42,43,45,62,64,70,78,81,82,83],$VK=[5,26,31,34,37,38,41,42,45,62],$VL=[5,26,31,42,56,58];\nvar parser = {trace: function trace () { },\nyy: {},\nsymbols_: {\"error\":2,\"Root\":3,\"Query\":4,\"EOF\":5,\"SelectQuery\":6,\"Unions\":7,\"SelectWithLimitQuery\":8,\"BasicSelectQuery\":9,\"Select\":10,\"OrderClause\":11,\"GroupClause\":12,\"LimitClause\":13,\"SelectClause\":14,\"WhereClause\":15,\"SELECT\":16,\"Fields\":17,\"FROM\":18,\"Table\":19,\"DISTINCT\":20,\"Joins\":21,\"Literal\":22,\"AS\":23,\"LEFT_PAREN\":24,\"List\":25,\"RIGHT_PAREN\":26,\"WINDOW\":27,\"WINDOW_FUNCTION\":28,\"Number\":29,\"Union\":30,\"UNION\":31,\"ALL\":32,\"Join\":33,\"JOIN\":34,\"ON\":35,\"Expression\":36,\"LEFT\":37,\"RIGHT\":38,\"INNER\":39,\"OUTER\":40,\"WHERE\":41,\"LIMIT\":42,\"SEPARATOR\":43,\"OFFSET\":44,\"ORDER\":45,\"BY\":46,\"OrderArgs\":47,\"OffsetClause\":48,\"OrderArg\":49,\"Value\":50,\"DIRECTION\":51,\"OffsetRows\":52,\"FetchClause\":53,\"ROW\":54,\"ROWS\":55,\"FETCH\":56,\"FIRST\":57,\"ONLY\":58,\"NEXT\":59,\"GroupBasicClause\":60,\"HavingClause\":61,\"GROUP\":62,\"ArgumentList\":63,\"HAVING\":64,\"MATH\":65,\"MATH_MULTI\":66,\"OPERATOR\":67,\"BETWEEN\":68,\"BetweenExpression\":69,\"CONDITIONAL\":70,\"SUB_SELECT_OP\":71,\"SubSelectExpression\":72,\"SUB_SELECT_UNARY_OP\":73,\"WhitepaceList\":74,\"CaseStatement\":75,\"CASE\":76,\"CaseWhens\":77,\"END\":78,\"CaseElse\":79,\"CaseWhen\":80,\"WHEN\":81,\"THEN\":82,\"ELSE\":83,\"String\":84,\"Function\":85,\"UserFunction\":86,\"Boolean\":87,\"Parameter\":88,\"NUMBER\":89,\"BOOLEAN\":90,\"PARAMETER\":91,\"STRING\":92,\"DBLSTRING\":93,\"LITERAL\":94,\"DOT\":95,\"FUNCTION\":96,\"AggregateArgumentList\":97,\"Case\":98,\"Field\":99,\"STAR\":100,\"$accept\":0,\"$end\":1},\nterminals_: {2:\"error\",5:\"EOF\",16:\"SELECT\",18:\"FROM\",20:\"DISTINCT\",23:\"AS\",24:\"LEFT_PAREN\",26:\"RIGHT_PAREN\",27:\"WINDOW\",28:\"WINDOW_FUNCTION\",31:\"UNION\",32:\"ALL\",34:\"JOIN\",35:\"ON\",37:\"LEFT\",38:\"RIGHT\",39:\"INNER\",40:\"OUTER\",41:\"WHERE\",42:\"LIMIT\",43:\"SEPARATOR\",44:\"OFFSET\",45:\"ORDER\",46:\"BY\",51:\"DIRECTION\",54:\"ROW\",55:\"ROWS\",56:\"FETCH\",57:\"FIRST\",58:\"ONLY\",59:\"NEXT\",62:\"GROUP\",64:\"HAVING\",65:\"MATH\",66:\"MATH_MULTI\",67:\"OPERATOR\",68:\"BETWEEN\",70:\"CONDITIONAL\",71:\"SUB_SELECT_OP\",73:\"SUB_SELECT_UNARY_OP\",76:\"CASE\",78:\"END\",81:\"WHEN\",82:\"THEN\",83:\"ELSE\",89:\"NUMBER\",90:\"BOOLEAN\",91:\"PARAMETER\",92:\"STRING\",93:\"DBLSTRING\",94:\"LITERAL\",95:\"DOT\",96:\"FUNCTION\",98:\"Case\",100:\"STAR\"},\nproductions_: [0,[3,2],[4,1],[4,2],[6,1],[6,1],[9,1],[9,2],[9,2],[9,3],[8,2],[10,1],[10,2],[14,4],[14,5],[14,5],[14,6],[19,1],[19,2],[19,3],[19,3],[19,3],[19,4],[19,6],[7,1],[7,2],[30,2],[30,3],[21,1],[21,2],[33,4],[33,5],[33,5],[33,6],[33,6],[33,6],[33,6],[15,2],[13,2],[13,4],[13,4],[11,3],[11,4],[47,1],[47,3],[49,1],[49,2],[48,2],[48,3],[52,2],[52,2],[53,4],[53,4],[12,1],[12,2],[60,3],[61,2],[36,3],[36,3],[36,3],[36,3],[36,3],[36,3],[36,5],[36,3],[36,2],[36,1],[36,1],[36,1],[36,1],[69,3],[75,3],[75,4],[80,4],[77,2],[77,1],[79,2],[72,3],[50,1],[50,1],[50,1],[50,1],[50,1],[50,1],[50,1],[74,2],[74,2],[25,1],[29,1],[87,1],[88,1],[84,1],[84,1],[22,1],[22,3],[85,4],[86,3],[86,4],[86,4],[97,1],[97,2],[63,1],[63,3],[17,1],[17,3],[99,1],[99,1],[99,3]],\nperformAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {\n/* this == yyval */\n\nvar $0 = $$.length - 1;\nswitch (yystate) {\ncase 1:\nreturn this.$ = $$[$0-1];\nbreak;\ncase 2: case 4: case 5: case 6: case 11: case 53: case 66: case 68: case 69: case 78: case 79: case 80: case 81: case 82: case 83: case 84:\nthis.$ = $$[$0];\nbreak;\ncase 3:\nthis.$ = (function(){ $$[$0-1].unions = $$[$0]; return $$[$0-1]; }());\nbreak;\ncase 7:\nthis.$ = (function(){ $$[$0-1].order = $$[$0]; return $$[$0-1]; }());\nbreak;\ncase 8:\nthis.$ = (function(){ $$[$0-1].group = $$[$0]; return $$[$0-1]; }());\nbreak;\ncase 9:\nthis.$ = (function(){ $$[$0-2].group = $$[$0-1]; $$[$0-2].order = $$[$0]; return $$[$0-2]; }());\nbreak;\ncase 10:\nthis.$ = (function(){ $$[$0-1].limit = $$[$0]; return $$[$0-1]; }());\nbreak;\ncase 12:\nthis.$ = (function(){ $$[$0-1].where = $$[$0]; return $$[$0-1]; }());\nbreak;\ncase 13:\nthis.$ = new yy.Select($$[$0-2], $$[$0], false);\nbreak;\ncase 14:\nthis.$ = new yy.Select($$[$0-2], $$[$0], true);\nbreak;\ncase 15:\nthis.$ = new yy.Select($$[$0-3], $$[$0-1], false, $$[$0]);\nbreak;\ncase 16:\nthis.$ = new yy.Select($$[$0-3], $$[$0-1], true, $$[$0]);\nbreak;\ncase 17:\nthis.$ = new yy.Table($$[$0]);\nbreak;\ncase 18:\nthis.$ = new yy.Table($$[$0-1], $$[$0]);\nbreak;\ncase 19:\nthis.$ = new yy.Table($$[$0-2], $$[$0]);\nbreak;\ncase 20: case 49: case 50: case 51: case 52: case 57:\nthis.$ = $$[$0-1];\nbreak;\ncase 21: case 77:\nthis.$ = new yy.SubSelect($$[$0-1]);\nbreak;\ncase 22:\nthis.$ = new yy.SubSelect($$[$0-2], $$[$0]);\nbreak;\ncase 23:\nthis.$ = new yy.Table($$[$0-5], null, $$[$0-4], $$[$0-3], $$[$0-1]);\nbreak;\ncase 24: case 28: case 43: case 75: case 101: case 103:\nthis.$ = [$$[$0]];\nbreak;\ncase 25: case 29: case 74:\nthis.$ = $$[$0-1].concat($$[$0]);\nbreak;\ncase 26:\nthis.$ = new yy.Union($$[$0]);\nbreak;\ncase 27:\nthis.$ = new yy.Union($$[$0], true);\nbreak;\ncase 30:\nthis.$ = new yy.Join($$[$0-2], $$[$0]);\nbreak;\ncase 31:\nthis.$ = new yy.Join($$[$0-2], $$[$0], 'LEFT');\nbreak;\ncase 32:\nthis.$ = new yy.Join($$[$0-2], $$[$0], 'RIGHT');\nbreak;\ncase 33:\nthis.$ = new yy.Join($$[$0-2], $$[$0], 'LEFT', 'INNER');\nbreak;\ncase 34:\nthis.$ = new yy.Join($$[$0-2], $$[$0], 'RIGHT', 'INNER');\nbreak;\ncase 35:\nthis.$ = new yy.Join($$[$0-2], $$[$0], 'LEFT', 'OUTER');\nbreak;\ncase 36:\nthis.$ = new yy.Join($$[$0-2], $$[$0], 'RIGHT', 'OUTER');\nbreak;\ncase 37:\nthis.$ = new yy.Where($$[$0]);\nbreak;\ncase 38:\nthis.$ = new yy.Limit($$[$0]);\nbreak;\ncase 39:\nthis.$ = new yy.Limit($$[$0], $$[$0-2]);\nbreak;\ncase 40:\nthis.$ = new yy.Limit($$[$0-2], $$[$0]);\nbreak;\ncase 41:\nthis.$ = new yy.Order($$[$0]);\nbreak;\ncase 42:\nthis.$ = new yy.Order($$[$0-1], $$[$0]);\nbreak;\ncase 44: case 102: case 104:\nthis.$ = $$[$0-2].concat($$[$0]);\nbreak;\ncase 45:\nthis.$ = new yy.OrderArgument($$[$0], 'ASC');\nbreak;\ncase 46:\nthis.$ = new yy.OrderArgument($$[$0-1], $$[$0]);\nbreak;\ncase 47:\nthis.$ = new yy.Offset($$[$0]);\nbreak;\ncase 48:\nthis.$ = new yy.Offset($$[$0-1], $$[$0]);\nbreak;\ncase 54:\nthis.$ = (function(){ $$[$0-1].having = $$[$0]; return $$[$0-1]; }());\nbreak;\ncase 55:\nthis.$ = new yy.Group($$[$0]);\nbreak;\ncase 56:\nthis.$ = new yy.Having($$[$0]);\nbreak;\ncase 58: case 59: case 60: case 61: case 62: case 64:\nthis.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]);\nbreak;\ncase 63:\nthis.$ = new yy.Op($$[$0-3], $$[$0-4], $$[$0-1]);\nbreak;\ncase 65:\nthis.$ = new yy.UnaryOp($$[$0-1], $$[$0]);\nbreak;\ncase 67:\nthis.$ = new yy.WhitepaceList($$[$0]);\nbreak;\ncase 70:\nthis.$ = new yy.BetweenOp([$$[$0-2], $$[$0]]);\nbreak;\ncase 71:\nthis.$ = new yy.Case($$[$0-1]);\nbreak;\ncase 72:\nthis.$ = new yy.Case($$[$0-2], $$[$0-1]);\nbreak;\ncase 73:\nthis.$ = new yy.CaseWhen($$[$0-2], $$[$0]);\nbreak;\ncase 76:\nthis.$ = new yy.CaseElse($$[$0]);\nbreak;\ncase 85:\nthis.$ = [$$[$0-1], $$[$0]];\nbreak;\ncase 86:\nthis.$ = (function(){ $$[$0-1].push($$[$0]); return $$[$0-1]; }());\nbreak;\ncase 87:\nthis.$ = new yy.ListValue($$[$0]);\nbreak;\ncase 88:\nthis.$ = new yy.NumberValue($$[$0]);\nbreak;\ncase 89:\nthis.$ = new yy.BooleanValue($$[$0]);\nbreak;\ncase 90:\nthis.$ = new yy.ParameterValue($$[$0]);\nbreak;\ncase 91:\nthis.$ = new yy.StringValue($$[$0], \"'\");\nbreak;\ncase 92:\nthis.$ = new yy.StringValue($$[$0], '\"');\nbreak;\ncase 93:\nthis.$ = new yy.LiteralValue($$[$0]);\nbreak;\ncase 94:\nthis.$ = new yy.LiteralValue($$[$0-2], $$[$0]);\nbreak;\ncase 95:\nthis.$ = new yy.FunctionValue($$[$0-3], $$[$0-1]);\nbreak;\ncase 96:\nthis.$ = new yy.FunctionValue($$[$0-2], null, true);\nbreak;\ncase 97: case 98:\nthis.$ = new yy.FunctionValue($$[$0-3], $$[$0-1], true);\nbreak;\ncase 99:\nthis.$ = new yy.ArgumentListValue($$[$0]);\nbreak;\ncase 100:\nthis.$ = new yy.ArgumentListValue($$[$0], true);\nbreak;\ncase 105:\nthis.$ = new yy.Star();\nbreak;\ncase 106:\nthis.$ = new yy.Field($$[$0]);\nbreak;\ncase 107:\nthis.$ = new yy.Field($$[$0-2], $$[$0]);\nbreak;\n}\n},\ntable: [{3:1,4:2,6:3,8:4,9:5,10:6,14:7,16:$V0},{1:[3]},{5:[1,9]},o($V1,[2,2],{7:10,13:11,30:12,31:$V2,42:$V3}),o($V4,[2,4]),o($V4,[2,5]),o($V4,[2,6],{11:15,12:16,60:18,45:$V5,62:[1,19]}),o($V6,[2,11],{15:20,41:[1,21]}),{17:22,20:[1,23],22:33,24:$V7,29:34,36:26,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg,99:24,100:$Vh},{1:[2,1]},o($V1,[2,3],{30:48,31:$V2}),o($V4,[2,10]),o($Vi,[2,24]),{29:49,89:$Va},{6:50,8:4,9:5,10:6,14:7,16:$V0,32:[1,51]},o($V4,[2,7]),o($V4,[2,8],{11:52,45:$V5}),{46:[1,53]},o($Vj,[2,53],{61:54,64:[1,55]}),{46:[1,56]},o($V6,[2,12]),{22:33,24:$V7,29:34,36:57,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{18:[1,58],43:$Vk},{17:60,22:33,24:$V7,29:34,36:26,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg,99:24,100:$Vh},o($Vl,[2,103]),o($Vl,[2,105]),o($Vl,[2,106],{23:[1,61],65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq}),{4:68,6:3,8:4,9:5,10:6,14:7,16:$V0,22:33,24:$V7,29:34,36:67,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},o($Vr,[2,69],{22:33,29:34,84:35,85:36,86:37,87:38,88:39,50:70,71:[1,69],89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg}),{24:[1,72],72:71},o($Vr,[2,66]),o($Vr,[2,67],{22:33,29:34,84:35,85:36,86:37,87:38,88:39,50:73,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg}),o($Vr,[2,68]),o($Vs,[2,78],{95:$Vt}),o($Vs,[2,79]),o($Vs,[2,80]),o($Vs,[2,81]),o($Vs,[2,82]),o($Vs,[2,83]),o($Vs,[2,84]),{77:75,80:76,81:$Vu},o([5,18,23,26,31,34,37,38,41,42,43,44,45,51,62,64,65,66,67,68,70,71,78,81,82,83,89,90,91,92,93,94,95,96],$Vv,{24:[1,78]}),o([5,18,23,26,31,34,37,38,41,42,43,44,45,51,54,55,62,64,65,66,67,68,70,71,78,81,82,83,89,90,91,92,93,94,96],[2,88]),o($Vs,[2,91]),o($Vs,[2,92]),{24:[1,79]},o($Vs,[2,89]),o($Vs,[2,90]),o($Vi,[2,25]),o($V4,[2,38],{43:[1,80],44:[1,81]}),o($Vi,[2,26],{13:11,42:$V3}),{6:82,8:4,9:5,10:6,14:7,16:$V0},o($V4,[2,9]),{22:33,29:34,47:83,49:84,50:85,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},o($Vj,[2,54]),{22:33,24:$V7,29:34,36:86,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{22:33,24:$V7,29:34,36:88,50:28,63:87,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},o($V6,[2,37],{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq}),{19:89,22:90,24:$Vw,94:$Vx},{22:33,24:$V7,29:34,36:26,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg,99:93,100:$Vh},{18:[1,94],43:$Vk},{22:95,94:$Vx},{22:33,24:$V7,29:34,36:96,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{22:33,24:$V7,29:34,36:97,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{22:33,24:$V7,29:34,36:98,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{22:33,24:$V7,29:34,36:100,50:28,69:99,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{22:33,24:$V7,29:34,36:101,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{26:[1,102],65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq},{26:[1,103]},{24:[1,104],72:105},o($Vy,[2,85]),o($Vr,[2,65]),{4:68,6:3,8:4,9:5,10:6,14:7,16:$V0},o($Vy,[2,86]),{94:[1,106]},{78:[1,107],79:108,80:109,81:$Vu,83:[1,110]},o($Vz,[2,75]),{22:33,24:$V7,29:34,36:111,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{20:$VA,22:33,24:$V7,26:[1,112],29:34,36:88,50:28,63:115,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg,97:113,98:[1,114]},{20:$VA,22:33,24:$V7,29:34,36:88,50:28,63:115,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg,97:117},{29:118,89:$Va},{29:119,89:$Va},o($Vi,[2,27],{13:11,42:$V3}),o($V4,[2,41],{48:120,43:[1,121],44:[1,122]}),o($VB,[2,43]),o($VB,[2,45],{51:[1,123]}),o($Vj,[2,56],{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq}),o([5,26,31,42,45,64],[2,55],{43:$VC}),o($VD,[2,101],{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq}),o($VE,[2,13],{21:125,33:126,34:$VF,37:$VG,38:$VH}),o($VI,[2,17],{22:130,23:[1,131],27:[1,132],94:$Vx,95:$Vt}),{4:134,6:3,8:4,9:5,10:6,14:7,16:$V0,22:33,24:$V7,25:133,29:34,36:88,50:28,63:135,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},o([5,18,23,26,27,31,34,35,37,38,41,42,43,45,62,94,95],$Vv),o($Vl,[2,104]),{19:136,22:90,24:$Vw,94:$Vx},o($Vl,[2,107],{95:$Vt}),o([5,18,23,26,31,34,37,38,41,42,43,45,62,64,65,67,70,78,81,82,83],[2,58],{66:$Vn,68:$Vp}),o([5,18,23,26,31,34,37,38,41,42,43,45,62,64,65,66,67,70,78,81,82,83],[2,59],{68:$Vp}),o([5,18,23,26,31,34,37,38,41,42,43,45,62,64,67,70,78,81,82,83],[2,60],{65:$Vm,66:$Vn,68:$Vp}),o($Vr,[2,61]),{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:[1,137]},o($VJ,[2,62],{65:$Vm,66:$Vn,67:$Vo,68:$Vp}),o($Vr,[2,57]),o($Vr,[2,77]),{4:68,6:3,8:4,9:5,10:6,14:7,16:$V0,22:33,24:$V7,25:138,29:34,36:88,50:28,63:135,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},o($Vr,[2,64]),o([5,18,23,26,27,31,34,35,37,38,41,42,43,44,45,51,62,64,65,66,67,68,70,71,78,81,82,83,89,90,91,92,93,94,95,96],[2,94]),o($Vr,[2,71]),{78:[1,139]},o($Vz,[2,74]),{22:33,24:$V7,29:34,36:140,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq,82:[1,141]},o($Vs,[2,96]),{26:[1,142]},{26:[1,143]},{26:[2,99],43:$VC},{22:33,24:$V7,29:34,36:88,50:28,63:144,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{26:[1,145]},o($V4,[2,39]),o($V4,[2,40]),o($V4,[2,42]),{22:33,29:34,49:146,50:85,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{29:148,52:147,89:$Va},o($VB,[2,46]),{22:33,24:$V7,29:34,36:149,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},o($VE,[2,15],{33:150,34:$VF,37:$VG,38:$VH}),o($VK,[2,28]),{19:151,22:90,24:$Vw,94:$Vx},{34:[1,152],39:[1,153],40:[1,154]},{34:[1,155],39:[1,156],40:[1,157]},o($VI,[2,18],{95:$Vt}),{22:158,94:$Vx},{28:[1,159]},{26:[1,160]},{26:[1,161]},{26:[2,87],43:$VC},o($VE,[2,14],{33:126,21:162,34:$VF,37:$VG,38:$VH}),{22:33,24:$V7,29:34,36:163,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{26:[1,164]},o($Vr,[2,72]),{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq,78:[2,76]},{22:33,24:$V7,29:34,36:165,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},o($Vs,[2,97]),o($Vs,[2,98]),{26:[2,100],43:$VC},o($Vs,[2,95]),o($VB,[2,44]),o($V4,[2,47],{53:166,56:[1,167]}),{54:[1,168],55:[1,169]},o($VD,[2,102],{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq}),o($VK,[2,29]),{35:[1,170]},{19:171,22:90,24:$Vw,94:$Vx},{34:[1,172]},{34:[1,173]},{19:174,22:90,24:$Vw,94:$Vx},{34:[1,175]},{34:[1,176]},o($VI,[2,19],{95:$Vt}),{24:[1,177]},o($VI,[2,20]),o($VI,[2,21],{22:178,94:$Vx}),o($VE,[2,16],{33:150,34:$VF,37:$VG,38:$VH}),o($VJ,[2,70],{65:$Vm,66:$Vn,67:$Vo,68:$Vp}),o($Vr,[2,63]),o($Vz,[2,73],{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq}),o($V4,[2,48]),{57:[1,179],59:[1,180]},o($VL,[2,49]),o($VL,[2,50]),{22:33,24:$V7,29:34,36:181,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{35:[1,182]},{19:183,22:90,24:$Vw,94:$Vx},{19:184,22:90,24:$Vw,94:$Vx},{35:[1,185]},{19:186,22:90,24:$Vw,94:$Vx},{19:187,22:90,24:$Vw,94:$Vx},{29:188,89:$Va},o($VI,[2,22],{95:$Vt}),{29:148,52:189,89:$Va},{29:148,52:190,89:$Va},o($VK,[2,30],{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq}),{22:33,24:$V7,29:34,36:191,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{35:[1,192]},{35:[1,193]},{22:33,24:$V7,29:34,36:194,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{35:[1,195]},{35:[1,196]},{26:[1,197]},{58:[1,198]},{58:[1,199]},o($VK,[2,31],{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq}),{22:33,24:$V7,29:34,36:200,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{22:33,24:$V7,29:34,36:201,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},o($VK,[2,32],{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq}),{22:33,24:$V7,29:34,36:202,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{22:33,24:$V7,29:34,36:203,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},o($VI,[2,23]),o($V4,[2,51]),o($V4,[2,52]),o($VK,[2,33],{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq}),o($VK,[2,35],{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq}),o($VK,[2,34],{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq}),o($VK,[2,36],{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq})],\ndefaultActions: {9:[2,1]},\nparseError: function parseError (str, hash) {\n    if (hash.recoverable) {\n        this.trace(str);\n    } else {\n        var error = new Error(str);\n        error.hash = hash;\n        throw error;\n    }\n},\nparse: function parse(input) {\n    var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;\n    var args = lstack.slice.call(arguments, 1);\n    var lexer = Object.create(this.lexer);\n    var sharedState = { yy: {} };\n    for (var k in this.yy) {\n        if (Object.prototype.hasOwnProperty.call(this.yy, k)) {\n            sharedState.yy[k] = this.yy[k];\n        }\n    }\n    lexer.setInput(input, sharedState.yy);\n    sharedState.yy.lexer = lexer;\n    sharedState.yy.parser = this;\n    if (typeof lexer.yylloc == 'undefined') {\n        lexer.yylloc = {};\n    }\n    var yyloc = lexer.yylloc;\n    lstack.push(yyloc);\n    var ranges = lexer.options && lexer.options.ranges;\n    if (typeof sharedState.yy.parseError === 'function') {\n        this.parseError = sharedState.yy.parseError;\n    } else {\n        this.parseError = Object.getPrototypeOf(this).parseError;\n    }\n    function popStack(n) {\n        stack.length = stack.length - 2 * n;\n        vstack.length = vstack.length - n;\n        lstack.length = lstack.length - n;\n    }\n    _token_stack:\n        var lex = function () {\n            var token;\n            token = lexer.lex() || EOF;\n            if (typeof token !== 'number') {\n                token = self.symbols_[token] || token;\n            }\n            return token;\n        };\n    var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;\n    while (true) {\n        state = stack[stack.length - 1];\n        if (this.defaultActions[state]) {\n            action = this.defaultActions[state];\n        } else {\n            if (symbol === null || typeof symbol == 'undefined') {\n                symbol = lex();\n            }\n            action = table[state] && table[state][symbol];\n        }\n                    if (typeof action === 'undefined' || !action.length || !action[0]) {\n                var errStr = '';\n                expected = [];\n                for (p in table[state]) {\n                    if (this.terminals_[p] && p > TERROR) {\n                        expected.push('\\'' + this.terminals_[p] + '\\'');\n                    }\n                }\n                if (lexer.showPosition) {\n                    errStr = 'Parse error on line ' + (yylineno + 1) + ':\\n' + lexer.showPosition() + '\\nExpecting ' + expected.join(', ') + ', got \\'' + (this.terminals_[symbol] || symbol) + '\\'';\n                } else {\n                    errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\\'' + (this.terminals_[symbol] || symbol) + '\\'');\n                }\n                this.parseError(errStr, {\n                    text: lexer.match,\n                    token: this.terminals_[symbol] || symbol,\n                    line: lexer.yylineno,\n                    loc: yyloc,\n                    expected: expected\n                });\n            }\n        if (action[0] instanceof Array && action.length > 1) {\n            throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol);\n        }\n        switch (action[0]) {\n        case 1:\n            stack.push(symbol);\n            vstack.push(lexer.yytext);\n            lstack.push(lexer.yylloc);\n            stack.push(action[1]);\n            symbol = null;\n            if (!preErrorSymbol) {\n                yyleng = lexer.yyleng;\n                yytext = lexer.yytext;\n                yylineno = lexer.yylineno;\n                yyloc = lexer.yylloc;\n                if (recovering > 0) {\n                    recovering--;\n                }\n            } else {\n                symbol = preErrorSymbol;\n                preErrorSymbol = null;\n            }\n            break;\n        case 2:\n            len = this.productions_[action[1]][1];\n            yyval.$ = vstack[vstack.length - len];\n            yyval._$ = {\n                first_line: lstack[lstack.length - (len || 1)].first_line,\n                last_line: lstack[lstack.length - 1].last_line,\n                first_column: lstack[lstack.length - (len || 1)].first_column,\n                last_column: lstack[lstack.length - 1].last_column\n            };\n            if (ranges) {\n                yyval._$.range = [\n                    lstack[lstack.length - (len || 1)].range[0],\n                    lstack[lstack.length - 1].range[1]\n                ];\n            }\n            r = this.performAction.apply(yyval, [\n                yytext,\n                yyleng,\n                yylineno,\n                sharedState.yy,\n                action[1],\n                vstack,\n                lstack\n            ].concat(args));\n            if (typeof r !== 'undefined') {\n                return r;\n            }\n            if (len) {\n                stack = stack.slice(0, -1 * len * 2);\n                vstack = vstack.slice(0, -1 * len);\n                lstack = lstack.slice(0, -1 * len);\n            }\n            stack.push(this.productions_[action[1]][0]);\n            vstack.push(yyval.$);\n            lstack.push(yyval._$);\n            newState = table[stack[stack.length - 2]][stack[stack.length - 1]];\n            stack.push(newState);\n            break;\n        case 3:\n            return true;\n        }\n    }\n    return true;\n}};\n\nfunction Parser () {\n  this.yy = {};\n}\nParser.prototype = parser;parser.Parser = Parser;\nreturn new Parser;\n})();\n\nexports.parser = parser;","function indent(str) {\n    return ((function () {\n        const ref = str.split('\\n');\n        const results = [];\n        for (let i = 0, len = ref.length; i < len; i++) {\n            results.push(`  ${ref[i]}`);\n        }\n        return results;\n    })()).join('\\n');\n}\n\nexports.Select = class Select {\n    constructor(fields, source, distinct = false, joins = [], unions = []) {\n        this.fields = fields;\n        this.source = source;\n        this.distinct = distinct;\n        this.joins = joins;\n        this.unions = unions;\n        this.order = null;\n        this.group = null;\n        this.where = null;\n        this.limit = null;\n    }\n\n    toString() {\n        const ret = [`SELECT ${this.fields.join(', ')}`];\n        ret.push(indent(`FROM ${this.source}`));\n        for (let i = 0, len = this.joins.length; i < len; i++) {\n            ret.push(indent(this.joins[i].toString()));\n        }\n        if (this.where) {\n            ret.push(indent(this.where.toString()));\n        }\n        if (this.group) {\n            ret.push(indent(this.group.toString()));\n        }\n        if (this.order) {\n            ret.push(indent(this.order.toString()));\n        }\n        if (this.limit) {\n            ret.push(indent(this.limit.toString()));\n        }\n        for (let j = 0, len1 = this.unions.length; j < len1; j++) {\n            ret.push(this.unions[j].toString());\n        }\n        return ret.join('\\n');\n    }\n};\n\nexports.SubSelect = class SubSelect {\n    constructor(select, name = null) {\n        this.select = select;\n        this.name = name;\n    }\n\n    toString() {\n        const ret = [];\n        ret.push('(');\n        ret.push(indent(this.select.toString()));\n        ret.push(this.name ? `) ${this.name.toString()}` : ')');\n        return ret.join('\\n');\n    }\n};\n\nexports.Join = class Join {\n    constructor(right, conditions = null, side = null, mode = null) {\n        this.right = right;\n        this.conditions = conditions;\n        this.side = side;\n        this.mode = mode;\n    }\n\n    toString() {\n        let ret = '';\n        if (this.side != null) {\n            ret += `${this.side} `;\n        }\n        if (this.mode != null) {\n            ret += `${this.mode} `;\n        }\n        return ret + `JOIN ${this.right}\\n` + indent(`ON ${this.conditions}`);\n    }\n};\n\nexports.Union = class Union {\n    constructor(query, all1 = false) {\n        this.query = query;\n        this.all = all1;\n    }\n\n    toString() {\n        const all = this.all ? ' ALL' : '';\n        return `UNION${all}\\n${this.query.toString()}`;\n    }\n};\n\nexports.LiteralValue = class LiteralValue {\n    constructor(value1, value2 = null) {\n        this.value = value1;\n        this.value2 = value2;\n        if (this.value2) {\n            this.nested = true;\n            this.values = this.value.values;\n            this.values.push(this.value2);\n        }\n        else {\n            this.nested = false;\n            this.values = [this.value];\n        }\n    }\n\n    // TODO: Backtick quotes only supports MySQL, Postgres uses double-quotes\n    toString(quote = true) {\n        if (quote) {\n            return `\\`${this.values.join('`.`')}\\``;\n        }\n        else {\n            return `${this.values.join('.')}`;\n        }\n    }\n};\n\nexports.StringValue = class StringValue {\n    constructor(value1, quoteType = '\\'\\'') {\n        this.value = value1;\n        this.quoteType = quoteType;\n    }\n\n    toString() {\n        const escaped = this.quoteType === '\\'' ? this.value.replace(/(^|[^\\\\])'/g, '$1\\'\\'') : this.value;\n        return `${this.quoteType}${escaped}${this.quoteType}`;\n    }\n};\n\nexports.NumberValue = class NumberValue {\n    constructor(value) {\n        this.value = Number(value);\n    }\n\n    toString() {\n        return this.value.toString();\n    }\n};\n\nexports.ListValue = class ListValue {\n    constructor(value1) {\n        this.value = value1;\n    }\n\n    toString() {\n        return `(${this.value.join(', ')})`;\n    }\n};\n\nexports.WhitepaceList = class WhitepaceList {\n    constructor(value1) {\n        this.value = value1;\n    }\n\n    toString() {\n        // not backtick for literals\n        return this.value.map(function (value) {\n            if (value instanceof exports.LiteralValue) {\n                return value.toString(false);\n            }\n            else {\n                return value.toString();\n            }\n        }).join(' ');\n    }\n};\n\nexports.ParameterValue = class ParameterValue {\n    constructor(value) {\n        this.value = value;\n        this.index = parseInt(value.substr(1), 10) - 1;\n    }\n\n    toString() {\n        return `$${this.value}`;\n    }\n};\n\nexports.ArgumentListValue = class ArgumentListValue {\n    constructor(value1, distinct = false) {\n        this.value = value1;\n        this.distinct = distinct;\n    }\n\n    toString() {\n        if (this.distinct) {\n            return `DISTINCT ${this.value.join(', ')}`;\n        }\n        else {\n            return `${this.value.join(', ')}`;\n        }\n    }\n};\n\nexports.BooleanValue = class LiteralValue {\n    constructor(value) {\n        this.value = (function () {\n            switch (value.toLowerCase()) {\n                case 'true':\n                    return true;\n                case 'false':\n                    return false;\n                default:\n                    return null;\n            }\n        })();\n    }\n\n    toString() {\n        if (this.value != null) {\n            return this.value.toString().toUpperCase();\n        }\n        else {\n            return 'NULL';\n        }\n    }\n};\n\nexports.FunctionValue = class FunctionValue {\n    constructor(name, _arguments = null, udf = false) {\n        this.name = name;\n        this.arguments = _arguments;\n        this.udf = udf;\n    }\n\n    toString() {\n        if (this.arguments) {\n            return `${this.name.toUpperCase()}(${this.arguments.toString()})`;\n        }\n        else {\n            return `${this.name.toUpperCase()}()`;\n        }\n    }\n};\n\nexports.Case = class Case {\n    constructor(whens, _else) {\n        this.whens = whens;\n        this.else = _else;\n    }\n\n    toString() {\n        const whensStr = this.whens.map(function (w) {\n            return w.toString();\n        }).join(' ');\n        if (this.else) {\n            return `CASE ${whensStr} ${this.else.toString()} END`;\n        }\n        else {\n            return `CASE ${whensStr} END`;\n        }\n    }\n};\n\nexports.CaseWhen = class CaseWhen {\n    constructor(whenCondition, resCondition) {\n        this.whenCondition = whenCondition;\n        this.resCondition = resCondition;\n    }\n\n    toString() {\n        return `WHEN ${this.whenCondition} THEN ${this.resCondition}`;\n    }\n};\n\nexports.CaseElse = class CaseElse {\n    constructor(elseCondition) {\n        this.elseCondition = elseCondition;\n    }\n\n    toString() {\n        return `ELSE ${this.elseCondition}`;\n    }\n};\n\nexports.Order = class Order {\n    constructor(orderings, offset) {\n        this.orderings = orderings;\n        this.offset = offset;\n    }\n\n    toString() {\n        return `ORDER BY ${this.orderings.join(', ')}` + (this.offset ? '\\n' + this.offset.toString() : '');\n    }\n};\n\nexports.OrderArgument = class OrderArgument {\n    constructor(value, direction = 'ASC') {\n        this.value = value;\n        this.direction = direction;\n        null;\n    }\n\n    toString() {\n        return `${this.value} ${this.direction}`;\n    }\n};\n\nexports.Offset = class Offset {\n    constructor(row_count, limit) {\n        this.row_count = row_count;\n        this.limit = limit;\n    }\n\n    toString() {\n        return `OFFSET ${this.row_count} ROWS` + (this.limit ? `\\nFETCH NEXT ${this.limit} ROWS ONLY` : '');\n    }\n};\n\nexports.Limit = class Limit {\n    constructor(value1, offset) {\n        this.value = value1;\n        this.offset = offset;\n    }\n\n    toString() {\n        return `LIMIT ${this.value}` + (this.offset ? `\\nOFFSET ${this.offset}` : '');\n    }\n};\n\nexports.Table = class Table {\n    constructor(name, alias = null, win = null, winFn = null, winArg = null) {\n        this.name = name;\n        this.alias = alias;\n        this.win = win;\n        this.winFn = winFn;\n        this.winArg = winArg;\n    }\n\n    toString() {\n        if (this.win) {\n            return `${this.name}.${this.win}:${this.winFn}(${this.winArg})`;\n        }\n        else if (this.alias) {\n            return `${this.name} AS ${this.alias}`;\n        }\n        else {\n            return this.name.toString();\n        }\n    }\n};\n\nexports.Group = class Group {\n    constructor(fields) {\n        this.fields = fields;\n        this.having = null;\n    }\n\n    toString() {\n        const ret = [`GROUP BY ${this.fields.join(', ')}`];\n        if (this.having) {\n            ret.push(this.having.toString());\n        }\n        return ret.join('\\n');\n    }\n};\n\nexports.Where = class Where {\n    constructor(conditions) {\n        this.conditions = conditions;\n    }\n\n    toString() {\n        return `WHERE ${this.conditions}`;\n    }\n};\n\nexports.Having = class Having {\n    constructor(conditions) {\n        this.conditions = conditions;\n    }\n\n    toString() {\n        return `HAVING ${this.conditions}`;\n    }\n};\n\nexports.Op = class Op {\n    constructor(operation, left, right) {\n        this.operation = operation;\n        this.left = left;\n        this.right = right;\n    }\n\n    toString() {\n        return `(${this.left} ${this.operation.toUpperCase()} ${this.right})`;\n    }\n};\n\nexports.UnaryOp = class UnaryOp {\n    constructor(operator, operand) {\n        this.operator = operator;\n        this.operand = operand;\n    }\n\n    toString() {\n        return `(${this.operator.toUpperCase()} ${this.operand})`;\n    }\n};\n\nexports.BetweenOp = class BetweenOp {\n    constructor(value) {\n        this.value = value;\n    }\n\n    toString() {\n        return `${this.value.join(' AND ')}`;\n    }\n};\n\nexports.Field = class Field {\n    constructor(field, name = null) {\n        this.field = field;\n        this.name = name;\n    }\n\n    toString() {\n        if (this.name) {\n            return `${this.field} AS ${this.name}`;\n        }\n        else {\n            return this.field.toString();\n        }\n    }\n};\n\nexports.Star = class Star {\n    toString() {\n        return '*';\n    }\n};\n","const parser = require('./compiled_parser').parser;\nconst nodes = require('./nodes');\n\nparser.lexer = {\n    lex          : function () {\n        let tag;\n        [tag, this.yytext, this.yylineno] = this.tokens[this.pos++] || [''];\n        return tag;\n    },\n    setInput     : function (tokens) {\n        this.tokens = tokens;\n        return this.pos = 0;\n    },\n    upcomingInput: function () {\n        return '';\n    }\n};\n\nparser.yy = nodes;\n\nexports.parser = parser;\n\nexports.parse = function (str) {\n    return parser.parse(str);\n};\n","exports.lexer = require('./lexer');\nexports.parser = require('./parser');\nexports.nodes = require('./nodes');\n\nexports.parse = function (sql) {\n    return exports.parser.parse(exports.lexer.tokenize(sql));\n};\n"],"names":["SQL_FUNCTIONS","SQL_SORT_ORDERS","SQL_OPERATORS","SUB_SELECT_OP","SUB_SELECT_UNARY_OP","SQL_CONDITIONALS","SQL_BETWEENS","BOOLEAN","MATH","MATH_MULTI","STAR","SEPARATOR","WHITESPACE","LITERAL","PARAMETER","NUMBER","STRING","DBLSTRING","Lexer","sql","opts","preserveWhitespace","tokens","currentLine","currentOffset","i","chunk","slice","bytesConsumed","keywordToken","starToken","booleanToken","functionToken","windowExtension","sortOrderToken","seperatorToken","operatorToken","numberToken","mathToken","dotToken","conditionalToken","betweenToken","subSelectOpToken","subSelectUnaryOpToken","stringToken","parameterToken","parensToken","whitespaceToken","literalToken","Error","token","postProcess","results","j","len","length","next_token","push","name","value","tokenizeFromStringRegex","regex","part","lengthPart","output","match","exec","partMatch","replace","tokenizeFromRegex","tokenizeFromWord","word","regexEscape","matcher","test","RegExp","tokenizeFromList","list","ret","entry","newlines","str","parser","o","k","v","l","$V0","$V1","$V2","$V3","$V4","$V5","$V6","$V7","$V8","$V9","$Va","$Vb","$Vc","$Vd","$Ve","$Vf","$Vg","$Vh","$Vi","$Vj","$Vk","$Vl","$Vm","$Vn","$Vo","$Vp","$Vq","$Vr","$Vs","$Vt","$Vu","$Vv","$Vw","$Vx","$Vy","$Vz","$VA","$VB","$VC","$VD","$VE","$VF","$VG","$VH","$VI","$VJ","$VK","$VL","trace","yy","symbols_","terminals_","productions_","performAction","anonymous","yytext","yyleng","yylineno","yystate","$$","_$","$0","$","unions","order","group","limit","where","Select","Table","SubSelect","concat","Union","Join","Where","Limit","Order","OrderArgument","Offset","having","Group","Having","Op","UnaryOp","WhitepaceList","BetweenOp","Case","CaseWhen","CaseElse","ListValue","NumberValue","BooleanValue","ParameterValue","StringValue","LiteralValue","FunctionValue","ArgumentListValue","Star","Field","table","defaultActions","parseError","hash","recoverable","error","parse","input","self","stack","tstack","vstack","lstack","recovering","TERROR","EOF","args","call","arguments","lexer","Object","create","sharedState","prototype","hasOwnProperty","setInput","yylloc","yyloc","ranges","options","getPrototypeOf","_token_stack","lex","symbol","preErrorSymbol","state","action","a","r","yyval","p","newState","expected","errStr","showPosition","join","text","line","loc","Array","first_line","last_line","first_column","last_column","range","apply","Parser","indent","ref","split","exports","fields","source","distinct","joins","toString","len1","select","right","conditions","side","mode","query","all1","all","value1","value2","nested","values","quote","quoteType","escaped","Number","map","index","parseInt","substr","toLowerCase","toUpperCase","_arguments","udf","whens","_else","whensStr","w","whenCondition","resCondition","elseCondition","orderings","offset","direction","row_count","alias","win","winFn","winArg","operation","left","operator","operand","field","require$$0","tag","pos","upcomingInput","nodes","require$$1","require$$2","tokenize"],"mappings":"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"}
\ No newline at end of file
diff --git a/compile-parser.js b/compile-parser.js
new file mode 100644
index 0000000..3de1c9d
--- /dev/null
+++ b/compile-parser.js
@@ -0,0 +1,9 @@
+const fs = require('fs');
+
+const parser = require('./src/grammar').parser;
+
+const code = `${parser.generate()}
+
+exports.parser = parser;`;
+
+fs.writeFileSync('src/compiled_parser.js', code);
diff --git a/index.js b/index.js
index d5e7880..7be458b 100644
--- a/index.js
+++ b/index.js
@@ -1,6 +1 @@
-sql = require('./lib/sql_parser')
-
-for(var key in sql) {
-  exports[key] = sql[key]
-}
-
+module.exports = require('./src/sql_parser');
diff --git a/lib/browser.js b/lib/browser.js
deleted file mode 100644
index 1b6ccfa..0000000
--- a/lib/browser.js
+++ /dev/null
@@ -1,1017 +0,0 @@
-(function(root) {
-  var SQLParser = function() {
-    function require(path){ return require[path]; }
-    require['./lexer'] = new function() {
-  var exports = this;
-  (function() {
-  var Lexer;
-
-  Lexer = (function() {
-    var BOOLEAN, DBLSTRING, LITERAL, MATH, MATH_MULTI, NUMBER, SEPARATOR, SQL_CONDITIONALS, SQL_FUNCTIONS, SQL_KEYWORDS, SQL_OPERATORS, SQL_SORT_ORDERS, STAR, STRING, WHITESPACE;
-
-    function Lexer(sql, opts) {
-      var bytesConsumed, i;
-      if (opts == null) opts = {};
-      this.sql = sql;
-      this.preserveWhitespace = opts.preserveWhitespace || false;
-      this.tokens = [];
-      this.currentLine = 1;
-      i = 0;
-      while (this.chunk = sql.slice(i)) {
-        bytesConsumed = this.keywordToken() || this.starToken() || this.booleanToken() || this.functionToken() || this.windowExtension() || this.sortOrderToken() || this.seperatorToken() || this.operatorToken() || this.mathToken() || this.dotToken() || this.conditionalToken() || this.numberToken() || this.stringToken() || this.parensToken() || this.whitespaceToken() || this.literalToken();
-        if (bytesConsumed < 1) {
-          throw new Error("NOTHING CONSUMED: Stopped at - '" + (this.chunk.slice(0, 30)) + "'");
-        }
-        i += bytesConsumed;
-      }
-      this.token('EOF', '');
-    }
-
-    Lexer.prototype.token = function(name, value) {
-      return this.tokens.push([name, value, this.currentLine]);
-    };
-
-    Lexer.prototype.tokenizeFromRegex = function(name, regex, part, lengthPart, output) {
-      var match, partMatch;
-      if (part == null) part = 0;
-      if (lengthPart == null) lengthPart = part;
-      if (output == null) output = true;
-      if (!(match = regex.exec(this.chunk))) return 0;
-      partMatch = match[part];
-      if (output) this.token(name, partMatch);
-      return match[lengthPart].length;
-    };
-
-    Lexer.prototype.tokenizeFromWord = function(name, word) {
-      var match, matcher;
-      if (word == null) word = name;
-      word = this.regexEscape(word);
-      matcher = /^\w+$/.test(word) ? new RegExp("^(" + word + ")\\b", 'ig') : new RegExp("^(" + word + ")", 'ig');
-      match = matcher.exec(this.chunk);
-      if (!match) return 0;
-      this.token(name, match[1]);
-      return match[1].length;
-    };
-
-    Lexer.prototype.tokenizeFromList = function(name, list) {
-      var entry, ret, _i, _len;
-      ret = 0;
-      for (_i = 0, _len = list.length; _i < _len; _i++) {
-        entry = list[_i];
-        ret = this.tokenizeFromWord(name, entry);
-        if (ret > 0) break;
-      }
-      return ret;
-    };
-
-    Lexer.prototype.keywordToken = function() {
-      return this.tokenizeFromWord('SELECT') || this.tokenizeFromWord('DISTINCT') || this.tokenizeFromWord('FROM') || this.tokenizeFromWord('WHERE') || this.tokenizeFromWord('GROUP') || this.tokenizeFromWord('ORDER') || this.tokenizeFromWord('BY') || this.tokenizeFromWord('HAVING') || this.tokenizeFromWord('LIMIT') || this.tokenizeFromWord('JOIN') || this.tokenizeFromWord('LEFT') || this.tokenizeFromWord('RIGHT') || this.tokenizeFromWord('INNER') || this.tokenizeFromWord('OUTER') || this.tokenizeFromWord('ON') || this.tokenizeFromWord('AS') || this.tokenizeFromWord('UNION') || this.tokenizeFromWord('ALL');
-    };
-
-    Lexer.prototype.dotToken = function() {
-      return this.tokenizeFromWord('DOT', '.');
-    };
-
-    Lexer.prototype.operatorToken = function() {
-      return this.tokenizeFromList('OPERATOR', SQL_OPERATORS);
-    };
-
-    Lexer.prototype.mathToken = function() {
-      return this.tokenizeFromList('MATH', MATH) || this.tokenizeFromList('MATH_MULTI', MATH_MULTI);
-    };
-
-    Lexer.prototype.conditionalToken = function() {
-      return this.tokenizeFromList('CONDITIONAL', SQL_CONDITIONALS);
-    };
-
-    Lexer.prototype.functionToken = function() {
-      return this.tokenizeFromList('FUNCTION', SQL_FUNCTIONS);
-    };
-
-    Lexer.prototype.sortOrderToken = function() {
-      return this.tokenizeFromList('DIRECTION', SQL_SORT_ORDERS);
-    };
-
-    Lexer.prototype.booleanToken = function() {
-      return this.tokenizeFromList('BOOLEAN', BOOLEAN);
-    };
-
-    Lexer.prototype.starToken = function() {
-      return this.tokenizeFromRegex('STAR', STAR);
-    };
-
-    Lexer.prototype.seperatorToken = function() {
-      return this.tokenizeFromRegex('SEPARATOR', SEPARATOR);
-    };
-
-    Lexer.prototype.literalToken = function() {
-      return this.tokenizeFromRegex('LITERAL', LITERAL, 1, 0);
-    };
-
-    Lexer.prototype.numberToken = function() {
-      return this.tokenizeFromRegex('NUMBER', NUMBER);
-    };
-
-    Lexer.prototype.stringToken = function() {
-      return this.tokenizeFromRegex('STRING', STRING, 1, 0) || this.tokenizeFromRegex('DBLSTRING', DBLSTRING, 1, 0);
-    };
-
-    Lexer.prototype.parensToken = function() {
-      return this.tokenizeFromRegex('LEFT_PAREN', /^\(/) || this.tokenizeFromRegex('RIGHT_PAREN', /^\)/);
-    };
-
-    Lexer.prototype.windowExtension = function() {
-      var match;
-      match = /^\.(win):(length|time)/i.exec(this.chunk);
-      if (!match) return 0;
-      this.token('WINDOW', match[1]);
-      this.token('WINDOW_FUNCTION', match[2]);
-      return match[0].length;
-    };
-
-    Lexer.prototype.whitespaceToken = function() {
-      var match, newlines, partMatch;
-      if (!(match = WHITESPACE.exec(this.chunk))) return 0;
-      partMatch = match[0];
-      newlines = partMatch.replace(/[^\n]/, '').length;
-      this.currentLine += newlines;
-      if (this.preserveWhitespace) this.token(name, partMatch);
-      return partMatch.length;
-    };
-
-    Lexer.prototype.regexEscape = function(str) {
-      return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
-    };
-
-    SQL_KEYWORDS = ['SELECT', 'FROM', 'WHERE', 'GROUP BY', 'ORDER BY', 'HAVING', 'AS'];
-
-    SQL_FUNCTIONS = ['AVG', 'COUNT', 'MIN', 'MAX', 'SUM'];
-
-    SQL_SORT_ORDERS = ['ASC', 'DESC'];
-
-    SQL_OPERATORS = ['=', '>', '<', 'LIKE', 'IS NOT', 'IS'];
-
-    SQL_CONDITIONALS = ['AND', 'OR'];
-
-    BOOLEAN = ['TRUE', 'FALSE', 'NULL'];
-
-    MATH = ['+', '-'];
-
-    MATH_MULTI = ['/', '*'];
-
-    STAR = /^\*/;
-
-    SEPARATOR = /^,/;
-
-    WHITESPACE = /^[ \n\r]+/;
-
-    LITERAL = /^`?([a-z_][a-z0-9_]{0,})`?/i;
-
-    NUMBER = /^[0-9]+(\.[0-9]+)?/;
-
-    STRING = /^'([^\\']*(?:\\.[^\\']*)*)'/;
-
-    DBLSTRING = /^"([^\\"]*(?:\\.[^\\"]*)*)"/;
-
-    return Lexer;
-
-  })();
-
-  exports.tokenize = function(sql, opts) {
-    return (new Lexer(sql, opts)).tokens;
-  };
-
-}).call(this);
-
-};require['./compiled_parser'] = new function() {
-  var exports = this;
-  /* Jison generated parser */
-var parser = (function(){
-undefined
-var parser = {trace: function trace() { },
-yy: {},
-symbols_: {"error":2,"Root":3,"Query":4,"EOF":5,"SelectQuery":6,"Unions":7,"SelectWithLimitQuery":8,"BasicSelectQuery":9,"Select":10,"OrderClause":11,"GroupClause":12,"LimitClause":13,"SelectClause":14,"WhereClause":15,"SELECT":16,"Fields":17,"FROM":18,"Table":19,"DISTINCT":20,"Joins":21,"Literal":22,"LEFT_PAREN":23,"RIGHT_PAREN":24,"WINDOW":25,"WINDOW_FUNCTION":26,"Number":27,"Union":28,"UNION":29,"ALL":30,"Join":31,"JOIN":32,"ON":33,"Expression":34,"LEFT":35,"RIGHT":36,"INNER":37,"OUTER":38,"WHERE":39,"LIMIT":40,"ORDER":41,"BY":42,"OrderArgs":43,"OrderArg":44,"SEPARATOR":45,"Value":46,"DIRECTION":47,"GroupBasicClause":48,"HavingClause":49,"GROUP":50,"ArgumentList":51,"HAVING":52,"MATH":53,"MATH_MULTI":54,"OPERATOR":55,"CONDITIONAL":56,"String":57,"Function":58,"UserFunction":59,"Boolean":60,"NUMBER":61,"BOOLEAN":62,"STRING":63,"DBLSTRING":64,"LITERAL":65,"DOT":66,"FUNCTION":67,"Field":68,"STAR":69,"AS":70,"$accept":0,"$end":1},
-terminals_: {2:"error",5:"EOF",16:"SELECT",18:"FROM",20:"DISTINCT",23:"LEFT_PAREN",24:"RIGHT_PAREN",25:"WINDOW",26:"WINDOW_FUNCTION",29:"UNION",30:"ALL",32:"JOIN",33:"ON",35:"LEFT",36:"RIGHT",37:"INNER",38:"OUTER",39:"WHERE",40:"LIMIT",41:"ORDER",42:"BY",45:"SEPARATOR",47:"DIRECTION",50:"GROUP",52:"HAVING",53:"MATH",54:"MATH_MULTI",55:"OPERATOR",56:"CONDITIONAL",61:"NUMBER",62:"BOOLEAN",63:"STRING",64:"DBLSTRING",65:"LITERAL",66:"DOT",67:"FUNCTION",69:"STAR",70:"AS"},
-productions_: [0,[3,2],[4,1],[4,2],[6,1],[6,1],[9,1],[9,2],[9,2],[9,3],[8,2],[10,1],[10,2],[14,4],[14,5],[14,5],[14,6],[19,1],[19,3],[19,4],[19,6],[7,1],[7,2],[28,2],[28,3],[21,1],[21,2],[31,4],[31,5],[31,5],[31,6],[31,6],[31,6],[31,6],[15,2],[13,2],[11,3],[43,1],[43,3],[44,1],[44,2],[12,1],[12,2],[48,3],[49,2],[34,3],[34,3],[34,3],[34,3],[34,3],[34,1],[46,1],[46,1],[46,1],[46,1],[46,1],[46,1],[27,1],[60,1],[57,1],[57,1],[22,1],[22,3],[58,4],[59,4],[51,1],[51,3],[17,1],[17,3],[68,1],[68,1],[68,3]],
-performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
-
-var $0 = $$.length - 1;
-switch (yystate) {
-case 1:return this.$ = $$[$0-1];
-break;
-case 2:this.$ = $$[$0];
-break;
-case 3:this.$ = (function () {
-        $$[$0-1].unions = $$[$0];
-        return $$[$0-1];
-      }());
-break;
-case 4:this.$ = $$[$0];
-break;
-case 5:this.$ = $$[$0];
-break;
-case 6:this.$ = $$[$0];
-break;
-case 7:this.$ = (function () {
-        $$[$0-1].order = $$[$0];
-        return $$[$0-1];
-      }());
-break;
-case 8:this.$ = (function () {
-        $$[$0-1].group = $$[$0];
-        return $$[$0-1];
-      }());
-break;
-case 9:this.$ = (function () {
-        $$[$0-2].group = $$[$0-1];
-        $$[$0-2].order = $$[$0];
-        return $$[$0-2];
-      }());
-break;
-case 10:this.$ = (function () {
-        $$[$0-1].limit = $$[$0];
-        return $$[$0-1];
-      }());
-break;
-case 11:this.$ = $$[$0];
-break;
-case 12:this.$ = (function () {
-        $$[$0-1].where = $$[$0];
-        return $$[$0-1];
-      }());
-break;
-case 13:this.$ = new yy.Select($$[$0-2], $$[$0], false);
-break;
-case 14:this.$ = new yy.Select($$[$0-2], $$[$0], true);
-break;
-case 15:this.$ = new yy.Select($$[$0-3], $$[$0-1], false, $$[$0]);
-break;
-case 16:this.$ = new yy.Select($$[$0-3], $$[$0-1], true, $$[$0]);
-break;
-case 17:this.$ = new yy.Table($$[$0]);
-break;
-case 18:this.$ = new yy.SubSelect($$[$0-1]);
-break;
-case 19:this.$ = new yy.SubSelect($$[$0-2], $$[$0]);
-break;
-case 20:this.$ = new yy.Table($$[$0-5], $$[$0-4], $$[$0-3], $$[$0-1]);
-break;
-case 21:this.$ = [$$[$0]];
-break;
-case 22:this.$ = $$[$0-1].concat($$[$01]);
-break;
-case 23:this.$ = new yy.Union($$[$0]);
-break;
-case 24:this.$ = new yy.Union($$[$0], true);
-break;
-case 25:this.$ = [$$[$0]];
-break;
-case 26:this.$ = $$[$0-1].concat($$[$0]);
-break;
-case 27:this.$ = new yy.Join($$[$0-2], $$[$0]);
-break;
-case 28:this.$ = new yy.Join($$[$0-2], $$[$0], 'LEFT');
-break;
-case 29:this.$ = new yy.Join($$[$0-2], $$[$0], 'RIGHT');
-break;
-case 30:this.$ = new yy.Join($$[$0-2], $$[$0], 'LEFT', 'INNER');
-break;
-case 31:this.$ = new yy.Join($$[$0-2], $$[$0], 'RIGHT', 'INNER');
-break;
-case 32:this.$ = new yy.Join($$[$0-2], $$[$0], 'LEFT', 'OUTER');
-break;
-case 33:this.$ = new yy.Join($$[$0-2], $$[$0], 'RIGHT', 'OUTER');
-break;
-case 34:this.$ = new yy.Where($$[$0]);
-break;
-case 35:this.$ = new yy.Limit($$[$0]);
-break;
-case 36:this.$ = new yy.Order($$[$0]);
-break;
-case 37:this.$ = [$$[$0]];
-break;
-case 38:this.$ = $$[$0-2].concat($$[$0]);
-break;
-case 39:this.$ = new yy.OrderArgument($$[$0], 'ASC');
-break;
-case 40:this.$ = new yy.OrderArgument($$[$0-1], $$[$0]);
-break;
-case 41:this.$ = $$[$0];
-break;
-case 42:this.$ = (function () {
-        $$[$0-1].having = $$[$0];
-        return $$[$0-1];
-      }());
-break;
-case 43:this.$ = new yy.Group($$[$0]);
-break;
-case 44:this.$ = new yy.Having($$[$0]);
-break;
-case 45:this.$ = $$[$0-1];
-break;
-case 46:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]);
-break;
-case 47:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]);
-break;
-case 48:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]);
-break;
-case 49:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]);
-break;
-case 50:this.$ = $$[$0];
-break;
-case 51:this.$ = $$[$0];
-break;
-case 52:this.$ = $$[$0];
-break;
-case 53:this.$ = $$[$0];
-break;
-case 54:this.$ = $$[$0];
-break;
-case 55:this.$ = $$[$0];
-break;
-case 56:this.$ = $$[$0];
-break;
-case 57:this.$ = new yy.NumberValue($$[$0]);
-break;
-case 58:this.$ = new yy.BooleanValue($$[$0]);
-break;
-case 59:this.$ = new yy.StringValue($$[$0], "'");
-break;
-case 60:this.$ = new yy.StringValue($$[$0], '"');
-break;
-case 61:this.$ = new yy.LiteralValue($$[$0]);
-break;
-case 62:this.$ = new yy.LiteralValue($$[$0-2], $$[$0]);
-break;
-case 63:this.$ = new yy.FunctionValue($$[$0-3], $$[$0-1]);
-break;
-case 64:this.$ = new yy.FunctionValue($$[$0-3], $$[$0-1], true);
-break;
-case 65:this.$ = [$$[$0]];
-break;
-case 66:this.$ = $$[$0-2].concat($$[$0]);
-break;
-case 67:this.$ = [$$[$0]];
-break;
-case 68:this.$ = $$[$0-2].concat($$[$0]);
-break;
-case 69:this.$ = new yy.Star();
-break;
-case 70:this.$ = new yy.Field($$[$0]);
-break;
-case 71:this.$ = new yy.Field($$[$0-2], $$[$0]);
-break;
-}
-},
-table: [{3:1,4:2,6:3,8:4,9:5,10:6,14:7,16:[1,8]},{1:[3]},{5:[1,9]},{5:[2,2],7:10,13:11,24:[2,2],28:12,29:[1,14],40:[1,13]},{5:[2,4],24:[2,4],29:[2,4],40:[2,4]},{5:[2,5],24:[2,5],29:[2,5],40:[2,5]},{5:[2,6],11:15,12:16,24:[2,6],29:[2,6],40:[2,6],41:[1,17],48:18,50:[1,19]},{5:[2,11],15:20,24:[2,11],29:[2,11],39:[1,21],40:[2,11],41:[2,11],50:[2,11]},{17:22,20:[1,23],22:29,23:[1,27],27:30,34:26,46:28,57:31,58:32,59:33,60:34,61:[1,36],62:[1,40],63:[1,37],64:[1,38],65:[1,35],67:[1,39],68:24,69:[1,25]},{1:[2,1]},{5:[2,3],24:[2,3],28:41,29:[1,14]},{5:[2,10],24:[2,10],29:[2,10],40:[2,10]},{5:[2,21],24:[2,21],29:[2,21]},{27:42,61:[1,36]},{6:43,8:4,9:5,10:6,14:7,16:[1,8],30:[1,44]},{5:[2,7],24:[2,7],29:[2,7],40:[2,7]},{5:[2,8],11:45,24:[2,8],29:[2,8],40:[2,8],41:[1,17]},{42:[1,46]},{5:[2,41],24:[2,41],29:[2,41],40:[2,41],41:[2,41],49:47,52:[1,48]},{42:[1,49]},{5:[2,12],24:[2,12],29:[2,12],40:[2,12],41:[2,12],50:[2,12]},{22:29,23:[1,27],27:30,34:50,46:28,57:31,58:32,59:33,60:34,61:[1,36],62:[1,40],63:[1,37],64:[1,38],65:[1,35],67:[1,39]},{18:[1,51],45:[1,52]},{17:53,22:29,23:[1,27],27:30,34:26,46:28,57:31,58:32,59:33,60:34,61:[1,36],62:[1,40],63:[1,37],64:[1,38],65:[1,35],67:[1,39],68:24,69:[1,25]},{18:[2,67],45:[2,67]},{18:[2,69],45:[2,69]},{18:[2,70],45:[2,70],53:[1,55],54:[1,56],55:[1,57],56:[1,58],70:[1,54]},{22:29,23:[1,27],27:30,34:59,46:28,57:31,58:32,59:33,60:34,61:[1,36],62:[1,40],63:[1,37],64:[1,38],65:[1,35],67:[1,39]},{5:[2,50],18:[2,50],24:[2,50],29:[2,50],32:[2,50],35:[2,50],36:[2,50],39:[2,50],40:[2,50],41:[2,50],45:[2,50],50:[2,50],52:[2,50],53:[2,50],54:[2,50],55:[2,50],56:[2,50],70:[2,50]},{5:[2,51],18:[2,51],24:[2,51],29:[2,51],32:[2,51],35:[2,51],36:[2,51],39:[2,51],40:[2,51],41:[2,51],45:[2,51],47:[2,51],50:[2,51],52:[2,51],53:[2,51],54:[2,51],55:[2,51],56:[2,51],66:[1,60],70:[2,51]},{5:[2,52],18:[2,52],24:[2,52],29:[2,52],32:[2,52],35:[2,52],36:[2,52],39:[2,52],40:[2,52],41:[2,52],45:[2,52],47:[2,52],50:[2,52],52:[2,52],53:[2,52],54:[2,52],55:[2,52],56:[2,52],70:[2,52]},{5:[2,53],18:[2,53],24:[2,53],29:[2,53],32:[2,53],35:[2,53],36:[2,53],39:[2,53],40:[2,53],41:[2,53],45:[2,53],47:[2,53],50:[2,53],52:[2,53],53:[2,53],54:[2,53],55:[2,53],56:[2,53],70:[2,53]},{5:[2,54],18:[2,54],24:[2,54],29:[2,54],32:[2,54],35:[2,54],36:[2,54],39:[2,54],40:[2,54],41:[2,54],45:[2,54],47:[2,54],50:[2,54],52:[2,54],53:[2,54],54:[2,54],55:[2,54],56:[2,54],70:[2,54]},{5:[2,55],18:[2,55],24:[2,55],29:[2,55],32:[2,55],35:[2,55],36:[2,55],39:[2,55],40:[2,55],41:[2,55],45:[2,55],47:[2,55],50:[2,55],52:[2,55],53:[2,55],54:[2,55],55:[2,55],56:[2,55],70:[2,55]},{5:[2,56],18:[2,56],24:[2,56],29:[2,56],32:[2,56],35:[2,56],36:[2,56],39:[2,56],40:[2,56],41:[2,56],45:[2,56],47:[2,56],50:[2,56],52:[2,56],53:[2,56],54:[2,56],55:[2,56],56:[2,56],70:[2,56]},{5:[2,61],18:[2,61],23:[1,61],24:[2,61],29:[2,61],32:[2,61],35:[2,61],36:[2,61],39:[2,61],40:[2,61],41:[2,61],45:[2,61],47:[2,61],50:[2,61],52:[2,61],53:[2,61],54:[2,61],55:[2,61],56:[2,61],66:[2,61],70:[2,61]},{5:[2,57],18:[2,57],24:[2,57],29:[2,57],32:[2,57],35:[2,57],36:[2,57],39:[2,57],40:[2,57],41:[2,57],45:[2,57],47:[2,57],50:[2,57],52:[2,57],53:[2,57],54:[2,57],55:[2,57],56:[2,57],70:[2,57]},{5:[2,59],18:[2,59],24:[2,59],29:[2,59],32:[2,59],35:[2,59],36:[2,59],39:[2,59],40:[2,59],41:[2,59],45:[2,59],47:[2,59],50:[2,59],52:[2,59],53:[2,59],54:[2,59],55:[2,59],56:[2,59],70:[2,59]},{5:[2,60],18:[2,60],24:[2,60],29:[2,60],32:[2,60],35:[2,60],36:[2,60],39:[2,60],40:[2,60],41:[2,60],45:[2,60],47:[2,60],50:[2,60],52:[2,60],53:[2,60],54:[2,60],55:[2,60],56:[2,60],70:[2,60]},{23:[1,62]},{5:[2,58],18:[2,58],24:[2,58],29:[2,58],32:[2,58],35:[2,58],36:[2,58],39:[2,58],40:[2,58],41:[2,58],45:[2,58],47:[2,58],50:[2,58],52:[2,58],53:[2,58],54:[2,58],55:[2,58],56:[2,58],70:[2,58]},{5:[2,22],24:[2,22],29:[2,22]},{5:[2,35],24:[2,35],29:[2,35],40:[2,35]},{5:[2,23],13:11,24:[2,23],29:[2,23],40:[1,13]},{6:63,8:4,9:5,10:6,14:7,16:[1,8]},{5:[2,9],24:[2,9],29:[2,9],40:[2,9]},{22:29,27:30,43:64,44:65,46:66,57:31,58:32,59:33,60:34,61:[1,36],62:[1,40],63:[1,37],64:[1,38],65:[1,35],67:[1,39]},{5:[2,42],24:[2,42],29:[2,42],40:[2,42],41:[2,42]},{22:29,23:[1,27],27:30,34:67,46:28,57:31,58:32,59:33,60:34,61:[1,36],62:[1,40],63:[1,37],64:[1,38],65:[1,35],67:[1,39]},{22:29,23:[1,27],27:30,34:69,46:28,51:68,57:31,58:32,59:33,60:34,61:[1,36],62:[1,40],63:[1,37],64:[1,38],65:[1,35],67:[1,39]},{5:[2,34],24:[2,34],29:[2,34],40:[2,34],41:[2,34],50:[2,34],53:[1,55],54:[1,56],55:[1,57],56:[1,58]},{19:70,22:71,23:[1,72],65:[1,73]},{22:29,23:[1,27],27:30,34:26,46:28,57:31,58:32,59:33,60:34,61:[1,36],62:[1,40],63:[1,37],64:[1,38],65:[1,35],67:[1,39],68:74,69:[1,25]},{18:[1,75],45:[1,52]},{22:76,65:[1,73]},{22:29,23:[1,27],27:30,34:77,46:28,57:31,58:32,59:33,60:34,61:[1,36],62:[1,40],63:[1,37],64:[1,38],65:[1,35],67:[1,39]},{22:29,23:[1,27],27:30,34:78,46:28,57:31,58:32,59:33,60:34,61:[1,36],62:[1,40],63:[1,37],64:[1,38],65:[1,35],67:[1,39]},{22:29,23:[1,27],27:30,34:79,46:28,57:31,58:32,59:33,60:34,61:[1,36],62:[1,40],63:[1,37],64:[1,38],65:[1,35],67:[1,39]},{22:29,23:[1,27],27:30,34:80,46:28,57:31,58:32,59:33,60:34,61:[1,36],62:[1,40],63:[1,37],64:[1,38],65:[1,35],67:[1,39]},{24:[1,81],53:[1,55],54:[1,56],55:[1,57],56:[1,58]},{65:[1,82]},{22:29,23:[1,27],27:30,34:69,46:28,51:83,57:31,58:32,59:33,60:34,61:[1,36],62:[1,40],63:[1,37],64:[1,38],65:[1,35],67:[1,39]},{22:29,23:[1,27],27:30,34:69,46:28,51:84,57:31,58:32,59:33,60:34,61:[1,36],62:[1,40],63:[1,37],64:[1,38],65:[1,35],67:[1,39]},{5:[2,24],13:11,24:[2,24],29:[2,24],40:[1,13]},{5:[2,36],24:[2,36],29:[2,36],40:[2,36],45:[1,85]},{5:[2,37],24:[2,37],29:[2,37],40:[2,37],45:[2,37]},{5:[2,39],24:[2,39],29:[2,39],40:[2,39],45:[2,39],47:[1,86]},{5:[2,44],24:[2,44],29:[2,44],40:[2,44],41:[2,44],53:[1,55],54:[1,56],55:[1,57],56:[1,58]},{5:[2,43],24:[2,43],29:[2,43],40:[2,43],41:[2,43],45:[1,87],52:[2,43]},{5:[2,65],24:[2,65],29:[2,65],40:[2,65],41:[2,65],45:[2,65],52:[2,65],53:[1,55],54:[1,56],55:[1,57],56:[1,58]},{5:[2,13],21:88,24:[2,13],29:[2,13],31:89,32:[1,90],35:[1,91],36:[1,92],39:[2,13],40:[2,13],41:[2,13],50:[2,13]},{5:[2,17],24:[2,17],25:[1,93],29:[2,17],32:[2,17],33:[2,17],35:[2,17],36:[2,17],39:[2,17],40:[2,17],41:[2,17],50:[2,17],66:[1,60]},{4:94,6:3,8:4,9:5,10:6,14:7,16:[1,8]},{5:[2,61],18:[2,61],24:[2,61],25:[2,61],29:[2,61],32:[2,61],33:[2,61],35:[2,61],36:[2,61],39:[2,61],40:[2,61],41:[2,61],45:[2,61],50:[2,61],66:[2,61]},{18:[2,68],45:[2,68]},{19:95,22:71,23:[1,72],65:[1,73]},{18:[2,71],45:[2,71],66:[1,60]},{5:[2,46],18:[2,46],24:[2,46],29:[2,46],32:[2,46],35:[2,46],36:[2,46],39:[2,46],40:[2,46],41:[2,46],45:[2,46],50:[2,46],52:[2,46],53:[2,46],54:[1,56],55:[2,46],56:[2,46],70:[2,46]},{5:[2,47],18:[2,47],24:[2,47],29:[2,47],32:[2,47],35:[2,47],36:[2,47],39:[2,47],40:[2,47],41:[2,47],45:[2,47],50:[2,47],52:[2,47],53:[2,47],54:[2,47],55:[2,47],56:[2,47],70:[2,47]},{5:[2,48],18:[2,48],24:[2,48],29:[2,48],32:[2,48],35:[2,48],36:[2,48],39:[2,48],40:[2,48],41:[2,48],45:[2,48],50:[2,48],52:[2,48],53:[1,55],54:[1,56],55:[2,48],56:[2,48],70:[2,48]},{5:[2,49],18:[2,49],24:[2,49],29:[2,49],32:[2,49],35:[2,49],36:[2,49],39:[2,49],40:[2,49],41:[2,49],45:[2,49],50:[2,49],52:[2,49],53:[1,55],54:[1,56],55:[1,57],56:[2,49],70:[2,49]},{5:[2,45],18:[2,45],24:[2,45],29:[2,45],32:[2,45],35:[2,45],36:[2,45],39:[2,45],40:[2,45],41:[2,45],45:[2,45],50:[2,45],52:[2,45],53:[2,45],54:[2,45],55:[2,45],56:[2,45],70:[2,45]},{5:[2,62],18:[2,62],24:[2,62],25:[2,62],29:[2,62],32:[2,62],33:[2,62],35:[2,62],36:[2,62],39:[2,62],40:[2,62],41:[2,62],45:[2,62],47:[2,62],50:[2,62],52:[2,62],53:[2,62],54:[2,62],55:[2,62],56:[2,62],66:[2,62],70:[2,62]},{24:[1,96],45:[1,87]},{24:[1,97],45:[1,87]},{22:29,27:30,44:98,46:66,57:31,58:32,59:33,60:34,61:[1,36],62:[1,40],63:[1,37],64:[1,38],65:[1,35],67:[1,39]},{5:[2,40],24:[2,40],29:[2,40],40:[2,40],45:[2,40]},{22:29,27:30,46:99,57:31,58:32,59:33,60:34,61:[1,36],62:[1,40],63:[1,37],64:[1,38],65:[1,35],67:[1,39]},{5:[2,15],24:[2,15],29:[2,15],31:100,32:[1,90],35:[1,91],36:[1,92],39:[2,15],40:[2,15],41:[2,15],50:[2,15]},{5:[2,25],24:[2,25],29:[2,25],32:[2,25],35:[2,25],36:[2,25],39:[2,25],40:[2,25],41:[2,25],50:[2,25]},{19:101,22:71,23:[1,72],65:[1,73]},{32:[1,102],37:[1,103],38:[1,104]},{32:[1,105],37:[1,106],38:[1,107]},{26:[1,108]},{24:[1,109]},{5:[2,14],21:110,24:[2,14],29:[2,14],31:89,32:[1,90],35:[1,91],36:[1,92],39:[2,14],40:[2,14],41:[2,14],50:[2,14]},{5:[2,64],18:[2,64],24:[2,64],29:[2,64],32:[2,64],35:[2,64],36:[2,64],39:[2,64],40:[2,64],41:[2,64],45:[2,64],47:[2,64],50:[2,64],52:[2,64],53:[2,64],54:[2,64],55:[2,64],56:[2,64],70:[2,64]},{5:[2,63],18:[2,63],24:[2,63],29:[2,63],32:[2,63],35:[2,63],36:[2,63],39:[2,63],40:[2,63],41:[2,63],45:[2,63],47:[2,63],50:[2,63],52:[2,63],53:[2,63],54:[2,63],55:[2,63],56:[2,63],70:[2,63]},{5:[2,38],24:[2,38],29:[2,38],40:[2,38],45:[2,38]},{5:[2,66],24:[2,66],29:[2,66],40:[2,66],41:[2,66],45:[2,66],52:[2,66]},{5:[2,26],24:[2,26],29:[2,26],32:[2,26],35:[2,26],36:[2,26],39:[2,26],40:[2,26],41:[2,26],50:[2,26]},{33:[1,111]},{19:112,22:71,23:[1,72],65:[1,73]},{32:[1,113]},{32:[1,114]},{19:115,22:71,23:[1,72],65:[1,73]},{32:[1,116]},{32:[1,117]},{23:[1,118]},{5:[2,18],22:119,24:[2,18],29:[2,18],32:[2,18],33:[2,18],35:[2,18],36:[2,18],39:[2,18],40:[2,18],41:[2,18],50:[2,18],65:[1,73]},{5:[2,16],24:[2,16],29:[2,16],31:100,32:[1,90],35:[1,91],36:[1,92],39:[2,16],40:[2,16],41:[2,16],50:[2,16]},{22:29,23:[1,27],27:30,34:120,46:28,57:31,58:32,59:33,60:34,61:[1,36],62:[1,40],63:[1,37],64:[1,38],65:[1,35],67:[1,39]},{33:[1,121]},{19:122,22:71,23:[1,72],65:[1,73]},{19:123,22:71,23:[1,72],65:[1,73]},{33:[1,124]},{19:125,22:71,23:[1,72],65:[1,73]},{19:126,22:71,23:[1,72],65:[1,73]},{27:127,61:[1,36]},{5:[2,19],24:[2,19],29:[2,19],32:[2,19],33:[2,19],35:[2,19],36:[2,19],39:[2,19],40:[2,19],41:[2,19],50:[2,19],66:[1,60]},{5:[2,27],24:[2,27],29:[2,27],32:[2,27],35:[2,27],36:[2,27],39:[2,27],40:[2,27],41:[2,27],50:[2,27],53:[1,55],54:[1,56],55:[1,57],56:[1,58]},{22:29,23:[1,27],27:30,34:128,46:28,57:31,58:32,59:33,60:34,61:[1,36],62:[1,40],63:[1,37],64:[1,38],65:[1,35],67:[1,39]},{33:[1,129]},{33:[1,130]},{22:29,23:[1,27],27:30,34:131,46:28,57:31,58:32,59:33,60:34,61:[1,36],62:[1,40],63:[1,37],64:[1,38],65:[1,35],67:[1,39]},{33:[1,132]},{33:[1,133]},{24:[1,134]},{5:[2,28],24:[2,28],29:[2,28],32:[2,28],35:[2,28],36:[2,28],39:[2,28],40:[2,28],41:[2,28],50:[2,28],53:[1,55],54:[1,56],55:[1,57],56:[1,58]},{22:29,23:[1,27],27:30,34:135,46:28,57:31,58:32,59:33,60:34,61:[1,36],62:[1,40],63:[1,37],64:[1,38],65:[1,35],67:[1,39]},{22:29,23:[1,27],27:30,34:136,46:28,57:31,58:32,59:33,60:34,61:[1,36],62:[1,40],63:[1,37],64:[1,38],65:[1,35],67:[1,39]},{5:[2,29],24:[2,29],29:[2,29],32:[2,29],35:[2,29],36:[2,29],39:[2,29],40:[2,29],41:[2,29],50:[2,29],53:[1,55],54:[1,56],55:[1,57],56:[1,58]},{22:29,23:[1,27],27:30,34:137,46:28,57:31,58:32,59:33,60:34,61:[1,36],62:[1,40],63:[1,37],64:[1,38],65:[1,35],67:[1,39]},{22:29,23:[1,27],27:30,34:138,46:28,57:31,58:32,59:33,60:34,61:[1,36],62:[1,40],63:[1,37],64:[1,38],65:[1,35],67:[1,39]},{5:[2,20],24:[2,20],29:[2,20],32:[2,20],33:[2,20],35:[2,20],36:[2,20],39:[2,20],40:[2,20],41:[2,20],50:[2,20]},{5:[2,30],24:[2,30],29:[2,30],32:[2,30],35:[2,30],36:[2,30],39:[2,30],40:[2,30],41:[2,30],50:[2,30],53:[1,55],54:[1,56],55:[1,57],56:[1,58]},{5:[2,32],24:[2,32],29:[2,32],32:[2,32],35:[2,32],36:[2,32],39:[2,32],40:[2,32],41:[2,32],50:[2,32],53:[1,55],54:[1,56],55:[1,57],56:[1,58]},{5:[2,31],24:[2,31],29:[2,31],32:[2,31],35:[2,31],36:[2,31],39:[2,31],40:[2,31],41:[2,31],50:[2,31],53:[1,55],54:[1,56],55:[1,57],56:[1,58]},{5:[2,33],24:[2,33],29:[2,33],32:[2,33],35:[2,33],36:[2,33],39:[2,33],40:[2,33],41:[2,33],50:[2,33],53:[1,55],54:[1,56],55:[1,57],56:[1,58]}],
-defaultActions: {9:[2,1]},
-parseError: function parseError(str, hash) {
-    throw new Error(str);
-},
-parse: function parse(input) {
-    var self = this,
-        stack = [0],
-        vstack = [null], // semantic value stack
-        lstack = [], // location stack
-        table = this.table,
-        yytext = '',
-        yylineno = 0,
-        yyleng = 0,
-        recovering = 0,
-        TERROR = 2,
-        EOF = 1;
-
-    //this.reductionCount = this.shiftCount = 0;
-
-    this.lexer.setInput(input);
-    this.lexer.yy = this.yy;
-    this.yy.lexer = this.lexer;
-    if (typeof this.lexer.yylloc == 'undefined')
-        this.lexer.yylloc = {};
-    var yyloc = this.lexer.yylloc;
-    lstack.push(yyloc);
-
-    if (typeof this.yy.parseError === 'function')
-        this.parseError = this.yy.parseError;
-
-    function popStack (n) {
-        stack.length = stack.length - 2*n;
-        vstack.length = vstack.length - n;
-        lstack.length = lstack.length - n;
-    }
-
-    function lex() {
-        var token;
-        token = self.lexer.lex() || 1; // $end = 1
-        // if token isn't its numeric value, convert
-        if (typeof token !== 'number') {
-            token = self.symbols_[token] || token;
-        }
-        return token;
-    };
-
-    var symbol, preErrorSymbol, state, action, a, r, yyval={},p,len,newState, expected;
-    while (true) {
-        // retreive state number from top of stack
-        state = stack[stack.length-1];
-
-        // use default actions if available
-        if (this.defaultActions[state]) {
-            action = this.defaultActions[state];
-        } else {
-            if (symbol == null)
-                symbol = lex();
-            // read action for current state and first input
-            action = table[state] && table[state][symbol];
-        }
-
-        // handle parse error
-        if (typeof action === 'undefined' || !action.length || !action[0]) {
-
-            if (!recovering) {
-                // Report error
-                expected = [];
-                for (p in table[state]) if (this.terminals_[p] && p > 2) {
-                    expected.push("'"+this.terminals_[p]+"'");
-                }
-                var errStr = '';
-                if (this.lexer.showPosition) {
-                    errStr = 'Parse error on line '+(yylineno+1)+":\n"+this.lexer.showPosition()+'\nExpecting '+expected.join(', ') + ", got '" + this.terminals_[symbol]+ "'";
-                } else {
-                    errStr = 'Parse error on line '+(yylineno+1)+": Unexpected " +
-                                  (symbol == 1 /*EOF*/ ? "end of input" :
-                                              ("'"+(this.terminals_[symbol] || symbol)+"'"));
-                }
-                this.parseError(errStr,
-                    {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
-            }
-
-            // just recovered from another error
-            if (recovering == 3) {
-                if (symbol == EOF) {
-                    throw new Error(errStr || 'Parsing halted.');
-                }
-
-                // discard current lookahead and grab another
-                yyleng = this.lexer.yyleng;
-                yytext = this.lexer.yytext;
-                yylineno = this.lexer.yylineno;
-                yyloc = this.lexer.yylloc;
-                symbol = lex();
-            }
-
-            // try to recover from error
-            while (1) {
-                // check for error recovery rule in this state
-                if ((TERROR.toString()) in table[state]) {
-                    break;
-                }
-                if (state == 0) {
-                    throw new Error(errStr || 'Parsing halted.');
-                }
-                popStack(1);
-                state = stack[stack.length-1];
-            }
-
-            preErrorSymbol = symbol; // save the lookahead token
-            symbol = TERROR;         // insert generic error symbol as new lookahead
-            state = stack[stack.length-1];
-            action = table[state] && table[state][TERROR];
-            recovering = 3; // allow 3 real symbols to be shifted before reporting a new error
-        }
-
-        // this shouldn't happen, unless resolve defaults are off
-        if (action[0] instanceof Array && action.length > 1) {
-            throw new Error('Parse Error: multiple actions possible at state: '+state+', token: '+symbol);
-        }
-
-        switch (action[0]) {
-
-            case 1: // shift
-                //this.shiftCount++;
-
-                stack.push(symbol);
-                vstack.push(this.lexer.yytext);
-                lstack.push(this.lexer.yylloc);
-                stack.push(action[1]); // push state
-                symbol = null;
-                if (!preErrorSymbol) { // normal execution/no error
-                    yyleng = this.lexer.yyleng;
-                    yytext = this.lexer.yytext;
-                    yylineno = this.lexer.yylineno;
-                    yyloc = this.lexer.yylloc;
-                    if (recovering > 0)
-                        recovering--;
-                } else { // error just occurred, resume old lookahead f/ before error
-                    symbol = preErrorSymbol;
-                    preErrorSymbol = null;
-                }
-                break;
-
-            case 2: // reduce
-                //this.reductionCount++;
-
-                len = this.productions_[action[1]][1];
-
-                // perform semantic action
-                yyval.$ = vstack[vstack.length-len]; // default to $$ = $1
-                // default location, uses first token for firsts, last for lasts
-                yyval._$ = {
-                    first_line: lstack[lstack.length-(len||1)].first_line,
-                    last_line: lstack[lstack.length-1].last_line,
-                    first_column: lstack[lstack.length-(len||1)].first_column,
-                    last_column: lstack[lstack.length-1].last_column
-                };
-                r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
-
-                if (typeof r !== 'undefined') {
-                    return r;
-                }
-
-                // pop off stack
-                if (len) {
-                    stack = stack.slice(0,-1*len*2);
-                    vstack = vstack.slice(0, -1*len);
-                    lstack = lstack.slice(0, -1*len);
-                }
-
-                stack.push(this.productions_[action[1]][0]);    // push nonterminal (reduce)
-                vstack.push(yyval.$);
-                lstack.push(yyval._$);
-                // goto new state = table[STATE][NONTERMINAL]
-                newState = table[stack[stack.length-2]][stack[stack.length-1]];
-                stack.push(newState);
-                break;
-
-            case 3: // accept
-                return true;
-        }
-
-    }
-
-    return true;
-}};
-return parser;
-})();
-if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
-exports.parser = parser;
-exports.parse = function () { return parser.parse.apply(parser, arguments); }
-exports.main = function commonjsMain(args) {
-    if (!args[1])
-        throw new Error('Usage: '+args[0]+' FILE');
-    if (typeof process !== 'undefined') {
-        var source = require('fs').readFileSync(require('path').join(process.cwd(), args[1]), "utf8");
-    } else {
-        var cwd = require("file").path(require("file").cwd());
-        var source = cwd.join(args[1]).read({charset: "utf-8"});
-    }
-    return exports.parser.parse(source);
-}
-if (typeof module !== 'undefined' && require.main === module) {
-  exports.main(typeof process !== 'undefined' ? process.argv.slice(1) : require("system").args);
-}
-}
-};require['./nodes'] = new function() {
-  var exports = this;
-  (function() {
-  var Field, FunctionValue, Group, Having, Join, Limit, LiteralValue, Op, Order, OrderArgument, Select, Star, StringValue, SubSelect, Table, Union, Where, indent;
-
-  indent = function(str) {
-    var line;
-    return ((function() {
-      var _i, _len, _ref, _results;
-      _ref = str.split("\n");
-      _results = [];
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        line = _ref[_i];
-        _results.push("  " + line);
-      }
-      return _results;
-    })()).join("\n");
-  };
-
-  exports.Select = Select = (function() {
-
-    function Select(fields, source, distinct, joins, unions) {
-      this.fields = fields;
-      this.source = source;
-      this.distinct = distinct != null ? distinct : false;
-      this.joins = joins != null ? joins : [];
-      this.unions = unions != null ? unions : [];
-      this.order = null;
-      this.group = null;
-      this.where = null;
-      this.limit = null;
-    }
-
-    Select.prototype.toString = function() {
-      var join, ret, union, _i, _j, _len, _len2, _ref, _ref2;
-      ret = ["SELECT " + (this.fields.join(', '))];
-      ret.push(indent("FROM " + this.source));
-      _ref = this.joins;
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        join = _ref[_i];
-        ret.push(indent(join.toString()));
-      }
-      if (this.where) ret.push(indent(this.where.toString()));
-      if (this.group) ret.push(indent(this.group.toString()));
-      if (this.order) ret.push(indent(this.order.toString()));
-      if (this.limit) ret.push(indent(this.limit.toString()));
-      _ref2 = this.unions;
-      for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
-        union = _ref2[_j];
-        ret.push(union.toString());
-      }
-      return ret.join("\n");
-    };
-
-    return Select;
-
-  })();
-
-  exports.SubSelect = SubSelect = (function() {
-
-    function SubSelect(select, name) {
-      this.select = select;
-      this.name = name != null ? name : null;
-      null;
-    }
-
-    SubSelect.prototype.toString = function() {
-      var ret;
-      ret = [];
-      ret.push('(');
-      ret.push(indent(this.select.toString()));
-      ret.push(this.name ? ") " + (this.name.toString()) : ")");
-      return ret.join("\n");
-    };
-
-    return SubSelect;
-
-  })();
-
-  exports.Join = Join = (function() {
-
-    function Join(right, conditions, side, mode) {
-      this.right = right;
-      this.conditions = conditions != null ? conditions : null;
-      this.side = side != null ? side : null;
-      this.mode = mode != null ? mode : null;
-      null;
-    }
-
-    Join.prototype.toString = function() {
-      var ret;
-      ret = '';
-      if (this.side != null) ret += "" + this.side + " ";
-      if (this.mode != null) ret += "" + this.mode + " ";
-      return ret + ("JOIN " + this.right + "\n") + indent("ON " + this.conditions);
-    };
-
-    return Join;
-
-  })();
-
-  exports.Union = Union = (function() {
-
-    function Union(query, all) {
-      this.query = query;
-      this.all = all != null ? all : false;
-      null;
-    }
-
-    Union.prototype.toString = function() {
-      var all;
-      all = this.all ? ' ALL' : '';
-      return "UNION" + all + "\n" + (this.query.toString());
-    };
-
-    return Union;
-
-  })();
-
-  exports.LiteralValue = LiteralValue = (function() {
-
-    function LiteralValue(value, value2) {
-      this.value = value;
-      this.value2 = value2 != null ? value2 : null;
-      if (this.value2) {
-        this.nested = true;
-        this.values = this.value.values;
-        this.values.push(value2);
-      } else {
-        this.nested = false;
-        this.values = [this.value];
-      }
-    }
-
-    LiteralValue.prototype.toString = function() {
-      return "`" + (this.values.join('.')) + "`";
-    };
-
-    return LiteralValue;
-
-  })();
-
-  exports.StringValue = StringValue = (function() {
-
-    function StringValue(value, quoteType) {
-      this.value = value;
-      this.quoteType = quoteType != null ? quoteType : "''";
-      null;
-    }
-
-    StringValue.prototype.toString = function() {
-      return "" + this.quoteType + this.value + this.quoteType;
-    };
-
-    return StringValue;
-
-  })();
-
-  exports.NumberValue = LiteralValue = (function() {
-
-    function LiteralValue(value) {
-      this.value = Number(value);
-    }
-
-    LiteralValue.prototype.toString = function() {
-      return this.value.toString();
-    };
-
-    return LiteralValue;
-
-  })();
-
-  exports.BooleanValue = LiteralValue = (function() {
-
-    function LiteralValue(value) {
-      this.value = (function() {
-        switch (value.toLowerCase()) {
-          case 'true':
-            return true;
-          case 'false':
-            return false;
-          default:
-            return null;
-        }
-      })();
-    }
-
-    LiteralValue.prototype.toString = function() {
-      if (this.value != null) {
-        return this.value.toString().toUpperCase();
-      } else {
-        return 'NULL';
-      }
-    };
-
-    return LiteralValue;
-
-  })();
-
-  exports.FunctionValue = FunctionValue = (function() {
-
-    function FunctionValue(name, _arguments, udf) {
-      this.name = name;
-      this.arguments = _arguments != null ? _arguments : [];
-      this.udf = udf != null ? udf : false;
-      null;
-    }
-
-    FunctionValue.prototype.toString = function() {
-      return "" + this.name + "(" + (this.arguments.join(', ')) + ")";
-    };
-
-    return FunctionValue;
-
-  })();
-
-  exports.Order = Order = (function() {
-
-    function Order(orderings) {
-      this.orderings = orderings;
-    }
-
-    Order.prototype.toString = function() {
-      return "ORDER BY " + (this.orderings.join(', '));
-    };
-
-    return Order;
-
-  })();
-
-  exports.OrderArgument = OrderArgument = (function() {
-
-    function OrderArgument(value, direction) {
-      this.value = value;
-      this.direction = direction != null ? direction : 'ASC';
-      null;
-    }
-
-    OrderArgument.prototype.toString = function() {
-      return "" + this.value + " " + this.direction;
-    };
-
-    return OrderArgument;
-
-  })();
-
-  exports.Limit = Limit = (function() {
-
-    function Limit(value) {
-      this.value = value;
-      null;
-    }
-
-    Limit.prototype.toString = function() {
-      return "LIMIT " + this.value;
-    };
-
-    return Limit;
-
-  })();
-
-  exports.Table = Table = (function() {
-
-    function Table(name, win, winFn, winArg) {
-      this.name = name;
-      this.win = win != null ? win : null;
-      this.winFn = winFn != null ? winFn : null;
-      this.winArg = winArg != null ? winArg : null;
-      null;
-    }
-
-    Table.prototype.toString = function() {
-      if (this.win) {
-        return "" + this.name + "." + this.win + ":" + this.winFn + "(" + this.winArg + ")";
-      } else {
-        return this.name.toString();
-      }
-    };
-
-    return Table;
-
-  })();
-
-  exports.Group = Group = (function() {
-
-    function Group(fields) {
-      this.fields = fields;
-      this.having = null;
-    }
-
-    Group.prototype.toString = function() {
-      var ret;
-      ret = ["GROUP BY " + (this.fields.join(', '))];
-      if (this.having) ret.push(this.having.toString());
-      return ret.join("\n");
-    };
-
-    return Group;
-
-  })();
-
-  exports.Where = Where = (function() {
-
-    function Where(conditions) {
-      this.conditions = conditions;
-      null;
-    }
-
-    Where.prototype.toString = function() {
-      return "WHERE " + this.conditions;
-    };
-
-    return Where;
-
-  })();
-
-  exports.Having = Having = (function() {
-
-    function Having(conditions) {
-      this.conditions = conditions;
-      null;
-    }
-
-    Having.prototype.toString = function() {
-      return "HAVING " + this.conditions;
-    };
-
-    return Having;
-
-  })();
-
-  exports.Op = Op = (function() {
-
-    function Op(operation, left, right) {
-      this.operation = operation;
-      this.left = left;
-      this.right = right;
-      null;
-    }
-
-    Op.prototype.toString = function() {
-      return "(" + this.left + " " + this.operation + " " + this.right + ")";
-    };
-
-    return Op;
-
-  })();
-
-  exports.Field = Field = (function() {
-
-    function Field(field, name) {
-      this.field = field;
-      this.name = name != null ? name : null;
-      null;
-    }
-
-    Field.prototype.toString = function() {
-      if (this.name) {
-        return "" + this.field + " AS " + this.name;
-      } else {
-        return this.field.toString();
-      }
-    };
-
-    return Field;
-
-  })();
-
-  exports.Star = Star = (function() {
-
-    function Star() {
-      null;
-    }
-
-    Star.prototype.toString = function() {
-      return '*';
-    };
-
-    Star.prototype.star = true;
-
-    return Star;
-
-  })();
-
-}).call(this);
-
-};require['./parser'] = new function() {
-  var exports = this;
-  (function() {
-  var buildParser;
-
-  buildParser = function() {
-    var parser;
-    parser = require('./compiled_parser').parser;
-    parser.lexer = {
-      lex: function() {
-        var tag, _ref;
-        _ref = this.tokens[this.pos++] || [''], tag = _ref[0], this.yytext = _ref[1], this.yylineno = _ref[2];
-        return tag;
-      },
-      setInput: function(tokens) {
-        this.tokens = tokens;
-        return this.pos = 0;
-      },
-      upcomingInput: function() {
-        return "";
-      }
-    };
-    parser.yy = require('./nodes');
-    return parser;
-  };
-
-  exports.parser = buildParser();
-
-  exports.parse = function(str) {
-    return buildParser().parse(str);
-  };
-
-}).call(this);
-
-};require['./sql_parser'] = new function() {
-  var exports = this;
-  (function() {
-
-  exports.lexer = require('./lexer');
-
-  exports.parser = require('./parser');
-
-  exports.nodes = require('./nodes');
-
-  exports.parse = function(sql) {
-    return exports.parser.parse(exports.lexer.tokenize(sql));
-  };
-
-}).call(this);
-
-};
-    return require['./sql_parser']
-  }();
-
-  if(typeof define === 'function' && define.amd) {
-    define(function() { return SQLParser });
-  } else { root.SQLParser = SQLParser }
-}(this));
\ No newline at end of file
diff --git a/lib/grammar.js b/lib/grammar.js
deleted file mode 100644
index 78dbc96..0000000
--- a/lib/grammar.js
+++ /dev/null
@@ -1,336 +0,0 @@
-// Generated by CoffeeScript 1.8.0
-(function() {
-  var Parser, alt, alternatives, grammar, name, o, operators, token, tokens, unwrap;
-
-  Parser = require('jison').Parser;
-
-  unwrap = /^function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/;
-
-  o = function(patternString, action, options) {
-    var match;
-    patternString = patternString.replace(/\s{2,}/g, ' ');
-    if (!action) {
-      return [patternString, '$$ = $1;', options];
-    }
-    action = (match = unwrap.exec(action)) ? match[1] : "(" + action + "())";
-    action = action.replace(/\bnew /g, '$&yy.');
-    return [patternString, "$$ = " + action + ";", options];
-  };
-
-  grammar = {
-    Root: [o('Query EOF')],
-    Query: [
-      o("SelectQuery"), o("SelectQuery Unions", function() {
-        $1.unions = $2;
-        return $1;
-      })
-    ],
-    SelectQuery: [o("SelectWithLimitQuery"), o("BasicSelectQuery")],
-    BasicSelectQuery: [
-      o('Select'), o('Select OrderClause', function() {
-        $1.order = $2;
-        return $1;
-      }), o('Select GroupClause', function() {
-        $1.group = $2;
-        return $1;
-      }), o('Select GroupClause OrderClause', function() {
-        $1.group = $2;
-        $1.order = $3;
-        return $1;
-      })
-    ],
-    SelectWithLimitQuery: [
-      o('SelectQuery LimitClause', function() {
-        $1.limit = $2;
-        return $1;
-      })
-    ],
-    Select: [
-      o('SelectClause'), o('SelectClause WhereClause', function() {
-        $1.where = $2;
-        return $1;
-      })
-    ],
-    SelectClause: [
-      o('SELECT Fields FROM Table', function() {
-        return new Select($2, $4, false);
-      }), o('SELECT DISTINCT Fields FROM Table', function() {
-        return new Select($3, $5, true);
-      }), o('SELECT Fields FROM Table Joins', function() {
-        return new Select($2, $4, false, $5);
-      }), o('SELECT DISTINCT Fields FROM Table Joins', function() {
-        return new Select($3, $5, true, $6);
-      })
-    ],
-    Table: [
-      o('Literal', function() {
-        return new Table($1);
-      }), o('Literal Literal', function() {
-        return new Table($1, $2);
-      }), o('Literal AS Literal', function() {
-        return new Table($1, $3);
-      }), o('LEFT_PAREN List RIGHT_PAREN', function() {
-        return $2;
-      }), o('LEFT_PAREN Query RIGHT_PAREN', function() {
-        return new SubSelect($2);
-      }), o('LEFT_PAREN Query RIGHT_PAREN Literal', function() {
-        return new SubSelect($2, $4);
-      }), o('Literal WINDOW WINDOW_FUNCTION LEFT_PAREN Number RIGHT_PAREN', function() {
-        return new Table($1, null, $2, $3, $5);
-      })
-    ],
-    Unions: [
-      o('Union', function() {
-        return [$1];
-      }), o('Unions Union', function() {
-        return $1.concat($3);
-      })
-    ],
-    Union: [
-      o('UNION SelectQuery', function() {
-        return new Union($2);
-      }), o('UNION ALL SelectQuery', function() {
-        return new Union($3, true);
-      })
-    ],
-    Joins: [
-      o('Join', function() {
-        return [$1];
-      }), o('Joins Join', function() {
-        return $1.concat($2);
-      })
-    ],
-    Join: [
-      o('JOIN Table ON Expression', function() {
-        return new Join($2, $4);
-      }), o('LEFT JOIN Table ON Expression', function() {
-        return new Join($3, $5, 'LEFT');
-      }), o('RIGHT JOIN Table ON Expression', function() {
-        return new Join($3, $5, 'RIGHT');
-      }), o('LEFT INNER JOIN Table ON Expression', function() {
-        return new Join($4, $6, 'LEFT', 'INNER');
-      }), o('RIGHT INNER JOIN Table ON Expression', function() {
-        return new Join($4, $6, 'RIGHT', 'INNER');
-      }), o('LEFT OUTER JOIN Table ON Expression', function() {
-        return new Join($4, $6, 'LEFT', 'OUTER');
-      }), o('RIGHT OUTER JOIN Table ON Expression', function() {
-        return new Join($4, $6, 'RIGHT', 'OUTER');
-      })
-    ],
-    WhereClause: [
-      o('WHERE Expression', function() {
-        return new Where($2);
-      })
-    ],
-    LimitClause: [
-      o('LIMIT Number', function() {
-        return new Limit($2);
-      }), o('LIMIT Number SEPARATOR Number', function() {
-        return new Limit($4, $2);
-      }), o('LIMIT Number OFFSET Number', function() {
-        return new Limit($2, $4);
-      })
-    ],
-    OrderClause: [
-      o('ORDER BY OrderArgs', function() {
-        return new Order($3);
-      }), o('ORDER BY OrderArgs OffsetClause', function() {
-        return new Order($3, $4);
-      })
-    ],
-    OrderArgs: [
-      o('OrderArg', function() {
-        return [$1];
-      }), o('OrderArgs SEPARATOR OrderArg', function() {
-        return $1.concat($3);
-      })
-    ],
-    OrderArg: [
-      o('Value', function() {
-        return new OrderArgument($1, 'ASC');
-      }), o('Value DIRECTION', function() {
-        return new OrderArgument($1, $2);
-      })
-    ],
-    OffsetClause: [
-      o('OFFSET OffsetRows', function() {
-        return new Offset($2);
-      }), o('OFFSET OffsetRows FetchClause', function() {
-        return new Offset($2, $3);
-      })
-    ],
-    OffsetRows: [
-      o('Number ROW', function() {
-        return $1;
-      }), o('Number ROWS', function() {
-        return $1;
-      })
-    ],
-    FetchClause: [
-      o('FETCH FIRST OffsetRows ONLY', function() {
-        return $3;
-      }), o('FETCH NEXT OffsetRows ONLY', function() {
-        return $3;
-      })
-    ],
-    GroupClause: [
-      o('GroupBasicClause'), o('GroupBasicClause HavingClause', function() {
-        $1.having = $2;
-        return $1;
-      })
-    ],
-    GroupBasicClause: [
-      o('GROUP BY ArgumentList', function() {
-        return new Group($3);
-      })
-    ],
-    HavingClause: [
-      o('HAVING Expression', function() {
-        return new Having($2);
-      })
-    ],
-    Expression: [
-      o('LEFT_PAREN Expression RIGHT_PAREN', function() {
-        return $2;
-      }), o('Expression MATH Expression', function() {
-        return new Op($2, $1, $3);
-      }), o('Expression MATH_MULTI Expression', function() {
-        return new Op($2, $1, $3);
-      }), o('Expression OPERATOR Expression', function() {
-        return new Op($2, $1, $3);
-      }), o('Expression BETWEEN BetweenExpression', function() {
-        return new Op($2, $1, $3);
-      }), o('Expression CONDITIONAL Expression', function() {
-        return new Op($2, $1, $3);
-      }), o('Value SUB_SELECT_OP LEFT_PAREN List RIGHT_PAREN', function() {
-        return new Op($2, $1, $4);
-      }), o('Value SUB_SELECT_OP SubSelectExpression', function() {
-        return new Op($2, $1, $3);
-      }), o('SUB_SELECT_UNARY_OP SubSelectExpression', function() {
-        return new UnaryOp($1, $2);
-      }), o('SubSelectExpression'), o('Value')
-    ],
-    BetweenExpression: [
-      o('Expression CONDITIONAL Expression', function() {
-        return new BetweenOp([$1, $3]);
-      })
-    ],
-    SubSelectExpression: [
-      o('LEFT_PAREN Query RIGHT_PAREN', function() {
-        return new SubSelect($2);
-      })
-    ],
-    Value: [o('Literal'), o('Number'), o('String'), o('Function'), o('UserFunction'), o('Boolean'), o('Parameter')],
-    List: [
-      o('ArgumentList', function() {
-        return new ListValue($1);
-      })
-    ],
-    Number: [
-      o('NUMBER', function() {
-        return new NumberValue($1);
-      })
-    ],
-    Boolean: [
-      o('BOOLEAN', function() {
-        return new BooleanValue($1);
-      })
-    ],
-    Parameter: [
-      o('PARAMETER', function() {
-        return new ParameterValue($1);
-      })
-    ],
-    String: [
-      o('STRING', function() {
-        return new StringValue($1, "'");
-      }), o('DBLSTRING', function() {
-        return new StringValue($1, '"');
-      })
-    ],
-    Literal: [
-      o('LITERAL', function() {
-        return new LiteralValue($1);
-      }), o('Literal DOT LITERAL', function() {
-        return new LiteralValue($1, $3);
-      })
-    ],
-    Function: [
-      o("FUNCTION LEFT_PAREN AggregateArgumentList RIGHT_PAREN", function() {
-        return new FunctionValue($1, $3);
-      })
-    ],
-    UserFunction: [
-      o("LITERAL LEFT_PAREN RIGHT_PAREN", function() {
-        return new FunctionValue($1, null, true);
-      }), o("LITERAL LEFT_PAREN AggregateArgumentList RIGHT_PAREN", function() {
-        return new FunctionValue($1, $3, true);
-      })
-    ],
-    AggregateArgumentList: [
-      o('ArgumentList', function() {
-        return new ArgumentListValue($1);
-      }), o('DISTINCT ArgumentList', function() {
-        return new ArgumentListValue($2, true);
-      })
-    ],
-    ArgumentList: [
-      o('Expression', function() {
-        return [$1];
-      }), o('ArgumentList SEPARATOR Value', function() {
-        return $1.concat($3);
-      })
-    ],
-    Fields: [
-      o('Field', function() {
-        return [$1];
-      }), o('Fields SEPARATOR Field', function() {
-        return $1.concat($3);
-      })
-    ],
-    Field: [
-      o('STAR', function() {
-        return new Star();
-      }), o('Expression', function() {
-        return new Field($1);
-      }), o('Expression AS Literal', function() {
-        return new Field($1, $3);
-      })
-    ]
-  };
-
-  tokens = [];
-
-  operators = [['left', 'Op'], ['left', 'MATH_MULTI'], ['left', 'MATH'], ['left', 'OPERATOR'], ['left', 'CONDITIONAL']];
-
-  for (name in grammar) {
-    alternatives = grammar[name];
-    grammar[name] = (function() {
-      var _i, _j, _len, _len1, _ref, _results;
-      _results = [];
-      for (_i = 0, _len = alternatives.length; _i < _len; _i++) {
-        alt = alternatives[_i];
-        _ref = alt[0].split(' ');
-        for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
-          token = _ref[_j];
-          if (!grammar[token]) {
-            tokens.push(token);
-          }
-        }
-        if (name === 'Root') {
-          alt[1] = "return " + alt[1];
-        }
-        _results.push(alt);
-      }
-      return _results;
-    })();
-  }
-
-  exports.parser = new Parser({
-    tokens: tokens.join(' '),
-    bnf: grammar,
-    operators: operators.reverse(),
-    startSymbol: 'Root'
-  });
-
-}).call(this);
diff --git a/lib/lexer.js b/lib/lexer.js
deleted file mode 100644
index 3f0ed9c..0000000
--- a/lib/lexer.js
+++ /dev/null
@@ -1,247 +0,0 @@
-// Generated by CoffeeScript 1.8.0
-(function() {
-  var Lexer;
-
-  Lexer = (function() {
-    var BOOLEAN, DBLSTRING, LITERAL, MATH, MATH_MULTI, NUMBER, PARAMETER, SEPARATOR, SQL_BETWEENS, SQL_CONDITIONALS, SQL_FUNCTIONS, SQL_OPERATORS, SQL_SORT_ORDERS, STAR, STRING, SUB_SELECT_OP, SUB_SELECT_UNARY_OP, WHITESPACE;
-
-    function Lexer(sql, opts) {
-      var bytesConsumed, i;
-      if (opts == null) {
-        opts = {};
-      }
-      this.sql = sql;
-      this.preserveWhitespace = opts.preserveWhitespace || false;
-      this.tokens = [];
-      this.currentLine = 1;
-      i = 0;
-      while (this.chunk = sql.slice(i)) {
-        bytesConsumed = this.keywordToken() || this.starToken() || this.booleanToken() || this.functionToken() || this.windowExtension() || this.sortOrderToken() || this.seperatorToken() || this.operatorToken() || this.mathToken() || this.dotToken() || this.conditionalToken() || this.betweenToken() || this.subSelectOpToken() || this.subSelectUnaryOpToken() || this.numberToken() || this.stringToken() || this.parameterToken() || this.parensToken() || this.whitespaceToken() || this.literalToken();
-        if (bytesConsumed < 1) {
-          throw new Error("NOTHING CONSUMED: Stopped at - '" + (this.chunk.slice(0, 30)) + "'");
-        }
-        i += bytesConsumed;
-      }
-      this.token('EOF', '');
-      this.postProcess();
-    }
-
-    Lexer.prototype.postProcess = function() {
-      var i, next_token, token, _i, _len, _ref, _results;
-      _ref = this.tokens;
-      _results = [];
-      for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
-        token = _ref[i];
-        if (token[0] === 'STAR') {
-          next_token = this.tokens[i + 1];
-          if (!(next_token[0] === 'SEPARATOR' || next_token[0] === 'FROM')) {
-            _results.push(token[0] = 'MATH_MULTI');
-          } else {
-            _results.push(void 0);
-          }
-        } else {
-          _results.push(void 0);
-        }
-      }
-      return _results;
-    };
-
-    Lexer.prototype.token = function(name, value) {
-      return this.tokens.push([name, value, this.currentLine]);
-    };
-
-    Lexer.prototype.tokenizeFromRegex = function(name, regex, part, lengthPart, output) {
-      var match, partMatch;
-      if (part == null) {
-        part = 0;
-      }
-      if (lengthPart == null) {
-        lengthPart = part;
-      }
-      if (output == null) {
-        output = true;
-      }
-      if (!(match = regex.exec(this.chunk))) {
-        return 0;
-      }
-      partMatch = match[part];
-      if (output) {
-        this.token(name, partMatch);
-      }
-      return match[lengthPart].length;
-    };
-
-    Lexer.prototype.tokenizeFromWord = function(name, word) {
-      var match, matcher;
-      if (word == null) {
-        word = name;
-      }
-      word = this.regexEscape(word);
-      matcher = /^\w+$/.test(word) ? new RegExp("^(" + word + ")\\b", 'ig') : new RegExp("^(" + word + ")", 'ig');
-      match = matcher.exec(this.chunk);
-      if (!match) {
-        return 0;
-      }
-      this.token(name, match[1]);
-      return match[1].length;
-    };
-
-    Lexer.prototype.tokenizeFromList = function(name, list) {
-      var entry, ret, _i, _len;
-      ret = 0;
-      for (_i = 0, _len = list.length; _i < _len; _i++) {
-        entry = list[_i];
-        ret = this.tokenizeFromWord(name, entry);
-        if (ret > 0) {
-          break;
-        }
-      }
-      return ret;
-    };
-
-    Lexer.prototype.keywordToken = function() {
-      return this.tokenizeFromWord('SELECT') || this.tokenizeFromWord('DISTINCT') || this.tokenizeFromWord('FROM') || this.tokenizeFromWord('WHERE') || this.tokenizeFromWord('GROUP') || this.tokenizeFromWord('ORDER') || this.tokenizeFromWord('BY') || this.tokenizeFromWord('HAVING') || this.tokenizeFromWord('LIMIT') || this.tokenizeFromWord('JOIN') || this.tokenizeFromWord('LEFT') || this.tokenizeFromWord('RIGHT') || this.tokenizeFromWord('INNER') || this.tokenizeFromWord('OUTER') || this.tokenizeFromWord('ON') || this.tokenizeFromWord('AS') || this.tokenizeFromWord('UNION') || this.tokenizeFromWord('ALL') || this.tokenizeFromWord('LIMIT') || this.tokenizeFromWord('OFFSET') || this.tokenizeFromWord('FETCH') || this.tokenizeFromWord('ROW') || this.tokenizeFromWord('ROWS') || this.tokenizeFromWord('ONLY') || this.tokenizeFromWord('NEXT') || this.tokenizeFromWord('FIRST');
-    };
-
-    Lexer.prototype.dotToken = function() {
-      return this.tokenizeFromWord('DOT', '.');
-    };
-
-    Lexer.prototype.operatorToken = function() {
-      return this.tokenizeFromList('OPERATOR', SQL_OPERATORS);
-    };
-
-    Lexer.prototype.mathToken = function() {
-      return this.tokenizeFromList('MATH', MATH) || this.tokenizeFromList('MATH_MULTI', MATH_MULTI);
-    };
-
-    Lexer.prototype.conditionalToken = function() {
-      return this.tokenizeFromList('CONDITIONAL', SQL_CONDITIONALS);
-    };
-
-    Lexer.prototype.betweenToken = function() {
-      return this.tokenizeFromList('BETWEEN', SQL_BETWEENS);
-    };
-
-    Lexer.prototype.subSelectOpToken = function() {
-      return this.tokenizeFromList('SUB_SELECT_OP', SUB_SELECT_OP);
-    };
-
-    Lexer.prototype.subSelectUnaryOpToken = function() {
-      return this.tokenizeFromList('SUB_SELECT_UNARY_OP', SUB_SELECT_UNARY_OP);
-    };
-
-    Lexer.prototype.functionToken = function() {
-      return this.tokenizeFromList('FUNCTION', SQL_FUNCTIONS);
-    };
-
-    Lexer.prototype.sortOrderToken = function() {
-      return this.tokenizeFromList('DIRECTION', SQL_SORT_ORDERS);
-    };
-
-    Lexer.prototype.booleanToken = function() {
-      return this.tokenizeFromList('BOOLEAN', BOOLEAN);
-    };
-
-    Lexer.prototype.starToken = function() {
-      return this.tokenizeFromRegex('STAR', STAR);
-    };
-
-    Lexer.prototype.seperatorToken = function() {
-      return this.tokenizeFromRegex('SEPARATOR', SEPARATOR);
-    };
-
-    Lexer.prototype.literalToken = function() {
-      return this.tokenizeFromRegex('LITERAL', LITERAL, 1, 0);
-    };
-
-    Lexer.prototype.numberToken = function() {
-      return this.tokenizeFromRegex('NUMBER', NUMBER);
-    };
-
-    Lexer.prototype.parameterToken = function() {
-      return this.tokenizeFromRegex('PARAMETER', PARAMETER);
-    };
-
-    Lexer.prototype.stringToken = function() {
-      return this.tokenizeFromRegex('STRING', STRING, 1, 0) || this.tokenizeFromRegex('DBLSTRING', DBLSTRING, 1, 0);
-    };
-
-    Lexer.prototype.parensToken = function() {
-      return this.tokenizeFromRegex('LEFT_PAREN', /^\(/) || this.tokenizeFromRegex('RIGHT_PAREN', /^\)/);
-    };
-
-    Lexer.prototype.windowExtension = function() {
-      var match;
-      match = /^\.(win):(length|time)/i.exec(this.chunk);
-      if (!match) {
-        return 0;
-      }
-      this.token('WINDOW', match[1]);
-      this.token('WINDOW_FUNCTION', match[2]);
-      return match[0].length;
-    };
-
-    Lexer.prototype.whitespaceToken = function() {
-      var match, newlines, partMatch;
-      if (!(match = WHITESPACE.exec(this.chunk))) {
-        return 0;
-      }
-      partMatch = match[0];
-      newlines = partMatch.replace(/[^\n]/, '').length;
-      this.currentLine += newlines;
-      if (this.preserveWhitespace) {
-        this.token(name, partMatch);
-      }
-      return partMatch.length;
-    };
-
-    Lexer.prototype.regexEscape = function(str) {
-      return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
-    };
-
-    SQL_FUNCTIONS = ['AVG', 'COUNT', 'MIN', 'MAX', 'SUM'];
-
-    SQL_SORT_ORDERS = ['ASC', 'DESC'];
-
-    SQL_OPERATORS = ['=', '!=', '>=', '>', '<=', '<>', '<', 'LIKE', 'IS NOT', 'IS'];
-
-    SUB_SELECT_OP = ['IN', 'NOT IN', 'ANY', 'ALL', 'SOME'];
-
-    SUB_SELECT_UNARY_OP = ['EXISTS'];
-
-    SQL_CONDITIONALS = ['AND', 'OR'];
-
-    SQL_BETWEENS = ['BETWEEN', 'NOT BETWEEN'];
-
-    BOOLEAN = ['TRUE', 'FALSE', 'NULL'];
-
-    MATH = ['+', '-'];
-
-    MATH_MULTI = ['/', '*'];
-
-    STAR = /^\*/;
-
-    SEPARATOR = /^,/;
-
-    WHITESPACE = /^[ \n\r]+/;
-
-    LITERAL = /^`?([a-z_][a-z0-9_]{0,})`?/i;
-
-    PARAMETER = /^\$[0-9]+/;
-
-    NUMBER = /^[0-9]+(\.[0-9]+)?/;
-
-    STRING = /^'([^\\']*(?:\\.[^\\']*)*)'/;
-
-    DBLSTRING = /^"([^\\"]*(?:\\.[^\\"]*)*)"/;
-
-    return Lexer;
-
-  })();
-
-  exports.tokenize = function(sql, opts) {
-    return (new Lexer(sql, opts)).tokens;
-  };
-
-}).call(this);
diff --git a/lib/nodes.js b/lib/nodes.js
deleted file mode 100644
index 6bb9bb9..0000000
--- a/lib/nodes.js
+++ /dev/null
@@ -1,478 +0,0 @@
-// Generated by CoffeeScript 1.8.0
-(function() {
-  var ArgumentListValue, BetweenOp, Field, FunctionValue, Group, Having, Join, Limit, ListValue, LiteralValue, Offset, Op, Order, OrderArgument, ParameterValue, Select, Star, StringValue, SubSelect, Table, UnaryOp, Union, Where, indent;
-
-  indent = function(str) {
-    var line;
-    return ((function() {
-      var _i, _len, _ref, _results;
-      _ref = str.split("\n");
-      _results = [];
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        line = _ref[_i];
-        _results.push("  " + line);
-      }
-      return _results;
-    })()).join("\n");
-  };
-
-  exports.Select = Select = (function() {
-    function Select(fields, source, distinct, joins, unions) {
-      this.fields = fields;
-      this.source = source;
-      this.distinct = distinct != null ? distinct : false;
-      this.joins = joins != null ? joins : [];
-      this.unions = unions != null ? unions : [];
-      this.order = null;
-      this.group = null;
-      this.where = null;
-      this.limit = null;
-    }
-
-    Select.prototype.toString = function() {
-      var join, ret, union, _i, _j, _len, _len1, _ref, _ref1;
-      ret = ["SELECT " + (this.fields.join(', '))];
-      ret.push(indent("FROM " + this.source));
-      _ref = this.joins;
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        join = _ref[_i];
-        ret.push(indent(join.toString()));
-      }
-      if (this.where) {
-        ret.push(indent(this.where.toString()));
-      }
-      if (this.group) {
-        ret.push(indent(this.group.toString()));
-      }
-      if (this.order) {
-        ret.push(indent(this.order.toString()));
-      }
-      if (this.limit) {
-        ret.push(indent(this.limit.toString()));
-      }
-      _ref1 = this.unions;
-      for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
-        union = _ref1[_j];
-        ret.push(union.toString());
-      }
-      return ret.join("\n");
-    };
-
-    return Select;
-
-  })();
-
-  exports.SubSelect = SubSelect = (function() {
-    function SubSelect(select, name) {
-      this.select = select;
-      this.name = name != null ? name : null;
-      null;
-    }
-
-    SubSelect.prototype.toString = function() {
-      var ret;
-      ret = [];
-      ret.push('(');
-      ret.push(indent(this.select.toString()));
-      ret.push(this.name ? ") " + (this.name.toString()) : ")");
-      return ret.join("\n");
-    };
-
-    return SubSelect;
-
-  })();
-
-  exports.Join = Join = (function() {
-    function Join(right, conditions, side, mode) {
-      this.right = right;
-      this.conditions = conditions != null ? conditions : null;
-      this.side = side != null ? side : null;
-      this.mode = mode != null ? mode : null;
-      null;
-    }
-
-    Join.prototype.toString = function() {
-      var ret;
-      ret = '';
-      if (this.side != null) {
-        ret += "" + this.side + " ";
-      }
-      if (this.mode != null) {
-        ret += "" + this.mode + " ";
-      }
-      return ret + ("JOIN " + this.right + "\n") + indent("ON " + this.conditions);
-    };
-
-    return Join;
-
-  })();
-
-  exports.Union = Union = (function() {
-    function Union(query, all) {
-      this.query = query;
-      this.all = all != null ? all : false;
-      null;
-    }
-
-    Union.prototype.toString = function() {
-      var all;
-      all = this.all ? ' ALL' : '';
-      return "UNION" + all + "\n" + (this.query.toString());
-    };
-
-    return Union;
-
-  })();
-
-  exports.LiteralValue = LiteralValue = (function() {
-    function LiteralValue(value, value2) {
-      this.value = value;
-      this.value2 = value2 != null ? value2 : null;
-      if (this.value2) {
-        this.nested = true;
-        this.values = this.value.values;
-        this.values.push(value2);
-      } else {
-        this.nested = false;
-        this.values = [this.value];
-      }
-    }
-
-    LiteralValue.prototype.toString = function() {
-      return "`" + (this.values.join('.')) + "`";
-    };
-
-    return LiteralValue;
-
-  })();
-
-  exports.StringValue = StringValue = (function() {
-    function StringValue(value, quoteType) {
-      this.value = value;
-      this.quoteType = quoteType != null ? quoteType : "''";
-      null;
-    }
-
-    StringValue.prototype.toString = function() {
-      return "" + this.quoteType + this.value + this.quoteType;
-    };
-
-    return StringValue;
-
-  })();
-
-  exports.NumberValue = LiteralValue = (function() {
-    function LiteralValue(value) {
-      this.value = Number(value);
-    }
-
-    LiteralValue.prototype.toString = function() {
-      return this.value.toString();
-    };
-
-    return LiteralValue;
-
-  })();
-
-  exports.ListValue = ListValue = (function() {
-    function ListValue(value) {
-      this.value = value;
-    }
-
-    ListValue.prototype.toString = function() {
-      return "(" + (this.value.join(', ')) + ")";
-    };
-
-    return ListValue;
-
-  })();
-
-  exports.ParameterValue = ParameterValue = (function() {
-    function ParameterValue(value) {
-      this.value = value;
-      this.index = parseInt(value.substr(1), 10) - 1;
-    }
-
-    ParameterValue.prototype.toString = function() {
-      return "" + this.value;
-    };
-
-    return ParameterValue;
-
-  })();
-
-  exports.ArgumentListValue = ArgumentListValue = (function() {
-    function ArgumentListValue(value, distinct) {
-      this.value = value;
-      this.distinct = distinct != null ? distinct : false;
-      null;
-    }
-
-    ArgumentListValue.prototype.toString = function() {
-      if (this.distinct) {
-        return "DISTINCT " + (this.value.join(', '));
-      } else {
-        return "" + (this.value.join(', '));
-      }
-    };
-
-    return ArgumentListValue;
-
-  })();
-
-  exports.BooleanValue = LiteralValue = (function() {
-    function LiteralValue(value) {
-      this.value = (function() {
-        switch (value.toLowerCase()) {
-          case 'true':
-            return true;
-          case 'false':
-            return false;
-          default:
-            return null;
-        }
-      })();
-    }
-
-    LiteralValue.prototype.toString = function() {
-      if (this.value != null) {
-        return this.value.toString().toUpperCase();
-      } else {
-        return 'NULL';
-      }
-    };
-
-    return LiteralValue;
-
-  })();
-
-  exports.FunctionValue = FunctionValue = (function() {
-    function FunctionValue(name, _arguments, udf) {
-      this.name = name;
-      this["arguments"] = _arguments != null ? _arguments : null;
-      this.udf = udf != null ? udf : false;
-      null;
-    }
-
-    FunctionValue.prototype.toString = function() {
-      if (this["arguments"]) {
-        return "" + (this.name.toUpperCase()) + "(" + (this["arguments"].toString()) + ")";
-      } else {
-        return "" + (this.name.toUpperCase()) + "()";
-      }
-    };
-
-    return FunctionValue;
-
-  })();
-
-  exports.Order = Order = (function() {
-    function Order(orderings, offset) {
-      this.orderings = orderings;
-      this.offset = offset;
-    }
-
-    Order.prototype.toString = function() {
-      return ("ORDER BY " + (this.orderings.join(', '))) + (this.offset ? "\n" + this.offset.toString() : "");
-    };
-
-    return Order;
-
-  })();
-
-  exports.OrderArgument = OrderArgument = (function() {
-    function OrderArgument(value, direction) {
-      this.value = value;
-      this.direction = direction != null ? direction : 'ASC';
-      null;
-    }
-
-    OrderArgument.prototype.toString = function() {
-      return "" + this.value + " " + this.direction;
-    };
-
-    return OrderArgument;
-
-  })();
-
-  exports.Offset = Offset = (function() {
-    function Offset(row_count, limit) {
-      this.row_count = row_count;
-      this.limit = limit;
-      null;
-    }
-
-    Offset.prototype.toString = function() {
-      return ("OFFSET " + this.row_count + " ROWS") + (this.limit ? "\nFETCH NEXT " + this.limit + " ROWS ONLY" : "");
-    };
-
-    return Offset;
-
-  })();
-
-  exports.Limit = Limit = (function() {
-    function Limit(value, offset) {
-      this.value = value;
-      this.offset = offset;
-      null;
-    }
-
-    Limit.prototype.toString = function() {
-      return ("LIMIT " + this.value) + (this.offset ? "\nOFFSET " + this.offset : "");
-    };
-
-    return Limit;
-
-  })();
-
-  exports.Table = Table = (function() {
-    function Table(name, alias, win, winFn, winArg) {
-      this.name = name;
-      this.alias = alias != null ? alias : null;
-      this.win = win != null ? win : null;
-      this.winFn = winFn != null ? winFn : null;
-      this.winArg = winArg != null ? winArg : null;
-      null;
-    }
-
-    Table.prototype.toString = function() {
-      if (this.win) {
-        return "" + this.name + "." + this.win + ":" + this.winFn + "(" + this.winArg + ")";
-      } else if (this.alias) {
-        return "" + this.name + " AS " + this.alias;
-      } else {
-        return this.name.toString();
-      }
-    };
-
-    return Table;
-
-  })();
-
-  exports.Group = Group = (function() {
-    function Group(fields) {
-      this.fields = fields;
-      this.having = null;
-    }
-
-    Group.prototype.toString = function() {
-      var ret;
-      ret = ["GROUP BY " + (this.fields.join(', '))];
-      if (this.having) {
-        ret.push(this.having.toString());
-      }
-      return ret.join("\n");
-    };
-
-    return Group;
-
-  })();
-
-  exports.Where = Where = (function() {
-    function Where(conditions) {
-      this.conditions = conditions;
-      null;
-    }
-
-    Where.prototype.toString = function() {
-      return "WHERE " + this.conditions;
-    };
-
-    return Where;
-
-  })();
-
-  exports.Having = Having = (function() {
-    function Having(conditions) {
-      this.conditions = conditions;
-      null;
-    }
-
-    Having.prototype.toString = function() {
-      return "HAVING " + this.conditions;
-    };
-
-    return Having;
-
-  })();
-
-  exports.Op = Op = (function() {
-    function Op(operation, left, right) {
-      this.operation = operation;
-      this.left = left;
-      this.right = right;
-      null;
-    }
-
-    Op.prototype.toString = function() {
-      return "(" + this.left + " " + (this.operation.toUpperCase()) + " " + this.right + ")";
-    };
-
-    return Op;
-
-  })();
-
-  exports.UnaryOp = UnaryOp = (function() {
-    function UnaryOp(operator, operand) {
-      this.operator = operator;
-      this.operand = operand;
-      null;
-    }
-
-    UnaryOp.prototype.toString = function() {
-      return "(" + (this.operator.toUpperCase()) + " " + this.operand + ")";
-    };
-
-    return UnaryOp;
-
-  })();
-
-  exports.BetweenOp = BetweenOp = (function() {
-    function BetweenOp(value) {
-      this.value = value;
-      null;
-    }
-
-    BetweenOp.prototype.toString = function() {
-      return "" + (this.value.join(' AND '));
-    };
-
-    return BetweenOp;
-
-  })();
-
-  exports.Field = Field = (function() {
-    function Field(field, name) {
-      this.field = field;
-      this.name = name != null ? name : null;
-      null;
-    }
-
-    Field.prototype.toString = function() {
-      if (this.name) {
-        return "" + this.field + " AS " + this.name;
-      } else {
-        return this.field.toString();
-      }
-    };
-
-    return Field;
-
-  })();
-
-  exports.Star = Star = (function() {
-    function Star() {
-      null;
-    }
-
-    Star.prototype.toString = function() {
-      return '*';
-    };
-
-    Star.prototype.star = true;
-
-    return Star;
-
-  })();
-
-}).call(this);
diff --git a/lib/parser.js b/lib/parser.js
deleted file mode 100644
index ec02cf2..0000000
--- a/lib/parser.js
+++ /dev/null
@@ -1,32 +0,0 @@
-// Generated by CoffeeScript 1.8.0
-(function() {
-  var buildParser;
-
-  buildParser = function() {
-    var parser;
-    parser = require('./compiled_parser').parser;
-    parser.lexer = {
-      lex: function() {
-        var tag, _ref;
-        _ref = this.tokens[this.pos++] || [''], tag = _ref[0], this.yytext = _ref[1], this.yylineno = _ref[2];
-        return tag;
-      },
-      setInput: function(tokens) {
-        this.tokens = tokens;
-        return this.pos = 0;
-      },
-      upcomingInput: function() {
-        return "";
-      }
-    };
-    parser.yy = require('./nodes');
-    return parser;
-  };
-
-  exports.parser = buildParser();
-
-  exports.parse = function(str) {
-    return buildParser().parse(str);
-  };
-
-}).call(this);
diff --git a/lib/sql_parser.js b/lib/sql_parser.js
deleted file mode 100644
index e44ee0b..0000000
--- a/lib/sql_parser.js
+++ /dev/null
@@ -1,13 +0,0 @@
-// Generated by CoffeeScript 1.8.0
-(function() {
-  exports.lexer = require('./lexer');
-
-  exports.parser = require('./parser');
-
-  exports.nodes = require('./nodes');
-
-  exports.parse = function(sql) {
-    return exports.parser.parse(exports.lexer.tokenize(sql));
-  };
-
-}).call(this);
diff --git a/package.json b/package.json
index 04c9ffb..77e8f37 100644
--- a/package.json
+++ b/package.json
@@ -1,30 +1,46 @@
 {
-  "name": "sql-parser",
+  "name": "sql-parser-mistic",
   "description": "Lexer and Parser for SQL Syntax",
-  "version": "0.5.0",
-  "scripts": {
-    "test": "./node_modules/.bin/cake build && ./node_modules/.bin/mocha --require should --compilers coffee:coffee-script/register"
-  },
+  "version": "1.3.0",
   "author": {
     "name": "Andy Kent",
     "email": "andy@forward.co.uk"
   },
-  "directories": {
-    "lib" : "./lib"
-  },
-  "dependencies": {
-  },
+  "contributors": [
+    {
+      "name": "Damien \"Mistic\" Sorel",
+      "email": "contact@git.strangeplanet.fr",
+      "url": "https://www.strangeplanet.fr"
+    }
+  ],
+  "files": [
+    "index.js",
+    "src/",
+    "browser/"
+  ],
+  "keywords": [
+    "sql",
+    "lexer",
+    "parser",
+    "ast"
+  ],
   "devDependencies": {
-    "jison": "0.4.15",
-    "coffee-script": "1.8.0",
-    "mocha"     : "2.0.1",
-    "should"    : "4.1.0"
+    "@babel/core": "^7.2.2",
+    "@babel/preset-env": "^7.2.3",
+    "jest": "^28.0.0",
+    "jison": "0.4.18",
+    "rollup": "^2.0.2",
+    "rollup-plugin-babel": "^4.3.0",
+    "rollup-plugin-commonjs": "^10.0.0"
   },
-  "engines": [
-    "node"
-  ],
+  "license": "MIT",
+  "homepage": "https://github.com/mistic100/sql-parser",
   "repository": {
     "type": "git",
-    "url": "http://github.com/forward/sql-parser.git"
+    "url": "http://github.com/mistic100/sql-parser.git"
+  },
+  "scripts": {
+    "compile": "node compile-parser.js && rollup --config rollup.config.js",
+    "test": "jest"
   }
-}
\ No newline at end of file
+}
diff --git a/rollup.config.js b/rollup.config.js
new file mode 100644
index 0000000..96ba928
--- /dev/null
+++ b/rollup.config.js
@@ -0,0 +1,27 @@
+import babel from 'rollup-plugin-babel';
+import commonjs from 'rollup-plugin-commonjs';
+
+const pkg = require('./package.json');
+
+export default {
+    input   : 'src/sql_parser.js',
+    output  : {
+        file     : 'browser/sql-parser.js',
+        name     : 'SQLParser',
+        exports: 'named',
+        format   : 'umd',
+        sourcemap: true,
+        banner   : `/*!
+ * SQLParser (v${pkg.version})
+ * @copyright 2012-2015 ${pkg.author.name} <${pkg.author.email}>
+ * @copyright 2015-${new Date().getFullYear()} ${pkg.contributors[0].name} <${pkg.contributors[0].email}>
+ * @licence ${pkg.license}
+ */`,
+    },
+    plugins : [
+        commonjs(),
+        babel({
+            exclude: 'node_modules/**',
+        }),
+    ]
+};
diff --git a/lib/compiled_parser.js b/src/compiled_parser.js
similarity index 52%
rename from lib/compiled_parser.js
rename to src/compiled_parser.js
index 0e32d9b..6793134 100644
--- a/lib/compiled_parser.js
+++ b/src/compiled_parser.js
@@ -1,4 +1,4 @@
-/* parser generated by jison 0.4.15 */
+/* parser generated by jison 0.4.18 */
 /*
   Returns a Parser object of the following structure:
 
@@ -72,12 +72,12 @@
   }
 */
 var parser = (function(){
-var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,8],$V1=[5,26],$V2=[1,14],$V3=[1,13],$V4=[5,26,31,42],$V5=[1,17],$V6=[5,26,31,42,45,62],$V7=[1,27],$V8=[1,29],$V9=[1,39],$Va=[1,43],$Vb=[1,44],$Vc=[1,40],$Vd=[1,41],$Ve=[1,38],$Vf=[1,42],$Vg=[1,25],$Vh=[5,26,31],$Vi=[5,26,31,42,45],$Vj=[1,56],$Vk=[18,43],$Vl=[1,59],$Vm=[1,60],$Vn=[1,61],$Vo=[1,62],$Vp=[1,63],$Vq=[5,18,23,26,31,34,37,38,41,42,43,45,62,64,65,66,67,68,70],$Vr=[5,18,23,26,31,34,37,38,41,42,43,44,45,51,62,64,65,66,67,68,70,71],$Vs=[1,69],$Vt=[2,83],$Vu=[1,83],$Vv=[1,84],$Vw=[1,102],$Vx=[5,26,31,42,43,44],$Vy=[1,110],$Vz=[5,26,31,42,43,45,64],$VA=[5,26,31,41,42,45,62],$VB=[1,113],$VC=[1,114],$VD=[1,115],$VE=[5,26,31,34,35,37,38,41,42,45,62],$VF=[5,18,23,26,31,34,37,38,41,42,43,45,62,64,70],$VG=[5,26,31,34,37,38,41,42,45,62],$VH=[5,26,31,42,56,58];
-var parser = {trace: function trace() { },
+var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,8],$V1=[5,26],$V2=[1,14],$V3=[1,13],$V4=[5,26,31,42],$V5=[1,17],$V6=[5,26,31,42,45,62],$V7=[1,27],$V8=[1,29],$V9=[1,40],$Va=[1,42],$Vb=[1,46],$Vc=[1,47],$Vd=[1,43],$Ve=[1,44],$Vf=[1,41],$Vg=[1,45],$Vh=[1,25],$Vi=[5,26,31],$Vj=[5,26,31,42,45],$Vk=[1,59],$Vl=[18,43],$Vm=[1,62],$Vn=[1,63],$Vo=[1,64],$Vp=[1,65],$Vq=[1,66],$Vr=[5,18,23,26,31,34,37,38,41,42,43,45,62,64,65,66,67,68,70,78,81,82,83],$Vs=[5,18,23,26,31,34,37,38,41,42,43,44,45,51,62,64,65,66,67,68,70,71,78,81,82,83,89,90,91,92,93,94,96],$Vt=[1,74],$Vu=[1,77],$Vv=[2,93],$Vw=[1,91],$Vx=[1,92],$Vy=[5,18,23,26,31,34,37,38,41,42,43,45,62,64,65,66,67,68,70,78,81,82,83,89,90,91,92,93,94,96],$Vz=[78,81,83],$VA=[1,116],$VB=[5,26,31,42,43,44],$VC=[1,124],$VD=[5,26,31,42,43,45,64],$VE=[5,26,31,41,42,45,62],$VF=[1,127],$VG=[1,128],$VH=[1,129],$VI=[5,26,31,34,35,37,38,41,42,45,62],$VJ=[5,18,23,26,31,34,37,38,41,42,43,45,62,64,70,78,81,82,83],$VK=[5,26,31,34,37,38,41,42,45,62],$VL=[5,26,31,42,56,58];
+var parser = {trace: function trace () { },
 yy: {},
-symbols_: {"error":2,"Root":3,"Query":4,"EOF":5,"SelectQuery":6,"Unions":7,"SelectWithLimitQuery":8,"BasicSelectQuery":9,"Select":10,"OrderClause":11,"GroupClause":12,"LimitClause":13,"SelectClause":14,"WhereClause":15,"SELECT":16,"Fields":17,"FROM":18,"Table":19,"DISTINCT":20,"Joins":21,"Literal":22,"AS":23,"LEFT_PAREN":24,"List":25,"RIGHT_PAREN":26,"WINDOW":27,"WINDOW_FUNCTION":28,"Number":29,"Union":30,"UNION":31,"ALL":32,"Join":33,"JOIN":34,"ON":35,"Expression":36,"LEFT":37,"RIGHT":38,"INNER":39,"OUTER":40,"WHERE":41,"LIMIT":42,"SEPARATOR":43,"OFFSET":44,"ORDER":45,"BY":46,"OrderArgs":47,"OffsetClause":48,"OrderArg":49,"Value":50,"DIRECTION":51,"OffsetRows":52,"FetchClause":53,"ROW":54,"ROWS":55,"FETCH":56,"FIRST":57,"ONLY":58,"NEXT":59,"GroupBasicClause":60,"HavingClause":61,"GROUP":62,"ArgumentList":63,"HAVING":64,"MATH":65,"MATH_MULTI":66,"OPERATOR":67,"BETWEEN":68,"BetweenExpression":69,"CONDITIONAL":70,"SUB_SELECT_OP":71,"SubSelectExpression":72,"SUB_SELECT_UNARY_OP":73,"String":74,"Function":75,"UserFunction":76,"Boolean":77,"Parameter":78,"NUMBER":79,"BOOLEAN":80,"PARAMETER":81,"STRING":82,"DBLSTRING":83,"LITERAL":84,"DOT":85,"FUNCTION":86,"AggregateArgumentList":87,"Field":88,"STAR":89,"$accept":0,"$end":1},
-terminals_: {2:"error",5:"EOF",16:"SELECT",18:"FROM",20:"DISTINCT",23:"AS",24:"LEFT_PAREN",26:"RIGHT_PAREN",27:"WINDOW",28:"WINDOW_FUNCTION",31:"UNION",32:"ALL",34:"JOIN",35:"ON",37:"LEFT",38:"RIGHT",39:"INNER",40:"OUTER",41:"WHERE",42:"LIMIT",43:"SEPARATOR",44:"OFFSET",45:"ORDER",46:"BY",51:"DIRECTION",54:"ROW",55:"ROWS",56:"FETCH",57:"FIRST",58:"ONLY",59:"NEXT",62:"GROUP",64:"HAVING",65:"MATH",66:"MATH_MULTI",67:"OPERATOR",68:"BETWEEN",70:"CONDITIONAL",71:"SUB_SELECT_OP",73:"SUB_SELECT_UNARY_OP",79:"NUMBER",80:"BOOLEAN",81:"PARAMETER",82:"STRING",83:"DBLSTRING",84:"LITERAL",85:"DOT",86:"FUNCTION",89:"STAR"},
-productions_: [0,[3,2],[4,1],[4,2],[6,1],[6,1],[9,1],[9,2],[9,2],[9,3],[8,2],[10,1],[10,2],[14,4],[14,5],[14,5],[14,6],[19,1],[19,2],[19,3],[19,3],[19,3],[19,4],[19,6],[7,1],[7,2],[30,2],[30,3],[21,1],[21,2],[33,4],[33,5],[33,5],[33,6],[33,6],[33,6],[33,6],[15,2],[13,2],[13,4],[13,4],[11,3],[11,4],[47,1],[47,3],[49,1],[49,2],[48,2],[48,3],[52,2],[52,2],[53,4],[53,4],[12,1],[12,2],[60,3],[61,2],[36,3],[36,3],[36,3],[36,3],[36,3],[36,3],[36,5],[36,3],[36,2],[36,1],[36,1],[69,3],[72,3],[50,1],[50,1],[50,1],[50,1],[50,1],[50,1],[50,1],[25,1],[29,1],[77,1],[78,1],[74,1],[74,1],[22,1],[22,3],[75,4],[76,3],[76,4],[87,1],[87,2],[63,1],[63,3],[17,1],[17,3],[88,1],[88,1],[88,3]],
+symbols_: {"error":2,"Root":3,"Query":4,"EOF":5,"SelectQuery":6,"Unions":7,"SelectWithLimitQuery":8,"BasicSelectQuery":9,"Select":10,"OrderClause":11,"GroupClause":12,"LimitClause":13,"SelectClause":14,"WhereClause":15,"SELECT":16,"Fields":17,"FROM":18,"Table":19,"DISTINCT":20,"Joins":21,"Literal":22,"AS":23,"LEFT_PAREN":24,"List":25,"RIGHT_PAREN":26,"WINDOW":27,"WINDOW_FUNCTION":28,"Number":29,"Union":30,"UNION":31,"ALL":32,"Join":33,"JOIN":34,"ON":35,"Expression":36,"LEFT":37,"RIGHT":38,"INNER":39,"OUTER":40,"WHERE":41,"LIMIT":42,"SEPARATOR":43,"OFFSET":44,"ORDER":45,"BY":46,"OrderArgs":47,"OffsetClause":48,"OrderArg":49,"Value":50,"DIRECTION":51,"OffsetRows":52,"FetchClause":53,"ROW":54,"ROWS":55,"FETCH":56,"FIRST":57,"ONLY":58,"NEXT":59,"GroupBasicClause":60,"HavingClause":61,"GROUP":62,"ArgumentList":63,"HAVING":64,"MATH":65,"MATH_MULTI":66,"OPERATOR":67,"BETWEEN":68,"BetweenExpression":69,"CONDITIONAL":70,"SUB_SELECT_OP":71,"SubSelectExpression":72,"SUB_SELECT_UNARY_OP":73,"WhitepaceList":74,"CaseStatement":75,"CASE":76,"CaseWhens":77,"END":78,"CaseElse":79,"CaseWhen":80,"WHEN":81,"THEN":82,"ELSE":83,"String":84,"Function":85,"UserFunction":86,"Boolean":87,"Parameter":88,"NUMBER":89,"BOOLEAN":90,"PARAMETER":91,"STRING":92,"DBLSTRING":93,"LITERAL":94,"DOT":95,"FUNCTION":96,"AggregateArgumentList":97,"Case":98,"Field":99,"STAR":100,"$accept":0,"$end":1},
+terminals_: {2:"error",5:"EOF",16:"SELECT",18:"FROM",20:"DISTINCT",23:"AS",24:"LEFT_PAREN",26:"RIGHT_PAREN",27:"WINDOW",28:"WINDOW_FUNCTION",31:"UNION",32:"ALL",34:"JOIN",35:"ON",37:"LEFT",38:"RIGHT",39:"INNER",40:"OUTER",41:"WHERE",42:"LIMIT",43:"SEPARATOR",44:"OFFSET",45:"ORDER",46:"BY",51:"DIRECTION",54:"ROW",55:"ROWS",56:"FETCH",57:"FIRST",58:"ONLY",59:"NEXT",62:"GROUP",64:"HAVING",65:"MATH",66:"MATH_MULTI",67:"OPERATOR",68:"BETWEEN",70:"CONDITIONAL",71:"SUB_SELECT_OP",73:"SUB_SELECT_UNARY_OP",76:"CASE",78:"END",81:"WHEN",82:"THEN",83:"ELSE",89:"NUMBER",90:"BOOLEAN",91:"PARAMETER",92:"STRING",93:"DBLSTRING",94:"LITERAL",95:"DOT",96:"FUNCTION",98:"Case",100:"STAR"},
+productions_: [0,[3,2],[4,1],[4,2],[6,1],[6,1],[9,1],[9,2],[9,2],[9,3],[8,2],[10,1],[10,2],[14,4],[14,5],[14,5],[14,6],[19,1],[19,2],[19,3],[19,3],[19,3],[19,4],[19,6],[7,1],[7,2],[30,2],[30,3],[21,1],[21,2],[33,4],[33,5],[33,5],[33,6],[33,6],[33,6],[33,6],[15,2],[13,2],[13,4],[13,4],[11,3],[11,4],[47,1],[47,3],[49,1],[49,2],[48,2],[48,3],[52,2],[52,2],[53,4],[53,4],[12,1],[12,2],[60,3],[61,2],[36,3],[36,3],[36,3],[36,3],[36,3],[36,3],[36,5],[36,3],[36,2],[36,1],[36,1],[36,1],[36,1],[69,3],[75,3],[75,4],[80,4],[77,2],[77,1],[79,2],[72,3],[50,1],[50,1],[50,1],[50,1],[50,1],[50,1],[50,1],[74,2],[74,2],[25,1],[29,1],[87,1],[88,1],[84,1],[84,1],[22,1],[22,3],[85,4],[86,3],[86,4],[86,4],[97,1],[97,2],[63,1],[63,3],[17,1],[17,3],[99,1],[99,1],[99,3]],
 performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
 /* this == yyval */
 
@@ -86,45 +86,26 @@ switch (yystate) {
 case 1:
 return this.$ = $$[$0-1];
 break;
-case 2: case 4: case 5: case 6: case 11: case 53: case 66: case 67: case 70: case 71: case 72: case 73: case 74: case 75: case 76:
+case 2: case 4: case 5: case 6: case 11: case 53: case 66: case 68: case 69: case 78: case 79: case 80: case 81: case 82: case 83: case 84:
 this.$ = $$[$0];
 break;
 case 3:
-this.$ = (function () {
-        $$[$0-1].unions = $$[$0];
-        return $$[$0-1];
-      }());
+this.$ = (function(){ $$[$0-1].unions = $$[$0]; return $$[$0-1]; }());
 break;
 case 7:
-this.$ = (function () {
-        $$[$0-1].order = $$[$0];
-        return $$[$0-1];
-      }());
+this.$ = (function(){ $$[$0-1].order = $$[$0]; return $$[$0-1]; }());
 break;
 case 8:
-this.$ = (function () {
-        $$[$0-1].group = $$[$0];
-        return $$[$0-1];
-      }());
+this.$ = (function(){ $$[$0-1].group = $$[$0]; return $$[$0-1]; }());
 break;
 case 9:
-this.$ = (function () {
-        $$[$0-2].group = $$[$0-1];
-        $$[$0-2].order = $$[$0];
-        return $$[$0-2];
-      }());
+this.$ = (function(){ $$[$0-2].group = $$[$0-1]; $$[$0-2].order = $$[$0]; return $$[$0-2]; }());
 break;
 case 10:
-this.$ = (function () {
-        $$[$0-1].limit = $$[$0];
-        return $$[$0-1];
-      }());
+this.$ = (function(){ $$[$0-1].limit = $$[$0]; return $$[$0-1]; }());
 break;
 case 12:
-this.$ = (function () {
-        $$[$0-1].where = $$[$0];
-        return $$[$0-1];
-      }());
+this.$ = (function(){ $$[$0-1].where = $$[$0]; return $$[$0-1]; }());
 break;
 case 13:
 this.$ = new yy.Select($$[$0-2], $$[$0], false);
@@ -150,7 +131,7 @@ break;
 case 20: case 49: case 50: case 51: case 52: case 57:
 this.$ = $$[$0-1];
 break;
-case 21: case 69:
+case 21: case 77:
 this.$ = new yy.SubSelect($$[$0-1]);
 break;
 case 22:
@@ -159,11 +140,11 @@ break;
 case 23:
 this.$ = new yy.Table($$[$0-5], null, $$[$0-4], $$[$0-3], $$[$0-1]);
 break;
-case 24: case 28: case 43: case 90: case 92:
+case 24: case 28: case 43: case 75: case 101: case 103:
 this.$ = [$$[$0]];
 break;
-case 25:
-this.$ = $$[$0-1].concat($$[$01]);
+case 25: case 29: case 74:
+this.$ = $$[$0-1].concat($$[$0]);
 break;
 case 26:
 this.$ = new yy.Union($$[$0]);
@@ -171,9 +152,6 @@ break;
 case 27:
 this.$ = new yy.Union($$[$0], true);
 break;
-case 29:
-this.$ = $$[$0-1].concat($$[$0]);
-break;
 case 30:
 this.$ = new yy.Join($$[$0-2], $$[$0]);
 break;
@@ -213,7 +191,7 @@ break;
 case 42:
 this.$ = new yy.Order($$[$0-1], $$[$0]);
 break;
-case 44: case 91: case 93:
+case 44: case 102: case 104:
 this.$ = $$[$0-2].concat($$[$0]);
 break;
 case 45:
@@ -229,10 +207,7 @@ case 48:
 this.$ = new yy.Offset($$[$0-1], $$[$0]);
 break;
 case 54:
-this.$ = (function () {
-        $$[$0-1].having = $$[$0];
-        return $$[$0-1];
-      }());
+this.$ = (function(){ $$[$0-1].having = $$[$0]; return $$[$0-1]; }());
 break;
 case 55:
 this.$ = new yy.Group($$[$0]);
@@ -249,66 +224,89 @@ break;
 case 65:
 this.$ = new yy.UnaryOp($$[$0-1], $$[$0]);
 break;
-case 68:
+case 67:
+this.$ = new yy.WhitepaceList($$[$0]);
+break;
+case 70:
 this.$ = new yy.BetweenOp([$$[$0-2], $$[$0]]);
 break;
-case 77:
+case 71:
+this.$ = new yy.Case($$[$0-1]);
+break;
+case 72:
+this.$ = new yy.Case($$[$0-2], $$[$0-1]);
+break;
+case 73:
+this.$ = new yy.CaseWhen($$[$0-2], $$[$0]);
+break;
+case 76:
+this.$ = new yy.CaseElse($$[$0]);
+break;
+case 85:
+this.$ = [$$[$0-1], $$[$0]];
+break;
+case 86:
+this.$ = (function(){ $$[$0-1].push($$[$0]); return $$[$0-1]; }());
+break;
+case 87:
 this.$ = new yy.ListValue($$[$0]);
 break;
-case 78:
+case 88:
 this.$ = new yy.NumberValue($$[$0]);
 break;
-case 79:
+case 89:
 this.$ = new yy.BooleanValue($$[$0]);
 break;
-case 80:
+case 90:
 this.$ = new yy.ParameterValue($$[$0]);
 break;
-case 81:
+case 91:
 this.$ = new yy.StringValue($$[$0], "'");
 break;
-case 82:
+case 92:
 this.$ = new yy.StringValue($$[$0], '"');
 break;
-case 83:
+case 93:
 this.$ = new yy.LiteralValue($$[$0]);
 break;
-case 84:
+case 94:
 this.$ = new yy.LiteralValue($$[$0-2], $$[$0]);
 break;
-case 85:
+case 95:
 this.$ = new yy.FunctionValue($$[$0-3], $$[$0-1]);
 break;
-case 86:
+case 96:
 this.$ = new yy.FunctionValue($$[$0-2], null, true);
 break;
-case 87:
+case 97: case 98:
 this.$ = new yy.FunctionValue($$[$0-3], $$[$0-1], true);
 break;
-case 88:
+case 99:
 this.$ = new yy.ArgumentListValue($$[$0]);
 break;
-case 89:
+case 100:
 this.$ = new yy.ArgumentListValue($$[$0], true);
 break;
-case 94:
+case 105:
 this.$ = new yy.Star();
 break;
-case 95:
+case 106:
 this.$ = new yy.Field($$[$0]);
 break;
-case 96:
+case 107:
 this.$ = new yy.Field($$[$0-2], $$[$0]);
 break;
 }
 },
-table: [{3:1,4:2,6:3,8:4,9:5,10:6,14:7,16:$V0},{1:[3]},{5:[1,9]},o($V1,[2,2],{7:10,13:11,30:12,31:$V2,42:$V3}),o($V4,[2,4]),o($V4,[2,5]),o($V4,[2,6],{11:15,12:16,60:18,45:$V5,62:[1,19]}),o($V6,[2,11],{15:20,41:[1,21]}),{17:22,20:[1,23],22:31,24:$V7,29:32,36:26,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf,88:24,89:$Vg},{1:[2,1]},o($V1,[2,3],{30:45,31:$V2}),o($V4,[2,10]),o($Vh,[2,24]),{29:46,79:$V9},{6:47,8:4,9:5,10:6,14:7,16:$V0,32:[1,48]},o($V4,[2,7]),o($V4,[2,8],{11:49,45:$V5}),{46:[1,50]},o($Vi,[2,53],{61:51,64:[1,52]}),{46:[1,53]},o($V6,[2,12]),{22:31,24:$V7,29:32,36:54,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{18:[1,55],43:$Vj},{17:57,22:31,24:$V7,29:32,36:26,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf,88:24,89:$Vg},o($Vk,[2,92]),o($Vk,[2,94]),o($Vk,[2,95],{23:[1,58],65:$Vl,66:$Vm,67:$Vn,68:$Vo,70:$Vp}),{4:65,6:3,8:4,9:5,10:6,14:7,16:$V0,22:31,24:$V7,29:32,36:64,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},o($Vq,[2,67],{71:[1,66]}),{24:[1,68],72:67},o($Vq,[2,66]),o($Vr,[2,70],{85:$Vs}),o($Vr,[2,71]),o($Vr,[2,72]),o($Vr,[2,73]),o($Vr,[2,74]),o($Vr,[2,75]),o($Vr,[2,76]),o([5,18,23,26,31,34,37,38,41,42,43,44,45,51,62,64,65,66,67,68,70,71,85],$Vt,{24:[1,70]}),o([5,18,23,26,31,34,37,38,41,42,43,44,45,51,54,55,62,64,65,66,67,68,70,71],[2,78]),o($Vr,[2,81]),o($Vr,[2,82]),{24:[1,71]},o($Vr,[2,79]),o($Vr,[2,80]),o($Vh,[2,25]),o($V4,[2,38],{43:[1,72],44:[1,73]}),o($Vh,[2,26],{13:11,42:$V3}),{6:74,8:4,9:5,10:6,14:7,16:$V0},o($V4,[2,9]),{22:31,29:32,47:75,49:76,50:77,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},o($Vi,[2,54]),{22:31,24:$V7,29:32,36:78,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{22:31,24:$V7,29:32,36:80,50:28,63:79,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},o($V6,[2,37],{65:$Vl,66:$Vm,67:$Vn,68:$Vo,70:$Vp}),{19:81,22:82,24:$Vu,84:$Vv},{22:31,24:$V7,29:32,36:26,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf,88:85,89:$Vg},{18:[1,86],43:$Vj},{22:87,84:$Vv},{22:31,24:$V7,29:32,36:88,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{22:31,24:$V7,29:32,36:89,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{22:31,24:$V7,29:32,36:90,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{22:31,24:$V7,29:32,36:92,50:28,69:91,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{22:31,24:$V7,29:32,36:93,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{26:[1,94],65:$Vl,66:$Vm,67:$Vn,68:$Vo,70:$Vp},{26:[1,95]},{24:[1,96],72:97},o($Vq,[2,65]),{4:65,6:3,8:4,9:5,10:6,14:7,16:$V0},{84:[1,98]},{20:$Vw,22:31,24:$V7,26:[1,99],29:32,36:80,50:28,63:101,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf,87:100},{20:$Vw,22:31,24:$V7,29:32,36:80,50:28,63:101,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf,87:103},{29:104,79:$V9},{29:105,79:$V9},o($Vh,[2,27],{13:11,42:$V3}),o($V4,[2,41],{48:106,43:[1,107],44:[1,108]}),o($Vx,[2,43]),o($Vx,[2,45],{51:[1,109]}),o($Vi,[2,56],{65:$Vl,66:$Vm,67:$Vn,68:$Vo,70:$Vp}),o([5,26,31,42,45,64],[2,55],{43:$Vy}),o($Vz,[2,90],{65:$Vl,66:$Vm,67:$Vn,68:$Vo,70:$Vp}),o($VA,[2,13],{21:111,33:112,34:$VB,37:$VC,38:$VD}),o($VE,[2,17],{22:116,23:[1,117],27:[1,118],84:$Vv,85:$Vs}),{4:120,6:3,8:4,9:5,10:6,14:7,16:$V0,22:31,24:$V7,25:119,29:32,36:80,50:28,63:121,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},o([5,18,23,26,27,31,34,35,37,38,41,42,43,45,62,84,85],$Vt),o($Vk,[2,93]),{19:122,22:82,24:$Vu,84:$Vv},o($Vk,[2,96],{85:$Vs}),o([5,18,23,26,31,34,37,38,41,42,43,45,62,64,65,67,70],[2,58],{66:$Vm,68:$Vo}),o([5,18,23,26,31,34,37,38,41,42,43,45,62,64,65,66,67,70],[2,59],{68:$Vo}),o([5,18,23,26,31,34,37,38,41,42,43,45,62,64,67,70],[2,60],{65:$Vl,66:$Vm,68:$Vo}),o($Vq,[2,61]),{65:$Vl,66:$Vm,67:$Vn,68:$Vo,70:[1,123]},o($VF,[2,62],{65:$Vl,66:$Vm,67:$Vn,68:$Vo}),o($Vq,[2,57]),o($Vq,[2,69]),{4:65,6:3,8:4,9:5,10:6,14:7,16:$V0,22:31,24:$V7,25:124,29:32,36:80,50:28,63:121,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},o($Vq,[2,64]),o([5,18,23,26,27,31,34,35,37,38,41,42,43,44,45,51,62,64,65,66,67,68,70,71,84,85],[2,84]),o($Vr,[2,86]),{26:[1,125]},{26:[2,88],43:$Vy},{22:31,24:$V7,29:32,36:80,50:28,63:126,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{26:[1,127]},o($V4,[2,39]),o($V4,[2,40]),o($V4,[2,42]),{22:31,29:32,49:128,50:77,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{29:130,52:129,79:$V9},o($Vx,[2,46]),{22:31,29:32,50:131,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},o($VA,[2,15],{33:132,34:$VB,37:$VC,38:$VD}),o($VG,[2,28]),{19:133,22:82,24:$Vu,84:$Vv},{34:[1,134],39:[1,135],40:[1,136]},{34:[1,137],39:[1,138],40:[1,139]},o($VE,[2,18],{85:$Vs}),{22:140,84:$Vv},{28:[1,141]},{26:[1,142]},{26:[1,143]},{26:[2,77],43:$Vy},o($VA,[2,14],{33:112,21:144,34:$VB,37:$VC,38:$VD}),{22:31,24:$V7,29:32,36:145,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{26:[1,146]},o($Vr,[2,87]),{26:[2,89],43:$Vy},o($Vr,[2,85]),o($Vx,[2,44]),o($V4,[2,47],{53:147,56:[1,148]}),{54:[1,149],55:[1,150]},o($Vz,[2,91]),o($VG,[2,29]),{35:[1,151]},{19:152,22:82,24:$Vu,84:$Vv},{34:[1,153]},{34:[1,154]},{19:155,22:82,24:$Vu,84:$Vv},{34:[1,156]},{34:[1,157]},o($VE,[2,19],{85:$Vs}),{24:[1,158]},o($VE,[2,20]),o($VE,[2,21],{22:159,84:$Vv}),o($VA,[2,16],{33:132,34:$VB,37:$VC,38:$VD}),o($VF,[2,68],{65:$Vl,66:$Vm,67:$Vn,68:$Vo}),o($Vq,[2,63]),o($V4,[2,48]),{57:[1,160],59:[1,161]},o($VH,[2,49]),o($VH,[2,50]),{22:31,24:$V7,29:32,36:162,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{35:[1,163]},{19:164,22:82,24:$Vu,84:$Vv},{19:165,22:82,24:$Vu,84:$Vv},{35:[1,166]},{19:167,22:82,24:$Vu,84:$Vv},{19:168,22:82,24:$Vu,84:$Vv},{29:169,79:$V9},o($VE,[2,22],{85:$Vs}),{29:130,52:170,79:$V9},{29:130,52:171,79:$V9},o($VG,[2,30],{65:$Vl,66:$Vm,67:$Vn,68:$Vo,70:$Vp}),{22:31,24:$V7,29:32,36:172,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{35:[1,173]},{35:[1,174]},{22:31,24:$V7,29:32,36:175,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{35:[1,176]},{35:[1,177]},{26:[1,178]},{58:[1,179]},{58:[1,180]},o($VG,[2,31],{65:$Vl,66:$Vm,67:$Vn,68:$Vo,70:$Vp}),{22:31,24:$V7,29:32,36:181,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{22:31,24:$V7,29:32,36:182,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},o($VG,[2,32],{65:$Vl,66:$Vm,67:$Vn,68:$Vo,70:$Vp}),{22:31,24:$V7,29:32,36:183,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},{22:31,24:$V7,29:32,36:184,50:28,72:30,73:$V8,74:33,75:34,76:35,77:36,78:37,79:$V9,80:$Va,81:$Vb,82:$Vc,83:$Vd,84:$Ve,86:$Vf},o($VE,[2,23]),o($V4,[2,51]),o($V4,[2,52]),o($VG,[2,33],{65:$Vl,66:$Vm,67:$Vn,68:$Vo,70:$Vp}),o($VG,[2,35],{65:$Vl,66:$Vm,67:$Vn,68:$Vo,70:$Vp}),o($VG,[2,34],{65:$Vl,66:$Vm,67:$Vn,68:$Vo,70:$Vp}),o($VG,[2,36],{65:$Vl,66:$Vm,67:$Vn,68:$Vo,70:$Vp})],
+table: [{3:1,4:2,6:3,8:4,9:5,10:6,14:7,16:$V0},{1:[3]},{5:[1,9]},o($V1,[2,2],{7:10,13:11,30:12,31:$V2,42:$V3}),o($V4,[2,4]),o($V4,[2,5]),o($V4,[2,6],{11:15,12:16,60:18,45:$V5,62:[1,19]}),o($V6,[2,11],{15:20,41:[1,21]}),{17:22,20:[1,23],22:33,24:$V7,29:34,36:26,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg,99:24,100:$Vh},{1:[2,1]},o($V1,[2,3],{30:48,31:$V2}),o($V4,[2,10]),o($Vi,[2,24]),{29:49,89:$Va},{6:50,8:4,9:5,10:6,14:7,16:$V0,32:[1,51]},o($V4,[2,7]),o($V4,[2,8],{11:52,45:$V5}),{46:[1,53]},o($Vj,[2,53],{61:54,64:[1,55]}),{46:[1,56]},o($V6,[2,12]),{22:33,24:$V7,29:34,36:57,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{18:[1,58],43:$Vk},{17:60,22:33,24:$V7,29:34,36:26,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg,99:24,100:$Vh},o($Vl,[2,103]),o($Vl,[2,105]),o($Vl,[2,106],{23:[1,61],65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq}),{4:68,6:3,8:4,9:5,10:6,14:7,16:$V0,22:33,24:$V7,29:34,36:67,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},o($Vr,[2,69],{22:33,29:34,84:35,85:36,86:37,87:38,88:39,50:70,71:[1,69],89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg}),{24:[1,72],72:71},o($Vr,[2,66]),o($Vr,[2,67],{22:33,29:34,84:35,85:36,86:37,87:38,88:39,50:73,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg}),o($Vr,[2,68]),o($Vs,[2,78],{95:$Vt}),o($Vs,[2,79]),o($Vs,[2,80]),o($Vs,[2,81]),o($Vs,[2,82]),o($Vs,[2,83]),o($Vs,[2,84]),{77:75,80:76,81:$Vu},o([5,18,23,26,31,34,37,38,41,42,43,44,45,51,62,64,65,66,67,68,70,71,78,81,82,83,89,90,91,92,93,94,95,96],$Vv,{24:[1,78]}),o([5,18,23,26,31,34,37,38,41,42,43,44,45,51,54,55,62,64,65,66,67,68,70,71,78,81,82,83,89,90,91,92,93,94,96],[2,88]),o($Vs,[2,91]),o($Vs,[2,92]),{24:[1,79]},o($Vs,[2,89]),o($Vs,[2,90]),o($Vi,[2,25]),o($V4,[2,38],{43:[1,80],44:[1,81]}),o($Vi,[2,26],{13:11,42:$V3}),{6:82,8:4,9:5,10:6,14:7,16:$V0},o($V4,[2,9]),{22:33,29:34,47:83,49:84,50:85,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},o($Vj,[2,54]),{22:33,24:$V7,29:34,36:86,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{22:33,24:$V7,29:34,36:88,50:28,63:87,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},o($V6,[2,37],{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq}),{19:89,22:90,24:$Vw,94:$Vx},{22:33,24:$V7,29:34,36:26,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg,99:93,100:$Vh},{18:[1,94],43:$Vk},{22:95,94:$Vx},{22:33,24:$V7,29:34,36:96,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{22:33,24:$V7,29:34,36:97,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{22:33,24:$V7,29:34,36:98,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{22:33,24:$V7,29:34,36:100,50:28,69:99,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{22:33,24:$V7,29:34,36:101,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{26:[1,102],65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq},{26:[1,103]},{24:[1,104],72:105},o($Vy,[2,85]),o($Vr,[2,65]),{4:68,6:3,8:4,9:5,10:6,14:7,16:$V0},o($Vy,[2,86]),{94:[1,106]},{78:[1,107],79:108,80:109,81:$Vu,83:[1,110]},o($Vz,[2,75]),{22:33,24:$V7,29:34,36:111,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{20:$VA,22:33,24:$V7,26:[1,112],29:34,36:88,50:28,63:115,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg,97:113,98:[1,114]},{20:$VA,22:33,24:$V7,29:34,36:88,50:28,63:115,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg,97:117},{29:118,89:$Va},{29:119,89:$Va},o($Vi,[2,27],{13:11,42:$V3}),o($V4,[2,41],{48:120,43:[1,121],44:[1,122]}),o($VB,[2,43]),o($VB,[2,45],{51:[1,123]}),o($Vj,[2,56],{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq}),o([5,26,31,42,45,64],[2,55],{43:$VC}),o($VD,[2,101],{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq}),o($VE,[2,13],{21:125,33:126,34:$VF,37:$VG,38:$VH}),o($VI,[2,17],{22:130,23:[1,131],27:[1,132],94:$Vx,95:$Vt}),{4:134,6:3,8:4,9:5,10:6,14:7,16:$V0,22:33,24:$V7,25:133,29:34,36:88,50:28,63:135,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},o([5,18,23,26,27,31,34,35,37,38,41,42,43,45,62,94,95],$Vv),o($Vl,[2,104]),{19:136,22:90,24:$Vw,94:$Vx},o($Vl,[2,107],{95:$Vt}),o([5,18,23,26,31,34,37,38,41,42,43,45,62,64,65,67,70,78,81,82,83],[2,58],{66:$Vn,68:$Vp}),o([5,18,23,26,31,34,37,38,41,42,43,45,62,64,65,66,67,70,78,81,82,83],[2,59],{68:$Vp}),o([5,18,23,26,31,34,37,38,41,42,43,45,62,64,67,70,78,81,82,83],[2,60],{65:$Vm,66:$Vn,68:$Vp}),o($Vr,[2,61]),{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:[1,137]},o($VJ,[2,62],{65:$Vm,66:$Vn,67:$Vo,68:$Vp}),o($Vr,[2,57]),o($Vr,[2,77]),{4:68,6:3,8:4,9:5,10:6,14:7,16:$V0,22:33,24:$V7,25:138,29:34,36:88,50:28,63:135,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},o($Vr,[2,64]),o([5,18,23,26,27,31,34,35,37,38,41,42,43,44,45,51,62,64,65,66,67,68,70,71,78,81,82,83,89,90,91,92,93,94,95,96],[2,94]),o($Vr,[2,71]),{78:[1,139]},o($Vz,[2,74]),{22:33,24:$V7,29:34,36:140,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq,82:[1,141]},o($Vs,[2,96]),{26:[1,142]},{26:[1,143]},{26:[2,99],43:$VC},{22:33,24:$V7,29:34,36:88,50:28,63:144,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{26:[1,145]},o($V4,[2,39]),o($V4,[2,40]),o($V4,[2,42]),{22:33,29:34,49:146,50:85,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{29:148,52:147,89:$Va},o($VB,[2,46]),{22:33,24:$V7,29:34,36:149,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},o($VE,[2,15],{33:150,34:$VF,37:$VG,38:$VH}),o($VK,[2,28]),{19:151,22:90,24:$Vw,94:$Vx},{34:[1,152],39:[1,153],40:[1,154]},{34:[1,155],39:[1,156],40:[1,157]},o($VI,[2,18],{95:$Vt}),{22:158,94:$Vx},{28:[1,159]},{26:[1,160]},{26:[1,161]},{26:[2,87],43:$VC},o($VE,[2,14],{33:126,21:162,34:$VF,37:$VG,38:$VH}),{22:33,24:$V7,29:34,36:163,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{26:[1,164]},o($Vr,[2,72]),{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq,78:[2,76]},{22:33,24:$V7,29:34,36:165,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},o($Vs,[2,97]),o($Vs,[2,98]),{26:[2,100],43:$VC},o($Vs,[2,95]),o($VB,[2,44]),o($V4,[2,47],{53:166,56:[1,167]}),{54:[1,168],55:[1,169]},o($VD,[2,102],{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq}),o($VK,[2,29]),{35:[1,170]},{19:171,22:90,24:$Vw,94:$Vx},{34:[1,172]},{34:[1,173]},{19:174,22:90,24:$Vw,94:$Vx},{34:[1,175]},{34:[1,176]},o($VI,[2,19],{95:$Vt}),{24:[1,177]},o($VI,[2,20]),o($VI,[2,21],{22:178,94:$Vx}),o($VE,[2,16],{33:150,34:$VF,37:$VG,38:$VH}),o($VJ,[2,70],{65:$Vm,66:$Vn,67:$Vo,68:$Vp}),o($Vr,[2,63]),o($Vz,[2,73],{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq}),o($V4,[2,48]),{57:[1,179],59:[1,180]},o($VL,[2,49]),o($VL,[2,50]),{22:33,24:$V7,29:34,36:181,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{35:[1,182]},{19:183,22:90,24:$Vw,94:$Vx},{19:184,22:90,24:$Vw,94:$Vx},{35:[1,185]},{19:186,22:90,24:$Vw,94:$Vx},{19:187,22:90,24:$Vw,94:$Vx},{29:188,89:$Va},o($VI,[2,22],{95:$Vt}),{29:148,52:189,89:$Va},{29:148,52:190,89:$Va},o($VK,[2,30],{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq}),{22:33,24:$V7,29:34,36:191,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{35:[1,192]},{35:[1,193]},{22:33,24:$V7,29:34,36:194,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{35:[1,195]},{35:[1,196]},{26:[1,197]},{58:[1,198]},{58:[1,199]},o($VK,[2,31],{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq}),{22:33,24:$V7,29:34,36:200,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{22:33,24:$V7,29:34,36:201,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},o($VK,[2,32],{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq}),{22:33,24:$V7,29:34,36:202,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},{22:33,24:$V7,29:34,36:203,50:28,72:30,73:$V8,74:31,75:32,76:$V9,84:35,85:36,86:37,87:38,88:39,89:$Va,90:$Vb,91:$Vc,92:$Vd,93:$Ve,94:$Vf,96:$Vg},o($VI,[2,23]),o($V4,[2,51]),o($V4,[2,52]),o($VK,[2,33],{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq}),o($VK,[2,35],{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq}),o($VK,[2,34],{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq}),o($VK,[2,36],{65:$Vm,66:$Vn,67:$Vo,68:$Vp,70:$Vq})],
 defaultActions: {9:[2,1]},
-parseError: function parseError(str, hash) {
+parseError: function parseError (str, hash) {
     if (hash.recoverable) {
         this.trace(str);
     } else {
-        throw new Error(str);
+        var error = new Error(str);
+        error.hash = hash;
+        throw error;
     }
 },
 parse: function parse(input) {
@@ -341,14 +339,14 @@ parse: function parse(input) {
         lstack.length = lstack.length - n;
     }
     _token_stack:
-        function lex() {
+        var lex = function () {
             var token;
             token = lexer.lex() || EOF;
             if (typeof token !== 'number') {
                 token = self.symbols_[token] || token;
             }
             return token;
-        }
+        };
     var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
     while (true) {
         state = stack[stack.length - 1];
@@ -456,20 +454,4 @@ Parser.prototype = parser;parser.Parser = Parser;
 return new Parser;
 })();
 
-
-if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
-exports.parser = parser;
-exports.Parser = parser.Parser;
-exports.parse = function () { return parser.parse.apply(parser, arguments); };
-exports.main = function commonjsMain(args) {
-    if (!args[1]) {
-        console.log('Usage: '+args[0]+' FILE');
-        process.exit(1);
-    }
-    var source = require('fs').readFileSync(require('path').normalize(args[1]), "utf8");
-    return exports.parser.parse(source);
-};
-if (typeof module !== 'undefined' && require.main === module) {
-  exports.main(process.argv.slice(1));
-}
-}
\ No newline at end of file
+exports.parser = parser;
\ No newline at end of file
diff --git a/src/grammar.coffee b/src/grammar.coffee
deleted file mode 100644
index b89a4a4..0000000
--- a/src/grammar.coffee
+++ /dev/null
@@ -1,250 +0,0 @@
-{Parser} = require 'jison'
-
-unwrap = /^function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/
-
-o = (patternString, action, options) ->
-  patternString = patternString.replace /\s{2,}/g, ' '
-  return [patternString, '$$ = $1;', options] unless action
-  action = if match = unwrap.exec action then match[1] else "(#{action}())"
-  action = action.replace /\bnew /g, '$&yy.'
-  [patternString, "$$ = #{action};", options]
-
-grammar =
-
-  Root: [
-    o 'Query EOF'
-  ]
-
-  Query: [
-    o "SelectQuery"
-    o "SelectQuery Unions",                                -> $1.unions = $2; $1
-  ]
-
-  SelectQuery: [
-    o "SelectWithLimitQuery"
-    o "BasicSelectQuery"
-  ]
-
-  BasicSelectQuery: [
-    o 'Select'
-    o 'Select OrderClause',                               -> $1.order = $2; $1
-    o 'Select GroupClause',                               -> $1.group = $2; $1
-    o 'Select GroupClause OrderClause',                   -> $1.group = $2; $1.order = $3; $1
-  ]
-
-  SelectWithLimitQuery: [
-    o 'SelectQuery LimitClause',                          -> $1.limit = $2; $1
-  ]
-
-  Select: [
-    o 'SelectClause'
-    o 'SelectClause WhereClause',                         -> $1.where = $2; $1
-  ]
-
-  SelectClause: [
-    o 'SELECT Fields FROM Table',                         -> new Select($2, $4, false)
-    o 'SELECT DISTINCT Fields FROM Table',                -> new Select($3, $5, true)
-    o 'SELECT Fields FROM Table Joins',                   -> new Select($2, $4, false, $5)
-    o 'SELECT DISTINCT Fields FROM Table Joins',          -> new Select($3, $5, true, $6)
-  ]
-
-  Table: [
-    o 'Literal',                                          -> new Table($1)
-    o 'Literal Literal',                                  -> new Table($1, $2)
-    o 'Literal AS Literal',                               -> new Table($1, $3)
-    o 'LEFT_PAREN List RIGHT_PAREN',                      -> $2
-    o 'LEFT_PAREN Query RIGHT_PAREN',                     -> new SubSelect($2)
-    o 'LEFT_PAREN Query RIGHT_PAREN Literal',             -> new SubSelect($2, $4)
-    o 'Literal WINDOW WINDOW_FUNCTION LEFT_PAREN Number RIGHT_PAREN',
-                                                          -> new Table($1, null, $2, $3, $5)
-  ]
-
-  Unions: [
-    o 'Union',                                            -> [$1]
-    o 'Unions Union',                                     -> $1.concat($3)
-  ]
-
-  Union: [
-    o 'UNION SelectQuery',                                -> new Union($2)
-    o 'UNION ALL SelectQuery',                            -> new Union($3, true)
-  ]
-
-  Joins: [
-    o 'Join',                                             -> [$1]
-    o 'Joins Join',                                       -> $1.concat($2)
-  ]
-
-  Join: [
-    o 'JOIN Table ON Expression',                         -> new Join($2, $4)
-    o 'LEFT JOIN Table ON Expression',                    -> new Join($3, $5, 'LEFT')
-    o 'RIGHT JOIN Table ON Expression',                   -> new Join($3, $5, 'RIGHT')
-    o 'LEFT INNER JOIN Table ON Expression',              -> new Join($4, $6, 'LEFT', 'INNER')
-    o 'RIGHT INNER JOIN Table ON Expression',             -> new Join($4, $6, 'RIGHT', 'INNER')
-    o 'LEFT OUTER JOIN Table ON Expression',              -> new Join($4, $6, 'LEFT', 'OUTER')
-    o 'RIGHT OUTER JOIN Table ON Expression',             -> new Join($4, $6, 'RIGHT', 'OUTER')
-  ]
-
-  WhereClause: [
-    o 'WHERE Expression',                                 -> new Where($2)
-  ]
-
-  LimitClause: [
-    o 'LIMIT Number',                                     -> new Limit($2)
-    o 'LIMIT Number SEPARATOR Number',                    -> new Limit($4, $2)
-    o 'LIMIT Number OFFSET Number',                       -> new Limit($2, $4)
-  ]
-
-  OrderClause: [
-    o 'ORDER BY OrderArgs',                               -> new Order($3)
-    o 'ORDER BY OrderArgs OffsetClause',                  -> new Order($3, $4)
-  ]
-
-  OrderArgs: [
-    o 'OrderArg',                                         -> [$1]
-    o 'OrderArgs SEPARATOR OrderArg',                     -> $1.concat($3)
-  ]
-
-  OrderArg: [
-    o 'Value',                                            -> new OrderArgument($1, 'ASC')
-    o 'Value DIRECTION',                                  -> new OrderArgument($1, $2)
-  ]
-
-  OffsetClause: [
-    # MS SQL Server 2012+
-    o 'OFFSET OffsetRows',                                -> new Offset($2)
-    o 'OFFSET OffsetRows FetchClause',                    -> new Offset($2, $3)
-  ]
-
-  OffsetRows: [
-    o 'Number ROW',                                       -> $1
-    o 'Number ROWS',                                      -> $1
-  ]
-
-  FetchClause: [
-    o 'FETCH FIRST OffsetRows ONLY',                      -> $3
-    o 'FETCH NEXT OffsetRows ONLY',                       -> $3
-  ]
-
-  GroupClause: [
-    o 'GroupBasicClause'
-    o 'GroupBasicClause HavingClause',                    -> $1.having = $2; $1
-  ]
-
-  GroupBasicClause: [
-    o 'GROUP BY ArgumentList',                            -> new Group($3)
-  ]
-
-  HavingClause: [
-    o 'HAVING Expression',                                -> new Having($2)
-  ]
-
-
-  Expression: [
-    o 'LEFT_PAREN Expression RIGHT_PAREN',                -> $2
-    o 'Expression MATH Expression',                       -> new Op($2, $1, $3)
-    o 'Expression MATH_MULTI Expression',                 -> new Op($2, $1, $3)
-    o 'Expression OPERATOR Expression',                   -> new Op($2, $1, $3)
-    o 'Expression BETWEEN BetweenExpression',             -> new Op($2, $1, $3)
-    o 'Expression CONDITIONAL Expression',                -> new Op($2, $1, $3)
-    o 'Value SUB_SELECT_OP LEFT_PAREN List RIGHT_PAREN',  -> new Op($2, $1, $4)
-    o 'Value SUB_SELECT_OP SubSelectExpression',          -> new Op($2, $1, $3)
-    o 'SUB_SELECT_UNARY_OP SubSelectExpression',          -> new UnaryOp($1, $2)
-    o 'SubSelectExpression'
-    o 'Value'
-  ]
-
-  BetweenExpression: [
-    o 'Expression CONDITIONAL Expression',                -> new BetweenOp([$1, $3])
-  ]
-
-  SubSelectExpression: [
-    o 'LEFT_PAREN Query RIGHT_PAREN',                     -> new SubSelect($2)
-  ]
-
-  Value: [
-    o 'Literal'
-    o 'Number'
-    o 'String'
-    o 'Function'
-    o 'UserFunction'
-    o 'Boolean'
-    o 'Parameter'
-  ]
-
-  List: [
-    o 'ArgumentList',                                     -> new ListValue($1)
-  ]
-
-  Number: [
-    o 'NUMBER',                                           -> new NumberValue($1)
-  ]
-
-  Boolean: [
-    o 'BOOLEAN',                                           -> new BooleanValue($1)
-  ]
-
-  Parameter: [
-    o 'PARAMETER',                                        -> new ParameterValue($1)
-  ]
-
-  String: [
-    o 'STRING',                                           -> new StringValue($1, "'")
-    o 'DBLSTRING',                                        -> new StringValue($1, '"')
-  ]
-
-  Literal: [
-    o 'LITERAL',                                          -> new LiteralValue($1)
-    o 'Literal DOT LITERAL',                              -> new LiteralValue($1, $3)
-  ]
-
-  Function: [
-    o "FUNCTION LEFT_PAREN AggregateArgumentList RIGHT_PAREN",     -> new FunctionValue($1, $3)
-  ]
-
-  UserFunction: [
-    o "LITERAL LEFT_PAREN RIGHT_PAREN",                           -> new FunctionValue($1, null, true)
-    o "LITERAL LEFT_PAREN AggregateArgumentList RIGHT_PAREN",     -> new FunctionValue($1, $3, true)
-  ]
-
-  AggregateArgumentList: [
-    o 'ArgumentList',                                    -> new ArgumentListValue($1)
-    o 'DISTINCT ArgumentList',                           -> new ArgumentListValue($2, true)
-  ]
-
-  ArgumentList: [
-    o 'Expression',                                       -> [$1]
-    o 'ArgumentList SEPARATOR Value',                     -> $1.concat($3)
-  ]
-
-  Fields: [
-    o 'Field',                                            -> [$1]
-    o 'Fields SEPARATOR Field',                           -> $1.concat($3)
-  ]
-
-  Field: [
-    o 'STAR',                                             -> new Star()
-    o 'Expression',                                       -> new Field($1)
-    o 'Expression AS Literal',                            -> new Field($1, $3)
-  ]
-
-tokens = []
-operators = [
-  ['left', 'Op']
-  ['left', 'MATH_MULTI']
-  ['left', 'MATH']
-  ['left', 'OPERATOR']
-  ['left', 'CONDITIONAL']
-]
-
-for name, alternatives of grammar
-  grammar[name] = for alt in alternatives
-    for token in alt[0].split ' '
-      tokens.push token unless grammar[token]
-    alt[1] = "return #{alt[1]}" if name is 'Root'
-    alt
-
-exports.parser = new Parser
-  tokens      : tokens.join ' '
-  bnf         : grammar
-  operators   : operators.reverse()
-  startSymbol : 'Root'
diff --git a/src/grammar.js b/src/grammar.js
new file mode 100644
index 0000000..53dccc8
--- /dev/null
+++ b/src/grammar.js
@@ -0,0 +1,463 @@
+const Parser = require('jison').Parser;
+
+const unwrap = /^function\s*\(.*?\)\s*{\s*return\s*([\s\S]*);\s*}/;
+const cleanup = /^function\s*\(.*?\)\s*{\s*(.*?)\s*}/s;
+
+function o(patternString, action, options) {
+    patternString = patternString.replace(/\s{2,}/g, ' ');
+
+    if (!action) {
+        return [patternString, '$$ = $1;', options];
+    }
+
+    let match;
+    if ((match = unwrap.exec(action.toString()))) {
+        action = match[1];
+    } else if ((match = cleanup.exec(action.toString()))) {
+        action = `(function(){ ${match[1]} }())`;
+    } else {
+        throw `Invalid action ${action}`;
+    }
+
+    action = action.replace(/\bnew /g, '$&yy.');
+    action = action.replace(/\s+/g, ' ');
+
+    return [patternString, `$$ = ${action};`, options];
+}
+
+const grammar = {
+    Root                 : [
+        o('Query EOF')
+    ],
+    Query                : [
+        o('SelectQuery'),
+        o('SelectQuery Unions', function ($1, $2) {
+            $1.unions = $2;
+            return $1;
+        })
+    ],
+    SelectQuery          : [
+        o('SelectWithLimitQuery'),
+        o('BasicSelectQuery')
+    ],
+    BasicSelectQuery     : [
+        o('Select'),
+        o('Select OrderClause', function ($1, $2) {
+            $1.order = $2;
+            return $1;
+        }),
+        o('Select GroupClause', function ($1, $2) {
+            $1.group = $2;
+            return $1;
+        }),
+        o('Select GroupClause OrderClause', function ($1, $2, $3) {
+            $1.group = $2;
+            $1.order = $3;
+            return $1;
+        })
+    ],
+    SelectWithLimitQuery : [
+        o('SelectQuery LimitClause', function ($1, $2) {
+            $1.limit = $2;
+            return $1;
+        })
+    ],
+    Select               : [
+        o('SelectClause'),
+        o('SelectClause WhereClause', function ($1, $2) {
+            $1.where = $2;
+            return $1;
+        })
+    ],
+    SelectClause         : [
+        o('SELECT Fields FROM Table', function ($2, $4) {
+            return new Select($2, $4, false);
+        }),
+        o('SELECT DISTINCT Fields FROM Table', function ($3, $5) {
+            return new Select($3, $5, true);
+        }),
+        o('SELECT Fields FROM Table Joins', function ($2, $4, $5) {
+            return new Select($2, $4, false, $5);
+        }),
+        o('SELECT DISTINCT Fields FROM Table Joins', function ($3, $5, $6) {
+            return new Select($3, $5, true, $6);
+        })
+    ],
+    Table                : [
+        o('Literal', function ($1) {
+            return new Table($1);
+        }),
+        o('Literal Literal', function ($1, $2) {
+            return new Table($1, $2);
+        }),
+        o('Literal AS Literal', function ($1, $3) {
+            return new Table($1, $3);
+        }),
+        o('LEFT_PAREN List RIGHT_PAREN', function ($2) {
+            return $2;
+        }),
+        o('LEFT_PAREN Query RIGHT_PAREN', function ($2) {
+            return new SubSelect($2);
+        }),
+        o('LEFT_PAREN Query RIGHT_PAREN Literal', function ($2, $4) {
+            return new SubSelect($2, $4);
+        }),
+        o('Literal WINDOW WINDOW_FUNCTION LEFT_PAREN Number RIGHT_PAREN', function ($1, $2, $3, $5) {
+            return new Table($1, null, $2, $3, $5);
+        })
+    ],
+    Unions               : [
+        o('Union', function ($1) {
+            return [$1];
+        }),
+        o('Unions Union', function ($1, $2) {
+            return $1.concat($2);
+        })
+    ],
+    Union                : [
+        o('UNION SelectQuery', function ($2) {
+            return new Union($2);
+        }),
+        o('UNION ALL SelectQuery', function ($3) {
+            return new Union($3, true);
+        })
+    ],
+    Joins                : [
+        o('Join', function ($1) {
+            return [$1];
+        }),
+        o('Joins Join', function ($1, $2) {
+            return $1.concat($2);
+        })
+    ],
+    Join                 : [
+        o('JOIN Table ON Expression', function ($2, $4) {
+            return new Join($2, $4);
+        }),
+        o('LEFT JOIN Table ON Expression', function ($3, $5) {
+            return new Join($3, $5, 'LEFT');
+        }),
+        o('RIGHT JOIN Table ON Expression', function ($3, $5) {
+            return new Join($3, $5, 'RIGHT');
+        }),
+        o('LEFT INNER JOIN Table ON Expression', function ($4, $6) {
+            return new Join($4, $6, 'LEFT', 'INNER');
+        }),
+        o('RIGHT INNER JOIN Table ON Expression', function ($4, $6) {
+            return new Join($4, $6, 'RIGHT', 'INNER');
+        }),
+        o('LEFT OUTER JOIN Table ON Expression', function ($4, $6) {
+            return new Join($4, $6, 'LEFT', 'OUTER');
+        }),
+        o('RIGHT OUTER JOIN Table ON Expression', function ($4, $6) {
+            return new Join($4, $6, 'RIGHT', 'OUTER');
+        })
+    ],
+    WhereClause          : [
+        o('WHERE Expression', function ($2) {
+            return new Where($2);
+        })
+    ],
+    LimitClause          : [
+        o('LIMIT Number', function ($2) {
+            return new Limit($2);
+        }),
+        o('LIMIT Number SEPARATOR Number', function ($2, $4) {
+            return new Limit($4, $2);
+        }),
+        o('LIMIT Number OFFSET Number', function ($2, $4) {
+            return new Limit($2, $4);
+        })
+    ],
+    OrderClause          : [
+        o('ORDER BY OrderArgs', function ($3) {
+            return new Order($3);
+        }),
+        o('ORDER BY OrderArgs OffsetClause', function ($3, $4) {
+            return new Order($3, $4);
+        })
+    ],
+    OrderArgs            : [
+        o('OrderArg', function ($1) {
+            return [$1];
+        }),
+        o('OrderArgs SEPARATOR OrderArg', function ($1, $3) {
+            return $1.concat($3);
+        })
+    ],
+    OrderArg             : [
+        o('Value', function ($1) {
+            return new OrderArgument($1, 'ASC');
+        }),
+        o('Value DIRECTION', function ($1, $2) {
+            return new OrderArgument($1, $2);
+        })
+    ],
+    OffsetClause         : [
+        // MS SQL Server 2012+
+        o('OFFSET OffsetRows', function ($2) {
+            return new Offset($2);
+        }),
+        o('OFFSET OffsetRows FetchClause', function ($2, $3) {
+            return new Offset($2, $3);
+        })
+    ],
+    OffsetRows           : [
+        o('Number ROW', function ($1) {
+            return $1;
+        }),
+        o('Number ROWS', function ($1) {
+            return $1;
+        })
+    ],
+    FetchClause          : [
+        o('FETCH FIRST OffsetRows ONLY', function ($3) {
+            return $3;
+        }),
+        o('FETCH NEXT OffsetRows ONLY', function ($3) {
+            return $3;
+        })
+    ],
+    GroupClause          : [
+        o('GroupBasicClause', function ($1) {
+            return $1;
+        }),
+        o('GroupBasicClause HavingClause', function ($1, $2) {
+            $1.having = $2;
+            return $1;
+        })
+    ],
+    GroupBasicClause     : [
+        o('GROUP BY ArgumentList', function ($3) {
+            return new Group($3);
+        })
+    ],
+    HavingClause         : [
+        o('HAVING Expression', function ($2) {
+            return new Having($2);
+        })
+    ],
+    Expression           : [
+        o('LEFT_PAREN Expression RIGHT_PAREN', function ($2) {
+            return $2;
+        }),
+        o('Expression MATH Expression', function ($1, $2, $3) {
+            return new Op($2, $1, $3);
+        }),
+        o('Expression MATH_MULTI Expression', function ($1, $2, $3) {
+            return new Op($2, $1, $3);
+        }),
+        o('Expression OPERATOR Expression', function ($1, $2, $3) {
+            return new Op($2, $1, $3);
+        }),
+        o('Expression BETWEEN BetweenExpression', function ($1, $2, $3) {
+            return new Op($2, $1, $3);
+        }),
+        o('Expression CONDITIONAL Expression', function ($1, $2, $3) {
+            return new Op($2, $1, $3);
+        }),
+        o('Value SUB_SELECT_OP LEFT_PAREN List RIGHT_PAREN', function ($1, $2, $4) {
+            return new Op($2, $1, $4);
+        }),
+        o('Value SUB_SELECT_OP SubSelectExpression', function ($1, $2, $3) {
+            return new Op($2, $1, $3);
+        }),
+        o('SUB_SELECT_UNARY_OP SubSelectExpression', function ($1, $2) {
+            return new UnaryOp($1, $2);
+        }),
+        o('SubSelectExpression', function ($1) {
+            return $1;
+        }),
+        o('WhitepaceList', function ($1) {
+            return new WhitepaceList($1);
+        }),
+        o('CaseStatement', function ($1) {
+            return $1;
+        }),
+        o('Value', function ($1) {
+            return $1;
+        })
+    ],
+    BetweenExpression    : [
+        o('Expression CONDITIONAL Expression', function ($1, $3) {
+            return new BetweenOp([$1, $3]);
+        })
+    ],
+    CaseStatement        : [
+        o('CASE CaseWhens END', function ($2) {
+            return new Case($2);
+        }),
+        o('CASE CaseWhens CaseElse END', function ($2, $3) {
+            return new Case($2, $3);
+        })
+    ],
+    CaseWhen             : [
+        o('WHEN Expression THEN Expression', function ($2, $4) {
+            return new CaseWhen($2, $4);
+        })
+    ],
+    CaseWhens            : [
+        o('CaseWhens CaseWhen', function ($1, $2) {
+            return $1.concat($2);
+        }),
+        o('CaseWhen', function ($1) {
+            return [$1];
+        })
+    ],
+    CaseElse             : [
+        o('ELSE Expression', function ($2) {
+            return new CaseElse($2);
+        })
+    ],
+    SubSelectExpression  : [
+        o('LEFT_PAREN Query RIGHT_PAREN', function ($2) {
+            return new SubSelect($2);
+        })
+    ],
+    Value                : [
+        o('Literal'),
+        o('Number'),
+        o('String'),
+        o('Function'),
+        o('UserFunction'),
+        o('Boolean'),
+        o('Parameter')
+    ],
+    WhitepaceList        : [
+        o('Value Value', function ($1, $2) {
+            return [$1, $2];
+        }),
+        o('WhitepaceList Value', function ($1, $2) {
+            $1.push($2);
+            return $1;
+        })
+    ],
+    List                 : [
+        o('ArgumentList', function ($1) {
+            return new ListValue($1);
+        })
+    ],
+    Number               : [
+        o('NUMBER', function ($1) {
+            return new NumberValue($1);
+        })
+    ],
+    Boolean              : [
+        o('BOOLEAN', function ($1) {
+            return new BooleanValue($1);
+        })
+    ],
+    Parameter            : [
+        o('PARAMETER', function ($1) {
+            return new ParameterValue($1);
+        })
+    ],
+    String               : [
+        o('STRING', function ($1) {
+            return new StringValue($1, "'");
+        }),
+        o('DBLSTRING', function ($1) {
+            return new StringValue($1, '"');
+        })
+    ],
+    Literal              : [
+        o('LITERAL', function ($1) {
+            return new LiteralValue($1);
+        }),
+        o('Literal DOT LITERAL', function ($1, $3) {
+            return new LiteralValue($1, $3);
+        })
+    ],
+    Function             : [
+        o('FUNCTION LEFT_PAREN AggregateArgumentList RIGHT_PAREN', function ($1, $3) {
+            return new FunctionValue($1, $3);
+        })
+    ],
+    UserFunction         : [
+        o('LITERAL LEFT_PAREN RIGHT_PAREN', function ($1) {
+            return new FunctionValue($1, null, true);
+        }),
+        o('LITERAL LEFT_PAREN AggregateArgumentList RIGHT_PAREN', function ($1, $3) {
+            return new FunctionValue($1, $3, true);
+        }),
+        o('LITERAL LEFT_PAREN Case RIGHT_PAREN', function ($1, $3) {
+            return new FunctionValue($1, $3, true);
+        })
+    ],
+    AggregateArgumentList: [
+        o('ArgumentList', function ($1) {
+            return new ArgumentListValue($1);
+        }),
+        o('DISTINCT ArgumentList', function ($2) {
+            return new ArgumentListValue($2, true);
+        })
+    ],
+    ArgumentList         : [
+        o('Expression', function ($1) {
+            return [$1];
+        }),
+        o('ArgumentList SEPARATOR Expression', function ($1, $3) {
+            return $1.concat($3);
+        })
+    ],
+    Fields               : [
+        o('Field', function ($1) {
+            return [$1];
+        }),
+        o('Fields SEPARATOR Field', function ($1, $3) {
+            return $1.concat($3);
+        })
+    ],
+    Field                : [
+        o('STAR', function () {
+            return new Star();
+        }),
+        o('Expression', function ($1) {
+            return new Field($1);
+        }),
+        o('Expression AS Literal', function ($1, $3) {
+            return new Field($1, $3);
+        })
+    ]
+};
+
+const tokens = [];
+
+const operators = [
+    ['left', 'Op'],
+    ['left', 'MATH_MULTI'],
+    ['left', 'MATH'],
+    ['left', 'OPERATOR'],
+    ['left', 'CONDITIONAL']
+];
+
+for (let name in grammar) {
+    const alternatives = grammar[name];
+    grammar[name] = (function () {
+        const results = [];
+        for (let i = 0, len = alternatives.length; i < len; i++) {
+            const alt = alternatives[i];
+            const ref = alt[0].split(' ');
+            for (let j = 0, len1 = ref.length; j < len1; j++) {
+                token = ref[j];
+                if (!grammar[token]) {
+                    tokens.push(token);
+                }
+            }
+            if (name === 'Root') {
+                alt[1] = `return ${alt[1]}`;
+            }
+            results.push(alt);
+        }
+        return results;
+    })();
+}
+
+exports.parser = new Parser({
+    tokens     : tokens.join(' '),
+    bnf        : grammar,
+    operators  : operators.reverse(),
+    startSymbol: 'Root',
+}, {
+    moduleType: 'js',
+});
diff --git a/src/lexer.coffee b/src/lexer.coffee
deleted file mode 100644
index 4cb3d8b..0000000
--- a/src/lexer.coffee
+++ /dev/null
@@ -1,163 +0,0 @@
-class Lexer
-  constructor: (sql, opts={}) ->
-    @sql = sql
-    @preserveWhitespace = opts.preserveWhitespace || false
-    @tokens = []
-    @currentLine = 1
-    i = 0
-    while @chunk = sql.slice(i)
-      bytesConsumed =  @keywordToken() or
-                       @starToken() or
-                       @booleanToken() or
-                       @functionToken() or
-                       @windowExtension() or
-                       @sortOrderToken() or
-                       @seperatorToken() or
-                       @operatorToken() or
-                       @mathToken() or
-                       @dotToken() or
-                       @conditionalToken() or
-                       @betweenToken() or
-                       @subSelectOpToken() or
-                       @subSelectUnaryOpToken() or
-                       @numberToken() or
-                       @stringToken() or
-                       @parameterToken() or
-                       @parensToken() or
-                       @whitespaceToken() or
-                       @literalToken()
-      throw new Error("NOTHING CONSUMED: Stopped at - '#{@chunk.slice(0,30)}'") if bytesConsumed < 1
-      i += bytesConsumed
-    @token('EOF', '')
-    @postProcess()
-
-  postProcess: ->
-    for token, i in @tokens
-      if token[0] is 'STAR'
-        next_token = @tokens[i+1]
-        unless next_token[0] is 'SEPARATOR' or next_token[0] is 'FROM'
-          token[0] = 'MATH_MULTI'
-
-  token: (name, value) ->
-    @tokens.push([name, value, @currentLine])
-
-  tokenizeFromRegex: (name, regex, part=0, lengthPart=part, output=true) ->
-    return 0 unless match = regex.exec(@chunk)
-    partMatch = match[part]
-    @token(name, partMatch) if output
-    return match[lengthPart].length
-
-  tokenizeFromWord: (name, word=name) ->
-    word = @regexEscape(word)
-    matcher = if (/^\w+$/).test(word)
-      new RegExp("^(#{word})\\b",'ig')
-    else
-      new RegExp("^(#{word})",'ig')
-    match = matcher.exec(@chunk)
-    return 0 unless match
-    @token(name, match[1])
-    return match[1].length
-
-  tokenizeFromList: (name, list) ->
-    ret = 0
-    for entry in list
-      ret = @tokenizeFromWord(name, entry)
-      break if ret > 0
-    ret
-
-  keywordToken: ->
-    @tokenizeFromWord('SELECT') or
-    @tokenizeFromWord('DISTINCT') or
-    @tokenizeFromWord('FROM') or
-    @tokenizeFromWord('WHERE') or
-    @tokenizeFromWord('GROUP') or
-    @tokenizeFromWord('ORDER') or
-    @tokenizeFromWord('BY') or
-    @tokenizeFromWord('HAVING') or
-    @tokenizeFromWord('LIMIT') or
-    @tokenizeFromWord('JOIN') or
-    @tokenizeFromWord('LEFT') or
-    @tokenizeFromWord('RIGHT') or
-    @tokenizeFromWord('INNER') or
-    @tokenizeFromWord('OUTER') or
-    @tokenizeFromWord('ON') or
-    @tokenizeFromWord('AS') or
-    @tokenizeFromWord('UNION') or
-    @tokenizeFromWord('ALL') or
-    @tokenizeFromWord('LIMIT') or
-    @tokenizeFromWord('OFFSET') or
-    @tokenizeFromWord('FETCH') or
-    @tokenizeFromWord('ROW') or
-    @tokenizeFromWord('ROWS') or
-    @tokenizeFromWord('ONLY') or
-    @tokenizeFromWord('NEXT') or
-    @tokenizeFromWord('FIRST')
-
-  dotToken: -> @tokenizeFromWord('DOT', '.')
-  operatorToken:    -> @tokenizeFromList('OPERATOR', SQL_OPERATORS)
-  mathToken:        ->
-    @tokenizeFromList('MATH', MATH) or
-    @tokenizeFromList('MATH_MULTI', MATH_MULTI)
-  conditionalToken: -> @tokenizeFromList('CONDITIONAL', SQL_CONDITIONALS)
-  betweenToken:     -> @tokenizeFromList('BETWEEN', SQL_BETWEENS)
-  subSelectOpToken: -> @tokenizeFromList('SUB_SELECT_OP', SUB_SELECT_OP)
-  subSelectUnaryOpToken: -> @tokenizeFromList('SUB_SELECT_UNARY_OP', SUB_SELECT_UNARY_OP)
-  functionToken:    -> @tokenizeFromList('FUNCTION', SQL_FUNCTIONS)
-  sortOrderToken:   -> @tokenizeFromList('DIRECTION', SQL_SORT_ORDERS)
-  booleanToken:     -> @tokenizeFromList('BOOLEAN', BOOLEAN)
-
-  starToken:        -> @tokenizeFromRegex('STAR', STAR)
-  seperatorToken:   -> @tokenizeFromRegex('SEPARATOR', SEPARATOR)
-  literalToken:     -> @tokenizeFromRegex('LITERAL', LITERAL, 1, 0)
-  numberToken:      -> @tokenizeFromRegex('NUMBER', NUMBER)
-  parameterToken:   -> @tokenizeFromRegex('PARAMETER', PARAMETER)
-  stringToken:      ->
-    @tokenizeFromRegex('STRING', STRING, 1, 0) ||
-    @tokenizeFromRegex('DBLSTRING', DBLSTRING, 1, 0)
-
-
-  parensToken: ->
-    @tokenizeFromRegex('LEFT_PAREN', /^\(/,) or
-    @tokenizeFromRegex('RIGHT_PAREN', /^\)/,)
-
-  windowExtension: ->
-    match = (/^\.(win):(length|time)/i).exec(@chunk)
-    return 0 unless match
-    @token('WINDOW', match[1])
-    @token('WINDOW_FUNCTION', match[2])
-    match[0].length
-
-  whitespaceToken: ->
-    return 0 unless match = WHITESPACE.exec(@chunk)
-    partMatch = match[0]
-    newlines = partMatch.replace(/[^\n]/, '').length
-    @currentLine += newlines
-    @token(name, partMatch) if @preserveWhitespace
-    return partMatch.length
-
-  regexEscape: (str) ->
-    str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")
-
-  SQL_FUNCTIONS       = ['AVG', 'COUNT', 'MIN', 'MAX', 'SUM']
-  SQL_SORT_ORDERS     = ['ASC', 'DESC']
-  SQL_OPERATORS       = ['=', '!=', '>=', '>', '<=', '<>', '<', 'LIKE', 'IS NOT', 'IS']
-  SUB_SELECT_OP       = ['IN', 'NOT IN', 'ANY', 'ALL', 'SOME']
-  SUB_SELECT_UNARY_OP = ['EXISTS']
-  SQL_CONDITIONALS    = ['AND', 'OR']
-  SQL_BETWEENS        = ['BETWEEN', 'NOT BETWEEN']
-  BOOLEAN             = ['TRUE', 'FALSE', 'NULL']
-  MATH                = ['+', '-']
-  MATH_MULTI          = ['/', '*']
-  STAR                = /^\*/
-  SEPARATOR           = /^,/
-  WHITESPACE          = /^[ \n\r]+/
-  LITERAL             = /^`?([a-z_][a-z0-9_]{0,})`?/i
-  PARAMETER           = /^\$[0-9]+/
-  NUMBER              = /^[0-9]+(\.[0-9]+)?/
-  STRING              = /^'([^\\']*(?:\\.[^\\']*)*)'/
-  DBLSTRING           = /^"([^\\"]*(?:\\.[^\\"]*)*)"/
-
-
-
-exports.tokenize = (sql, opts) -> (new Lexer(sql, opts)).tokens
-
diff --git a/src/lexer.js b/src/lexer.js
new file mode 100644
index 0000000..da64488
--- /dev/null
+++ b/src/lexer.js
@@ -0,0 +1,273 @@
+const SQL_FUNCTIONS = ['AVG', 'COUNT', 'MIN', 'MAX', 'SUM'];
+const SQL_SORT_ORDERS = ['ASC', 'DESC'];
+const SQL_OPERATORS = ['=', '!=', '>=', '>', '<=', '<>', '<', 'LIKE', 'NOT LIKE', 'ILIKE', 'NOT ILIKE', 'IS NOT', 'IS', 'REGEXP', 'NOT REGEXP'];
+const SUB_SELECT_OP = ['IN', 'NOT IN', 'ANY', 'ALL', 'SOME'];
+const SUB_SELECT_UNARY_OP = ['EXISTS'];
+const SQL_CONDITIONALS = ['AND', 'OR'];
+const SQL_BETWEENS = ['BETWEEN', 'NOT BETWEEN'];
+const BOOLEAN = ['TRUE', 'FALSE', 'NULL'];
+const MATH = ['+', '-', '||', '&&'];
+const MATH_MULTI = ['/', '*'];
+const STAR = /^\*/;
+const SEPARATOR = /^,/;
+const WHITESPACE = /^[ \n\r]+/;
+const LITERAL = /^`?([a-z_][a-z0-9_]{0,}(\:(number|float|string|date|boolean))?)`?/i;
+const PARAMETER = /^\$([a-z0-9_]+(\:(number|float|string|date|boolean))?)/;
+const NUMBER = /^[+-]?[0-9]+(\.[0-9]+)?/;
+const STRING = /^'((?:[^\\']+?|\\.|'')*)'(?!')/;
+const DBLSTRING = /^"([^\\"]*(?:\\.[^\\"]*)*)"/;
+
+class Lexer {
+
+    constructor(sql, opts = {}) {
+        this.sql = sql;
+        this.preserveWhitespace = opts.preserveWhitespace || false;
+        this.tokens = [];
+        this.currentLine = 1;
+        this.currentOffset = 0;
+
+        let i = 0;
+        while (!!(this.chunk = sql.slice(i))) {
+            const bytesConsumed = this.keywordToken() ||
+                this.starToken() ||
+                this.booleanToken() ||
+                this.functionToken() ||
+                this.windowExtension() ||
+                this.sortOrderToken() ||
+                this.seperatorToken() ||
+                this.operatorToken() ||
+                this.numberToken() ||
+                this.mathToken() ||
+                this.dotToken() ||
+                this.conditionalToken() ||
+                this.betweenToken() ||
+                this.subSelectOpToken() ||
+                this.subSelectUnaryOpToken() ||
+                this.stringToken() ||
+                this.parameterToken() ||
+                this.parensToken() ||
+                this.whitespaceToken() ||
+                this.literalToken();
+
+            if (bytesConsumed < 1) {
+                throw new Error(`NOTHING CONSUMED: Stopped at - '${this.chunk.slice(0, 30)}'`);
+            }
+
+            i += bytesConsumed;
+            this.currentOffset += bytesConsumed;
+        }
+
+        this.token('EOF', '');
+        this.postProcess();
+    }
+
+    postProcess() {
+        const results = [];
+        for (let i =0, j = 0, len = this.tokens.length; j < len; i = ++j) {
+            const token = this.tokens[i];
+            if (token[0] === 'STAR') {
+                const next_token = this.tokens[i + 1];
+                if (!(next_token[0] === 'SEPARATOR' || next_token[0] === 'FROM')) {
+                    results.push(token[0] = 'MATH_MULTI');
+                }
+                else {
+                    results.push(void 0);
+                }
+            }
+            else {
+                results.push(void 0);
+            }
+        }
+        return results;
+    }
+
+    token(name, value) {
+        return this.tokens.push([name, value, this.currentLine, this.currentOffset]);
+    }
+
+    tokenizeFromStringRegex(name, regex, part = 0, lengthPart = part, output = true) {
+        const match = regex.exec(this.chunk);
+        if (!match) {
+            return 0;
+        }
+        const partMatch = match[part].replace(/''/g, '\'');
+        if (output) {
+            this.token(name, partMatch);
+        }
+        return match[lengthPart].length;
+    }
+
+    tokenizeFromRegex(name, regex, part = 0, lengthPart = part, output = true) {
+        const match = regex.exec(this.chunk);
+        if (!match) {
+            return 0;
+        }
+        const partMatch = match[part];
+        if (output) {
+            this.token(name, partMatch);
+        }
+        return match[lengthPart].length;
+    }
+
+    tokenizeFromWord(name, word = name) {
+        word = this.regexEscape(word);
+        const matcher = /^\w+$/.test(word) ? new RegExp(`^(${word})\\b`, 'ig') : new RegExp(`^(${word})`, 'ig');
+        const match = matcher.exec(this.chunk);
+        if (!match) {
+            return 0;
+        }
+        this.token(name, match[1]);
+        return match[1].length;
+    }
+
+    tokenizeFromList(name, list) {
+        let ret = 0;
+        for (let j = 0, len = list.length; j < len; j++) {
+            const entry = list[j];
+            ret = this.tokenizeFromWord(name, entry);
+            if (ret > 0) {
+                break;
+            }
+        }
+        return ret;
+    }
+
+    keywordToken() {
+        return this.tokenizeFromWord('SELECT') ||
+            this.tokenizeFromWord('INSERT') ||
+            this.tokenizeFromWord('INTO') ||
+            this.tokenizeFromWord('DEFAULT') ||
+            this.tokenizeFromWord('VALUES') ||
+            this.tokenizeFromWord('DISTINCT') ||
+            this.tokenizeFromWord('FROM') ||
+            this.tokenizeFromWord('WHERE') ||
+            this.tokenizeFromWord('GROUP') ||
+            this.tokenizeFromWord('ORDER') ||
+            this.tokenizeFromWord('BY') ||
+            this.tokenizeFromWord('HAVING') ||
+            this.tokenizeFromWord('LIMIT') ||
+            this.tokenizeFromWord('JOIN') ||
+            this.tokenizeFromWord('LEFT') ||
+            this.tokenizeFromWord('RIGHT') ||
+            this.tokenizeFromWord('INNER') ||
+            this.tokenizeFromWord('OUTER') ||
+            this.tokenizeFromWord('ON') ||
+            this.tokenizeFromWord('AS') ||
+            this.tokenizeFromWord('CASE') ||
+            this.tokenizeFromWord('WHEN') ||
+            this.tokenizeFromWord('THEN') ||
+            this.tokenizeFromWord('ELSE') ||
+            this.tokenizeFromWord('END') ||
+            this.tokenizeFromWord('UNION') ||
+            this.tokenizeFromWord('ALL') ||
+            this.tokenizeFromWord('LIMIT') ||
+            this.tokenizeFromWord('OFFSET') ||
+            this.tokenizeFromWord('FETCH') ||
+            this.tokenizeFromWord('ROW') ||
+            this.tokenizeFromWord('ROWS') ||
+            this.tokenizeFromWord('ONLY') ||
+            this.tokenizeFromWord('NEXT') ||
+            this.tokenizeFromWord('FIRST');
+    }
+
+    dotToken() {
+        return this.tokenizeFromWord('DOT', '.');
+    }
+
+    operatorToken() {
+        return this.tokenizeFromList('OPERATOR', SQL_OPERATORS);
+    }
+
+    mathToken() {
+        return this.tokenizeFromList('MATH', MATH) || this.tokenizeFromList('MATH_MULTI', MATH_MULTI);
+    }
+
+    conditionalToken() {
+        return this.tokenizeFromList('CONDITIONAL', SQL_CONDITIONALS);
+    }
+
+    betweenToken() {
+        return this.tokenizeFromList('BETWEEN', SQL_BETWEENS);
+    }
+
+    subSelectOpToken() {
+        return this.tokenizeFromList('SUB_SELECT_OP', SUB_SELECT_OP);
+    }
+
+    subSelectUnaryOpToken() {
+        return this.tokenizeFromList('SUB_SELECT_UNARY_OP', SUB_SELECT_UNARY_OP);
+    }
+
+    functionToken() {
+        return this.tokenizeFromList('FUNCTION', SQL_FUNCTIONS);
+    }
+
+    sortOrderToken() {
+        return this.tokenizeFromList('DIRECTION', SQL_SORT_ORDERS);
+    }
+
+    booleanToken() {
+        return this.tokenizeFromList('BOOLEAN', BOOLEAN);
+    }
+
+    starToken() {
+        return this.tokenizeFromRegex('STAR', STAR);
+    }
+
+    seperatorToken() {
+        return this.tokenizeFromRegex('SEPARATOR', SEPARATOR);
+    }
+
+    literalToken() {
+        return this.tokenizeFromRegex('LITERAL', LITERAL, 1, 0);
+    }
+
+    numberToken() {
+        return this.tokenizeFromRegex('NUMBER', NUMBER);
+    }
+
+    parameterToken() {
+        return this.tokenizeFromRegex('PARAMETER', PARAMETER, 1, 0);
+    }
+
+    stringToken() {
+        return this.tokenizeFromStringRegex('STRING', STRING, 1, 0) || this.tokenizeFromRegex('DBLSTRING', DBLSTRING, 1, 0);
+    }
+
+    parensToken() {
+        return this.tokenizeFromRegex('LEFT_PAREN', /^\(/) || this.tokenizeFromRegex('RIGHT_PAREN', /^\)/);
+    }
+
+    windowExtension() {
+        const match = /^\.(win):(length|time)/i.exec(this.chunk);
+        if (!match) {
+            return 0;
+        }
+        this.token('WINDOW', match[1]);
+        this.token('WINDOW_FUNCTION', match[2]);
+        return match[0].length;
+    }
+
+    whitespaceToken() {
+        const match = WHITESPACE.exec(this.chunk);
+        if (!match) {
+            return 0;
+        }
+        const partMatch = match[0];
+        if (this.preserveWhitespace) {
+            this.token('WHITESPACE', partMatch);
+        }
+        const newlines = partMatch.match(/\n/g, '');
+        this.currentLine += (newlines != null ? newlines.length : void 0) || 0;
+        return partMatch.length;
+    }
+
+    regexEscape(str) {
+        return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
+    }
+
+}
+
+exports.tokenize = function (sql, opts) {
+    return (new Lexer(sql, opts)).tokens;
+};
diff --git a/src/nodes.coffee b/src/nodes.coffee
deleted file mode 100644
index 119fd43..0000000
--- a/src/nodes.coffee
+++ /dev/null
@@ -1,164 +0,0 @@
-indent = (str) ->
-  ("  #{line}" for line in str.split("\n")).join("\n")
-
-exports.Select = class Select
-    constructor: (@fields, @source, @distinct=false, @joins=[], @unions=[]) ->
-      @order = null
-      @group = null
-      @where = null
-      @limit = null
-    toString: ->
-      ret = ["SELECT #{@fields.join(', ')}"]
-      ret.push indent("FROM #{@source}")
-      ret.push indent(join.toString()) for join in @joins
-      ret.push indent(@where.toString()) if @where
-      ret.push indent(@group.toString()) if @group
-      ret.push indent(@order.toString()) if @order
-      ret.push indent(@limit.toString()) if @limit
-      ret.push union.toString() for union in @unions
-      ret.join("\n")
-
-exports.SubSelect = class SubSelect
-  constructor: (@select, @name=null) -> null
-  toString: ->
-    ret = []
-    ret.push '('
-    ret.push indent(@select.toString())
-    ret.push if @name then ") #{@name.toString()}" else ")"
-    ret.join("\n")
-
-exports.Join = class Join
-  constructor: (@right, @conditions=null, @side=null, @mode=null) -> null
-  toString: ->
-    ret = ''
-    ret += "#{@side} " if @side?
-    ret += "#{@mode} " if @mode?
-    ret + "JOIN #{@right}\n" + indent("ON #{@conditions}")
-
-exports.Union = class Union
-  constructor: (@query, @all=false) -> null
-  toString: ->
-    all = if @all then ' ALL' else ''
-    "UNION#{all}\n#{@query.toString()}"
-
-exports.LiteralValue = class LiteralValue
-  constructor: (@value, @value2=null) ->
-    if @value2
-      @nested = true
-      @values = @value.values
-      @values.push(value2)
-    else
-      @nested = false
-      @values = [@value]
-  # TODO: Backtick quotes only supports MySQL, Postgres uses double-quotes
-  toString: -> "`#{@values.join('.')}`"
-
-exports.StringValue = class StringValue
-  constructor: (@value, @quoteType="''") -> null
-  toString: -> "#{@quoteType}#{@value}#{@quoteType}"
-
-exports.NumberValue = class LiteralValue
-  constructor: (value) -> @value = Number(value)
-  toString: -> @value.toString()
-
-exports.ListValue = class ListValue
-  constructor: (value) -> @value = value
-  toString: -> "(#{@value.join(', ')})"
-
-exports.ParameterValue = class ParameterValue
-  constructor: (value) ->
-    @value = value
-    @index = parseInt(value.substr(1), 10) - 1
-  toString: -> "#{@value}"
-
-exports.ArgumentListValue = class ArgumentListValue
-  constructor: (@value, @distinct=false) -> null
-  toString: ->
-    if @distinct
-      "DISTINCT #{@value.join(', ')}"
-    else
-      "#{@value.join(', ')}"
-
-exports.BooleanValue = class LiteralValue
-  constructor: (value) ->
-    @value = switch value.toLowerCase()
-      when 'true'
-        true
-      when 'false'
-        false
-      else
-        null
-  toString: -> if @value? then @value.toString().toUpperCase() else 'NULL'
-
-exports.FunctionValue = class FunctionValue
-  constructor: (@name, @arguments=null, @udf=false) -> null
-  toString: ->
-    if @arguments
-      "#{@name.toUpperCase()}(#{@arguments.toString()})"
-    else
-      "#{@name.toUpperCase()}()"
-
-exports.Order = class Order
-  constructor: (@orderings, @offset) ->
-  toString: -> "ORDER BY #{@orderings.join(', ')}" +
-    (if @offset then "\n" + @offset.toString() else "")
-
-exports.OrderArgument = class OrderArgument
-  constructor: (@value, @direction='ASC') -> null
-  toString: -> "#{@value} #{@direction}"
-
-exports.Offset = class Offset
-  constructor: (@row_count, @limit) -> null
-  toString: -> "OFFSET #{@row_count} ROWS" +
-    (if @limit then "\nFETCH NEXT #{@limit} ROWS ONLY" else "")
-
-exports.Limit = class Limit
-  constructor: (@value, @offset) -> null
-  toString: -> "LIMIT #{@value}" + (if @offset then "\nOFFSET #{@offset}" else "")
-
-exports.Table = class Table
-  constructor: (@name, @alias=null, @win=null, @winFn=null, @winArg=null) -> null
-  toString: ->
-    if @win
-      "#{@name}.#{@win}:#{@winFn}(#{@winArg})"
-    else if @alias
-      "#{@name} AS #{@alias}"
-    else
-      @name.toString()
-
-exports.Group = class Group
-  constructor: (@fields) ->
-    @having = null
-  toString: ->
-    ret = ["GROUP BY #{@fields.join(', ')}"]
-    ret.push @having.toString() if @having
-    ret.join("\n")
-
-exports.Where = class Where
-  constructor: (@conditions) -> null
-  toString: -> "WHERE #{@conditions}"
-
-exports.Having = class Having
-  constructor: (@conditions) -> null
-  toString: -> "HAVING #{@conditions}"
-
-exports.Op = class Op
-  constructor: (@operation, @left, @right) -> null
-  toString: -> "(#{@left} #{@operation.toUpperCase()} #{@right})"
-
-exports.UnaryOp = class UnaryOp
-  constructor: (@operator, @operand) -> null
-  toString: -> "(#{@operator.toUpperCase()} #{@operand})"
-
-exports.BetweenOp = class BetweenOp
-  constructor: (@value) -> null
-  toString: -> "#{@value.join(' AND ')}"
-
-exports.Field = class Field
-  constructor: (@field, @name=null) -> null
-  toString: -> if @name then "#{@field} AS #{@name}" else @field.toString()
-
-exports.Star = class Star
-  constructor: () -> null
-  toString: -> '*'
-  star: true
diff --git a/src/nodes.js b/src/nodes.js
new file mode 100644
index 0000000..c609cf3
--- /dev/null
+++ b/src/nodes.js
@@ -0,0 +1,436 @@
+function indent(str) {
+    return ((function () {
+        const ref = str.split('\n');
+        const results = [];
+        for (let i = 0, len = ref.length; i < len; i++) {
+            results.push(`  ${ref[i]}`);
+        }
+        return results;
+    })()).join('\n');
+}
+
+exports.Select = class Select {
+    constructor(fields, source, distinct = false, joins = [], unions = []) {
+        this.fields = fields;
+        this.source = source;
+        this.distinct = distinct;
+        this.joins = joins;
+        this.unions = unions;
+        this.order = null;
+        this.group = null;
+        this.where = null;
+        this.limit = null;
+    }
+
+    toString() {
+        const ret = [`SELECT ${this.fields.join(', ')}`];
+        ret.push(indent(`FROM ${this.source}`));
+        for (let i = 0, len = this.joins.length; i < len; i++) {
+            ret.push(indent(this.joins[i].toString()));
+        }
+        if (this.where) {
+            ret.push(indent(this.where.toString()));
+        }
+        if (this.group) {
+            ret.push(indent(this.group.toString()));
+        }
+        if (this.order) {
+            ret.push(indent(this.order.toString()));
+        }
+        if (this.limit) {
+            ret.push(indent(this.limit.toString()));
+        }
+        for (let j = 0, len1 = this.unions.length; j < len1; j++) {
+            ret.push(this.unions[j].toString());
+        }
+        return ret.join('\n');
+    }
+};
+
+exports.SubSelect = class SubSelect {
+    constructor(select, name = null) {
+        this.select = select;
+        this.name = name;
+    }
+
+    toString() {
+        const ret = [];
+        ret.push('(');
+        ret.push(indent(this.select.toString()));
+        ret.push(this.name ? `) ${this.name.toString()}` : ')');
+        return ret.join('\n');
+    }
+};
+
+exports.Join = class Join {
+    constructor(right, conditions = null, side = null, mode = null) {
+        this.right = right;
+        this.conditions = conditions;
+        this.side = side;
+        this.mode = mode;
+    }
+
+    toString() {
+        let ret = '';
+        if (this.side != null) {
+            ret += `${this.side} `;
+        }
+        if (this.mode != null) {
+            ret += `${this.mode} `;
+        }
+        return ret + `JOIN ${this.right}\n` + indent(`ON ${this.conditions}`);
+    }
+};
+
+exports.Union = class Union {
+    constructor(query, all1 = false) {
+        this.query = query;
+        this.all = all1;
+    }
+
+    toString() {
+        const all = this.all ? ' ALL' : '';
+        return `UNION${all}\n${this.query.toString()}`;
+    }
+};
+
+exports.LiteralValue = class LiteralValue {
+    constructor(value1, value2 = null) {
+        this.value = value1;
+        this.value2 = value2;
+        if (this.value2) {
+            this.nested = true;
+            this.values = this.value.values;
+            this.values.push(this.value2);
+        }
+        else {
+            this.nested = false;
+            this.values = [this.value];
+        }
+    }
+
+    // TODO: Backtick quotes only supports MySQL, Postgres uses double-quotes
+    toString(quote = true) {
+        if (quote) {
+            return `\`${this.values.join('`.`')}\``;
+        }
+        else {
+            return `${this.values.join('.')}`;
+        }
+    }
+};
+
+exports.StringValue = class StringValue {
+    constructor(value1, quoteType = '\'\'') {
+        this.value = value1;
+        this.quoteType = quoteType;
+    }
+
+    toString() {
+        const escaped = this.quoteType === '\'' ? this.value.replace(/(^|[^\\])'/g, '$1\'\'') : this.value;
+        return `${this.quoteType}${escaped}${this.quoteType}`;
+    }
+};
+
+exports.NumberValue = class NumberValue {
+    constructor(value) {
+        this.value = Number(value);
+    }
+
+    toString() {
+        return this.value.toString();
+    }
+};
+
+exports.ListValue = class ListValue {
+    constructor(value1) {
+        this.value = value1;
+    }
+
+    toString() {
+        return `(${this.value.join(', ')})`;
+    }
+};
+
+exports.WhitepaceList = class WhitepaceList {
+    constructor(value1) {
+        this.value = value1;
+    }
+
+    toString() {
+        // not backtick for literals
+        return this.value.map(function (value) {
+            if (value instanceof exports.LiteralValue) {
+                return value.toString(false);
+            }
+            else {
+                return value.toString();
+            }
+        }).join(' ');
+    }
+};
+
+exports.ParameterValue = class ParameterValue {
+    constructor(value) {
+        this.value = value;
+        this.index = parseInt(value.substr(1), 10) - 1;
+    }
+
+    toString() {
+        return `$${this.value}`;
+    }
+};
+
+exports.ArgumentListValue = class ArgumentListValue {
+    constructor(value1, distinct = false) {
+        this.value = value1;
+        this.distinct = distinct;
+    }
+
+    toString() {
+        if (this.distinct) {
+            return `DISTINCT ${this.value.join(', ')}`;
+        }
+        else {
+            return `${this.value.join(', ')}`;
+        }
+    }
+};
+
+exports.BooleanValue = class LiteralValue {
+    constructor(value) {
+        this.value = (function () {
+            switch (value.toLowerCase()) {
+                case 'true':
+                    return true;
+                case 'false':
+                    return false;
+                default:
+                    return null;
+            }
+        })();
+    }
+
+    toString() {
+        if (this.value != null) {
+            return this.value.toString().toUpperCase();
+        }
+        else {
+            return 'NULL';
+        }
+    }
+};
+
+exports.FunctionValue = class FunctionValue {
+    constructor(name, _arguments = null, udf = false) {
+        this.name = name;
+        this.arguments = _arguments;
+        this.udf = udf;
+    }
+
+    toString() {
+        if (this.arguments) {
+            return `${this.name.toUpperCase()}(${this.arguments.toString()})`;
+        }
+        else {
+            return `${this.name.toUpperCase()}()`;
+        }
+    }
+};
+
+exports.Case = class Case {
+    constructor(whens, _else) {
+        this.whens = whens;
+        this.else = _else;
+    }
+
+    toString() {
+        const whensStr = this.whens.map(function (w) {
+            return w.toString();
+        }).join(' ');
+        if (this.else) {
+            return `CASE ${whensStr} ${this.else.toString()} END`;
+        }
+        else {
+            return `CASE ${whensStr} END`;
+        }
+    }
+};
+
+exports.CaseWhen = class CaseWhen {
+    constructor(whenCondition, resCondition) {
+        this.whenCondition = whenCondition;
+        this.resCondition = resCondition;
+    }
+
+    toString() {
+        return `WHEN ${this.whenCondition} THEN ${this.resCondition}`;
+    }
+};
+
+exports.CaseElse = class CaseElse {
+    constructor(elseCondition) {
+        this.elseCondition = elseCondition;
+    }
+
+    toString() {
+        return `ELSE ${this.elseCondition}`;
+    }
+};
+
+exports.Order = class Order {
+    constructor(orderings, offset) {
+        this.orderings = orderings;
+        this.offset = offset;
+    }
+
+    toString() {
+        return `ORDER BY ${this.orderings.join(', ')}` + (this.offset ? '\n' + this.offset.toString() : '');
+    }
+};
+
+exports.OrderArgument = class OrderArgument {
+    constructor(value, direction = 'ASC') {
+        this.value = value;
+        this.direction = direction;
+        null;
+    }
+
+    toString() {
+        return `${this.value} ${this.direction}`;
+    }
+};
+
+exports.Offset = class Offset {
+    constructor(row_count, limit) {
+        this.row_count = row_count;
+        this.limit = limit;
+    }
+
+    toString() {
+        return `OFFSET ${this.row_count} ROWS` + (this.limit ? `\nFETCH NEXT ${this.limit} ROWS ONLY` : '');
+    }
+};
+
+exports.Limit = class Limit {
+    constructor(value1, offset) {
+        this.value = value1;
+        this.offset = offset;
+    }
+
+    toString() {
+        return `LIMIT ${this.value}` + (this.offset ? `\nOFFSET ${this.offset}` : '');
+    }
+};
+
+exports.Table = class Table {
+    constructor(name, alias = null, win = null, winFn = null, winArg = null) {
+        this.name = name;
+        this.alias = alias;
+        this.win = win;
+        this.winFn = winFn;
+        this.winArg = winArg;
+    }
+
+    toString() {
+        if (this.win) {
+            return `${this.name}.${this.win}:${this.winFn}(${this.winArg})`;
+        }
+        else if (this.alias) {
+            return `${this.name} AS ${this.alias}`;
+        }
+        else {
+            return this.name.toString();
+        }
+    }
+};
+
+exports.Group = class Group {
+    constructor(fields) {
+        this.fields = fields;
+        this.having = null;
+    }
+
+    toString() {
+        const ret = [`GROUP BY ${this.fields.join(', ')}`];
+        if (this.having) {
+            ret.push(this.having.toString());
+        }
+        return ret.join('\n');
+    }
+};
+
+exports.Where = class Where {
+    constructor(conditions) {
+        this.conditions = conditions;
+    }
+
+    toString() {
+        return `WHERE ${this.conditions}`;
+    }
+};
+
+exports.Having = class Having {
+    constructor(conditions) {
+        this.conditions = conditions;
+    }
+
+    toString() {
+        return `HAVING ${this.conditions}`;
+    }
+};
+
+exports.Op = class Op {
+    constructor(operation, left, right) {
+        this.operation = operation;
+        this.left = left;
+        this.right = right;
+    }
+
+    toString() {
+        return `(${this.left} ${this.operation.toUpperCase()} ${this.right})`;
+    }
+};
+
+exports.UnaryOp = class UnaryOp {
+    constructor(operator, operand) {
+        this.operator = operator;
+        this.operand = operand;
+    }
+
+    toString() {
+        return `(${this.operator.toUpperCase()} ${this.operand})`;
+    }
+};
+
+exports.BetweenOp = class BetweenOp {
+    constructor(value) {
+        this.value = value;
+    }
+
+    toString() {
+        return `${this.value.join(' AND ')}`;
+    }
+};
+
+exports.Field = class Field {
+    constructor(field, name = null) {
+        this.field = field;
+        this.name = name;
+    }
+
+    toString() {
+        if (this.name) {
+            return `${this.field} AS ${this.name}`;
+        }
+        else {
+            return this.field.toString();
+        }
+    }
+};
+
+exports.Star = class Star {
+    toString() {
+        return '*';
+    }
+};
diff --git a/src/parser.coffee b/src/parser.coffee
deleted file mode 100644
index 8b6632e..0000000
--- a/src/parser.coffee
+++ /dev/null
@@ -1,18 +0,0 @@
-buildParser = ->
-
-  parser = require('./compiled_parser').parser
-
-  parser.lexer =
-    lex: ->
-      [tag, @yytext, @yylineno] = @tokens[@pos++] or ['']
-      tag
-    setInput: (@tokens) -> @pos = 0
-    upcomingInput: -> ""
-    
-  parser.yy = require('./nodes')
-  
-  return parser
-  
-exports.parser = buildParser()
-
-exports.parse = (str) -> buildParser().parse(str)  
\ No newline at end of file
diff --git a/src/parser.js b/src/parser.js
new file mode 100644
index 0000000..1c1298b
--- /dev/null
+++ b/src/parser.js
@@ -0,0 +1,25 @@
+const parser = require('./compiled_parser').parser;
+const nodes = require('./nodes');
+
+parser.lexer = {
+    lex          : function () {
+        let tag;
+        [tag, this.yytext, this.yylineno] = this.tokens[this.pos++] || [''];
+        return tag;
+    },
+    setInput     : function (tokens) {
+        this.tokens = tokens;
+        return this.pos = 0;
+    },
+    upcomingInput: function () {
+        return '';
+    }
+};
+
+parser.yy = nodes;
+
+exports.parser = parser;
+
+exports.parse = function (str) {
+    return parser.parse(str);
+};
diff --git a/src/sql_parser.coffee b/src/sql_parser.coffee
deleted file mode 100644
index 77b7a72..0000000
--- a/src/sql_parser.coffee
+++ /dev/null
@@ -1,5 +0,0 @@
-exports.lexer   = require('./lexer')
-exports.parser  = require('./parser')
-exports.nodes   = require('./nodes')
-
-exports.parse = (sql) -> exports.parser.parse(exports.lexer.tokenize(sql))
\ No newline at end of file
diff --git a/src/sql_parser.js b/src/sql_parser.js
new file mode 100644
index 0000000..a47d934
--- /dev/null
+++ b/src/sql_parser.js
@@ -0,0 +1,7 @@
+exports.lexer = require('./lexer');
+exports.parser = require('./parser');
+exports.nodes = require('./nodes');
+
+exports.parse = function (sql) {
+    return exports.parser.parse(exports.lexer.tokenize(sql));
+};
diff --git a/test/__snapshots__/grammar.spec.js.snap b/test/__snapshots__/grammar.spec.js.snap
new file mode 100644
index 0000000..29ad545
--- /dev/null
+++ b/test/__snapshots__/grammar.spec.js.snap
@@ -0,0 +1,385 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`SQL Grammar Parameters parses query parameters 1`] = `
+"SELECT *
+  FROM \`foo\`
+  WHERE (\`bar\` = $12)"
+`;
+
+exports[`SQL Grammar SELECT Queries parses COUNT(DISTINCT field) 1`] = `
+"SELECT \`a\`, COUNT(DISTINCT \`b\`)
+  FROM \`my_table\`
+  LIMIT 10"
+`;
+
+exports[`SQL Grammar SELECT Queries parses GROUP BY and HAVING clauses 1`] = `
+"SELECT *
+  FROM \`my_table\`
+  GROUP BY \`x\`, \`y\`
+  HAVING (COUNT(\`y\`) > 1)"
+`;
+
+exports[`SQL Grammar SELECT Queries parses GROUP BY clauses 1`] = `
+"SELECT *
+  FROM \`my_table\`
+  GROUP BY \`x\`, \`y\`"
+`;
+
+exports[`SQL Grammar SELECT Queries parses LIMIT clauses 1`] = `
+"SELECT *
+  FROM \`my_table\`
+  LIMIT 10"
+`;
+
+exports[`SQL Grammar SELECT Queries parses LIMIT clauses after ORDER BY 1`] = `
+"SELECT *
+  FROM \`my_table\`
+  ORDER BY \`cat\` DESC
+  LIMIT 10"
+`;
+
+exports[`SQL Grammar SELECT Queries parses LIMIT clauses with OFFSET keyword 1`] = `
+"SELECT *
+  FROM \`my_table\`
+  LIMIT 10
+  OFFSET 30"
+`;
+
+exports[`SQL Grammar SELECT Queries parses LIMIT clauses with comma separated offset 1`] = `
+"SELECT *
+  FROM \`my_table\`
+  LIMIT 10
+  OFFSET 30"
+`;
+
+exports[`SQL Grammar SELECT Queries parses ORDER BY clauses 1`] = `
+"SELECT *
+  FROM \`my_table\`
+  ORDER BY \`x\` DESC"
+`;
+
+exports[`SQL Grammar SELECT Queries parses ORDER BY clauses with OFFSET n ROW 1`] = `
+"SELECT *
+  FROM \`my_table\`
+  ORDER BY \`x\` DESC
+  OFFSET 10 ROWS"
+`;
+
+exports[`SQL Grammar SELECT Queries parses ORDER BY clauses with OFFSET n ROW FETCH FIRST n ONLY 1`] = `
+"SELECT *
+  FROM \`my_table\`
+  ORDER BY \`x\` DESC
+  OFFSET 10 ROWS
+  FETCH NEXT 15 ROWS ONLY"
+`;
+
+exports[`SQL Grammar SELECT Queries parses ORDER BY clauses with OFFSET n ROW FETCH NEXT n ONLY 1`] = `
+"SELECT *
+  FROM \`my_table\`
+  ORDER BY \`x\` DESC
+  OFFSET 10 ROWS
+  FETCH NEXT 15 ROWS ONLY"
+`;
+
+exports[`SQL Grammar SELECT Queries parses ORDER BY clauses with OFFSET n ROWS 1`] = `
+"SELECT *
+  FROM \`my_table\`
+  ORDER BY \`x\` DESC
+  OFFSET 10 ROWS"
+`;
+
+exports[`SQL Grammar SELECT Queries parses SELECTs with FUNCTIONs 1`] = `
+"SELECT \`a\`, COUNT(1, \`b\`)
+  FROM \`my_table\`
+  LIMIT 10"
+`;
+
+exports[`SQL Grammar SELECT Queries parses SELECTs with FUNCTIONs without arguments 1`] = `
+"SELECT X(Y(Z()))
+  FROM \`X\`"
+`;
+
+exports[`SQL Grammar SELECT Queries parses UDFs 1`] = `
+"SELECT LENGTH(\`a\`)
+  FROM \`my_table\`"
+`;
+
+exports[`SQL Grammar SELECT Queries parses UNION ALL 1`] = `
+"SELECT *
+  FROM \`a\`
+UNION ALL
+SELECT *
+  FROM \`b\`"
+`;
+
+exports[`SQL Grammar SELECT Queries parses UNIONs 1`] = `
+"SELECT *
+  FROM \`a\`
+UNION
+SELECT *
+  FROM \`b\`
+UNION
+SELECT *
+  FROM \`c\`"
+`;
+
+exports[`SQL Grammar SELECT Queries parses WHERE clauses 1`] = `
+"SELECT *
+  FROM \`my_table\`
+  WHERE ((\`x\` > 1) AND (\`y\` = 'foo'))"
+`;
+
+exports[`SQL Grammar SELECT Queries parses WHERE clauses with BETWEEN operator 1`] = `
+"SELECT *
+  FROM \`my_table\`
+  WHERE (((\`a\` > 10) AND (\`b\` BETWEEN 4 AND 6)) AND (\`c\` = 4))"
+`;
+
+exports[`SQL Grammar SELECT Queries parses WHERE with GROUP BY and ORDER BY clauses 1`] = `
+"SELECT *
+  FROM \`my_table\`
+  WHERE (\`x\` > 1)
+  GROUP BY \`x\`, \`y\`
+  ORDER BY COUNT(\`y\`) ASC"
+`;
+
+exports[`SQL Grammar SELECT Queries parses WHERE with GROUP BY clauses 1`] = `
+"SELECT *
+  FROM \`my_table\`
+  WHERE (\`x\` > 1)
+  GROUP BY \`x\`, \`y\`"
+`;
+
+exports[`SQL Grammar SELECT Queries parses WHERE with ILIKE and NOT ILIKE clauses 1`] = `
+"SELECT *
+  FROM \`my_table\`
+  WHERE ((\`foo\` ILIKE '%a') AND (\`bar\` NOT ILIKE 'b%'))"
+`;
+
+exports[`SQL Grammar SELECT Queries parses WHERE with LIKE and NOT LIKE clauses 1`] = `
+"SELECT *
+  FROM \`my_table\`
+  WHERE ((\`foo\` LIKE '%a') AND (\`bar\` NOT LIKE 'b%'))"
+`;
+
+exports[`SQL Grammar SELECT Queries parses WHERE with NOT REGEXP clauses 1`] = `
+"SELECT *
+  FROM \`my_table\`
+  WHERE (((\`a\` > 10) AND (\`b\` NOT REGEXP '.*')) AND (\`c\` = 4))"
+`;
+
+exports[`SQL Grammar SELECT Queries parses WHERE with ORDER BY clauses 1`] = `
+"SELECT *
+  FROM \`my_table\`
+  WHERE (\`x\` > 1)
+  ORDER BY \`y\` ASC"
+`;
+
+exports[`SQL Grammar SELECT Queries parses WHERE with ORDER BY clauses with direction 1`] = `
+"SELECT *
+  FROM \`my_table\`
+  WHERE (\`x\` > 1)
+  ORDER BY \`y\` ASC"
+`;
+
+exports[`SQL Grammar SELECT Queries parses WHERE with REGEXP clauses 1`] = `
+"SELECT *
+  FROM \`my_table\`
+  WHERE (((\`a\` > 10) AND (\`b\` REGEXP '.*')) AND (\`c\` = 4))"
+`;
+
+exports[`SQL Grammar SELECT Queries parses WHERE with multiple ORDER BY clauses 1`] = `
+"SELECT *
+  FROM \`my_table\`
+  WHERE (\`x\` > 1)
+  ORDER BY \`x\` ASC, \`y\` DESC"
+`;
+
+exports[`SQL Grammar SELECT Queries parses WHERE with negative numbers and operaions 1`] = `
+"SELECT *
+  FROM \`my_table\`
+  WHERE (\`foo\` < (-5 - 4))"
+`;
+
+exports[`SQL Grammar SELECT Queries parses complex WHERE clauses 1`] = `
+"SELECT *
+  FROM \`my_table\`
+  WHERE ((\`a\` > 10) AND ((\`a\` < 30) OR (\`b\` = 'c')))"
+`;
+
+exports[`SQL Grammar SELECT Queries parses expressions in place of fields 1`] = `
+"SELECT (\`f\` + (LENGTH(\`f\`) / 3)) AS \`f1\`
+  FROM \`my_table\`"
+`;
+
+exports[`SQL Grammar SELECT Queries parses multiple joins 1`] = `
+"SELECT *
+  FROM \`a\`
+  JOIN \`b\`
+    ON (\`a\`.\`id\` = \`b\`.\`id\`)
+  JOIN \`c\`
+    ON (\`a\`.\`id\` = \`c\`.\`id\`)"
+`;
+
+exports[`SQL Grammar SELECT Queries parses named sub selects 1`] = `
+"SELECT *
+  FROM (
+    SELECT *
+      FROM \`my_table\`
+  ) \`t\`"
+`;
+
+exports[`SQL Grammar SELECT Queries parses right outer joins 1`] = `
+"SELECT *
+  FROM \`a\`
+  RIGHT OUTER JOIN \`b\`
+    ON (\`a\`.\`id\` = \`b\`.\`id\`)"
+`;
+
+exports[`SQL Grammar SELECT Queries parses single joins 1`] = `
+"SELECT *
+  FROM \`a\`
+  JOIN \`b\`
+    ON (\`a\`.\`id\` = \`b\`.\`id\`)"
+`;
+
+exports[`SQL Grammar SELECT Queries parses sub selects 1`] = `
+"SELECT *
+  FROM (
+    SELECT *
+      FROM \`my_table\`
+  )"
+`;
+
+exports[`SQL Grammar SELECT Queries supports IS and IS NOT 1`] = `
+"SELECT *
+  FROM \`my_table\`
+  WHERE ((\`a\` IS NULL) AND (\`b\` IS NOT NULL))"
+`;
+
+exports[`SQL Grammar SELECT Queries supports booleans 1`] = `
+"SELECT NULL
+  FROM \`my_table\`
+  WHERE (\`a\` = TRUE)"
+`;
+
+exports[`SQL Grammar SELECT Queries supports nested expressions 1`] = `
+"SELECT *
+  FROM \`my_table\`
+  WHERE MOD((LENGTH(\`a\`) + LENGTH(\`b\`)), \`c\`)"
+`;
+
+exports[`SQL Grammar SELECT Queries supports nested fields using dot syntax 1`] = `
+"SELECT \`a\`.\`b\`.\`c\`
+  FROM \`my_table\`
+  WHERE (\`a\`.\`b\` > 2)"
+`;
+
+exports[`SQL Grammar SELECT Queries supports time window extensions 1`] = `
+"SELECT *
+  FROM \`my_table\`.win:length(123)"
+`;
+
+exports[`SQL Grammar STARS parses stars as multiplication 1`] = `
+"SELECT *
+  FROM \`foo\`
+  WHERE (\`a\` = (1 * 2))"
+`;
+
+exports[`SQL Grammar aliases parses aliased table names 1`] = `
+"SELECT *
+  FROM \`a\` AS \`b\`"
+`;
+
+exports[`SQL Grammar aliases parses aliased table names with as 1`] = `
+"SELECT *
+  FROM \`a\` AS \`b\`"
+`;
+
+exports[`SQL Grammar functions parses function with complex arguments 1`] = `
+"SELECT *
+  FROM \`foo\`
+  WHERE (\`bar\` < DATE_SUB(NOW(), INTERVAL 14 DAYS))"
+`;
+
+exports[`SQL Grammar misc parses case when statements 1`] = `
+"SELECT CASE WHEN (\`foo\` = 'a') THEN \`a\` WHEN (\`foo\` = 'b') THEN \`b\` ELSE \`c\` END
+  FROM \`table\`"
+`;
+
+exports[`SQL Grammar misc parses nested AND 1`] = `
+"SELECT *
+  FROM \`a\`
+  WHERE (((\`id\` = 1) AND ((\`id\` = 2) AND (\`type\` = 'foo'))) AND ((\`id\` = 3) AND (\`type\` = 'bar')))"
+`;
+
+exports[`SQL Grammar string quoting allows nesting different quote styles 1`] = `
+"SELECT *
+  FROM \`a\`
+  WHERE (\`foo\` = \\"I'm\\")"
+`;
+
+exports[`SQL Grammar string quoting allows using double quotes 1`] = `
+"SELECT *
+  FROM \`a\`
+  WHERE (\`foo\` = \\"a\\")"
+`;
+
+exports[`SQL Grammar string quoting allows using two single quotes 1`] = `
+"SELECT *
+  FROM \`a\`
+  WHERE (\`foo\` = 'I''m')"
+`;
+
+exports[`SQL Grammar string quoting doesn't choke on escaped quotes 1`] = `
+"SELECT *
+  FROM \`a\`
+  WHERE (\`foo\` = 'I\\\\'m')"
+`;
+
+exports[`SQL Grammar string quoting parses single quote 1`] = `
+"SELECT *
+  FROM \`a\`
+  WHERE (\`foo\` = '''')"
+`;
+
+exports[`SQL Grammar subselect clauses parses a NOT IN clause containing a query 1`] = `
+"SELECT *
+  FROM \`a\`
+  WHERE (\`x\` NOT IN (
+    SELECT \`foo\`
+      FROM \`bar\`
+  ))"
+`;
+
+exports[`SQL Grammar subselect clauses parses a subselect field 1`] = `
+"SELECT (
+  SELECT \`x\`
+    FROM \`y\`
+)
+  FROM \`a\`"
+`;
+
+exports[`SQL Grammar subselect clauses parses an EXISTS clause containing a query 1`] = `
+"SELECT *
+  FROM \`a\`
+  WHERE (EXISTS (
+    SELECT \`foo\`
+      FROM \`bar\`
+  ))"
+`;
+
+exports[`SQL Grammar subselect clauses parses an IN clause containing a list 1`] = `
+"SELECT *
+  FROM \`a\`
+  WHERE (\`x\` IN (1, 2, 3))"
+`;
+
+exports[`SQL Grammar subselect clauses parses an IN clause containing a query 1`] = `
+"SELECT *
+  FROM \`a\`
+  WHERE (\`x\` IN (
+    SELECT \`foo\`
+      FROM \`bar\`
+  ))"
+`;
diff --git a/test/grammar.spec.coffee b/test/grammar.spec.coffee
deleted file mode 100644
index c681f7c..0000000
--- a/test/grammar.spec.coffee
+++ /dev/null
@@ -1,384 +0,0 @@
-lexer = require('../lib/lexer')
-parser = require("../lib/parser")
-
-parse = (query) ->
-  parser.parse(lexer.tokenize(query))
-
-describe "SQL Grammar", ->
-  describe "SELECT Queries", ->
-
-    it "parses ORDER BY clauses", ->
-      parse("SELECT * FROM my_table ORDER BY x DESC").toString().should.eql """
-      SELECT *
-        FROM `my_table`
-        ORDER BY `x` DESC
-      """
-
-    it "parses ORDER BY clauses with OFFSET n ROWS", ->
-      parse("SELECT * FROM my_table ORDER BY x DESC OFFSET 10 ROWS").toString().should.eql """
-      SELECT *
-        FROM `my_table`
-        ORDER BY `x` DESC
-        OFFSET 10 ROWS
-      """
-
-    it "parses ORDER BY clauses with OFFSET n ROW", ->
-      parse("SELECT * FROM my_table ORDER BY x DESC OFFSET 10 ROW").toString().should.eql """
-      SELECT *
-        FROM `my_table`
-        ORDER BY `x` DESC
-        OFFSET 10 ROWS
-      """
-
-    it "parses ORDER BY clauses with OFFSET n ROW FETCH FIRST n ONLY", ->
-      parse("SELECT * FROM my_table ORDER BY x DESC OFFSET 10 ROW FETCH FIRST 15 ROW ONLY").toString().should.eql """
-      SELECT *
-        FROM `my_table`
-        ORDER BY `x` DESC
-        OFFSET 10 ROWS
-        FETCH NEXT 15 ROWS ONLY
-      """
-
-    it "parses ORDER BY clauses with OFFSET n ROW FETCH NEXT n ONLY", ->
-      parse("SELECT * FROM my_table ORDER BY x DESC OFFSET 10 ROW FETCH NEXT 15 ROWS ONLY").toString().should.eql """
-      SELECT *
-        FROM `my_table`
-        ORDER BY `x` DESC
-        OFFSET 10 ROWS
-        FETCH NEXT 15 ROWS ONLY
-      """
-
-    it "parses GROUP BY clauses", ->
-      parse("SELECT * FROM my_table GROUP BY x, y").toString().should.eql """
-      SELECT *
-        FROM `my_table`
-        GROUP BY `x`, `y`
-      """
-
-    it "parses LIMIT clauses", ->
-      parse("SELECT * FROM my_table LIMIT 10").toString().should.eql """
-      SELECT *
-        FROM `my_table`
-        LIMIT 10
-      """
-
-    it "parses LIMIT clauses after ORDER BY", ->
-      parse("SELECT * FROM my_table ORDER BY cat DESC LIMIT 10").toString().should.eql """
-      SELECT *
-        FROM `my_table`
-        ORDER BY `cat` DESC
-        LIMIT 10
-      """
-
-    it "parses LIMIT clauses with comma separated offset", ->
-      parse("SELECT * FROM my_table LIMIT 30, 10").toString().should.eql """
-      SELECT *
-        FROM `my_table`
-        LIMIT 10
-        OFFSET 30
-      """
-
-    it "parses LIMIT clauses with OFFSET keyword", ->
-      parse("SELECT * FROM my_table LIMIT 10 OFFSET 30").toString().should.eql """
-      SELECT *
-        FROM `my_table`
-        LIMIT 10
-        OFFSET 30
-      """
-
-    it "parses SELECTs with FUNCTIONs without arguments", ->
-      parse("SELECT X(Y(Z())) FROM X").toString().should.eql """
-      SELECT X(Y(Z()))
-        FROM `X`
-      """
-
-    it "parses SELECTs with FUNCTIONs", ->
-      parse("SELECT a, COUNT(1, b) FROM my_table LIMIT 10").toString().should.eql """
-      SELECT `a`, COUNT(1, `b`)
-        FROM `my_table`
-        LIMIT 10
-      """
-
-    it "parses COUNT(DISTINCT field)", ->
-      parse("select a, count(distinct b) FROM my_table limit 10").toString().should.eql """
-      SELECT `a`, COUNT(DISTINCT `b`)
-        FROM `my_table`
-        LIMIT 10
-      """
-
-    it "parses WHERE clauses", ->
-      parse("SELECT * FROM my_table WHERE x > 1 AND y = 'foo'").toString().should.eql """
-      SELECT *
-        FROM `my_table`
-        WHERE ((`x` > 1) AND (`y` = 'foo'))
-      """
-
-    it "parses complex WHERE clauses", ->
-      parse("SELECT * FROM my_table WHERE a > 10 AND (a < 30 OR b = 'c')").toString().should.eql """
-      SELECT *
-        FROM `my_table`
-        WHERE ((`a` > 10) AND ((`a` < 30) OR (`b` = 'c')))
-      """
-
-    it "parses WHERE clauses with BETWEEN operator", ->
-      parse("SELECT * FROM my_table WHERE a > 10 AND b BETWEEN 4 AND 6 AND c = 4").toString().should.eql """
-      SELECT *
-        FROM `my_table`
-        WHERE (((`a` > 10) AND (`b` BETWEEN 4 AND 6)) AND (`c` = 4))
-      """
-
-    it "parses WHERE with ORDER BY clauses", ->
-      parse("SELECT * FROM my_table WHERE x > 1 ORDER BY y").toString().should.eql """
-      SELECT *
-        FROM `my_table`
-        WHERE (`x` > 1)
-        ORDER BY `y` ASC
-      """
-
-    it "parses WHERE with multiple ORDER BY clauses", ->
-      parse("SELECT * FROM my_table WHERE x > 1 ORDER BY x, y DESC").toString().should.eql """
-      SELECT *
-        FROM `my_table`
-        WHERE (`x` > 1)
-        ORDER BY `x` ASC, `y` DESC
-      """
-
-    it "parses WHERE with ORDER BY clauses with direction", ->
-      parse("SELECT * FROM my_table WHERE x > 1 ORDER BY y ASC").toString().should.eql """
-      SELECT *
-        FROM `my_table`
-        WHERE (`x` > 1)
-        ORDER BY `y` ASC
-      """
-
-    it "parses WHERE with GROUP BY clauses", ->
-      parse("SELECT * FROM my_table WHERE x > 1 GROUP BY x, y").toString().should.eql """
-      SELECT *
-        FROM `my_table`
-        WHERE (`x` > 1)
-        GROUP BY `x`, `y`
-      """
-
-    it "parses WHERE with GROUP BY and ORDER BY clauses", ->
-      parse("SELECT * FROM my_table WHERE x > 1 GROUP BY x, y ORDER BY COUNT(y) ASC").toString().should.eql """
-      SELECT *
-        FROM `my_table`
-        WHERE (`x` > 1)
-        GROUP BY `x`, `y`
-        ORDER BY COUNT(`y`) ASC
-      """
-
-    it "parses GROUP BY and HAVING clauses", ->
-      parse("SELECT * FROM my_table GROUP BY x, y HAVING COUNT(`y`) > 1").toString().should.eql """
-      SELECT *
-        FROM `my_table`
-        GROUP BY `x`, `y`
-        HAVING (COUNT(`y`) > 1)
-      """
-
-    it "parses UDFs", ->
-      parse("SELECT LENGTH(a) FROM my_table").toString().should.eql """
-      SELECT LENGTH(`a`)
-        FROM `my_table`
-      """
-
-    it "parses expressions in place of fields", ->
-      parse("SELECT f+LENGTH(f)/3 AS f1 FROM my_table").toString().should.eql """
-      SELECT (`f` + (LENGTH(`f`) / 3)) AS `f1`
-        FROM `my_table`
-      """
-
-    it "supports booleans", ->
-      parse("SELECT null FROM my_table WHERE a = true").toString().should.eql """
-      SELECT NULL
-        FROM `my_table`
-        WHERE (`a` = TRUE)
-      """
-
-    it "supports IS and IS NOT", ->
-      parse("SELECT * FROM my_table WHERE a IS NULL AND b IS NOT NULL").toString().should.eql """
-      SELECT *
-        FROM `my_table`
-        WHERE ((`a` IS NULL) AND (`b` IS NOT NULL))
-      """
-
-    it "supports nested expressions", ->
-      parse("SELECT * FROM my_table WHERE MOD(LENGTH(a) + LENGTH(b), c)").toString().should.eql """
-      SELECT *
-        FROM `my_table`
-        WHERE MOD((LENGTH(`a`) + LENGTH(`b`)), `c`)
-      """
-
-    it "supports nested fields using dot syntax", ->
-      parse("SELECT a.b.c FROM my_table WHERE a.b > 2").toString().should.eql """
-      SELECT `a.b.c`
-        FROM `my_table`
-        WHERE (`a.b` > 2)
-      """
-
-    it "supports time window extensions", ->
-      parse("SELECT * FROM my_table.win:length(123)").toString().should.eql """
-      SELECT *
-        FROM `my_table`.win:length(123)
-      """
-
-    it "parses sub selects", ->
-      parse("select * from (select * from my_table)").toString().should.eql """
-      SELECT *
-        FROM (
-          SELECT *
-            FROM `my_table`
-        )
-      """
-
-    it "parses named sub selects", ->
-      parse("select * from (select * from my_table) t").toString().should.eql """
-      SELECT *
-        FROM (
-          SELECT *
-            FROM `my_table`
-        ) `t`
-      """
-
-    it "parses single joins", ->
-      parse("select * from a join b on a.id = b.id").toString().should.eql """
-      SELECT *
-        FROM `a`
-        JOIN `b`
-          ON (`a.id` = `b.id`)
-      """
-
-    it "parses right outer joins", ->
-      parse("select * from a right outer join b on a.id = b.id").toString().should.eql """
-      SELECT *
-        FROM `a`
-        RIGHT OUTER JOIN `b`
-          ON (`a.id` = `b.id`)
-      """
-
-    it "parses multiple joins", ->
-      parse("select * from a join b on a.id = b.id join c on a.id = c.id").toString().should.eql """
-      SELECT *
-        FROM `a`
-        JOIN `b`
-          ON (`a.id` = `b.id`)
-        JOIN `c`
-          ON (`a.id` = `c.id`)
-      """
-
-    it "parses UNIONs", ->
-      parse("select * from a union select * from b").toString().should.eql """
-      SELECT *
-        FROM `a`
-      UNION
-      SELECT *
-        FROM `b`
-      """
-
-    it "parses UNION ALL", ->
-      parse("select * from a union all select * from b").toString().should.eql """
-      SELECT *
-        FROM `a`
-      UNION ALL
-      SELECT *
-        FROM `b`
-      """
-
-  describe "string quoting", ->
-    it "doesn't choke on escaped quotes", ->
-      parse("select * from a where foo = 'I\\'m'").toString().should.eql """
-      SELECT *
-        FROM `a`
-        WHERE (`foo` = 'I\\'m')
-      """
-
-    it "allows using double quotes", ->
-      parse('select * from a where foo = "a"').toString().should.eql """
-      SELECT *
-        FROM `a`
-        WHERE (`foo` = "a")
-      """
-
-    it "allows nesting different quote styles", ->
-      parse("""select * from a where foo = "I'm" """).toString().should.eql """
-      SELECT *
-        FROM `a`
-        WHERE (`foo` = "I'm")
-      """
-
-  describe "subselect clauses", ->
-    it "parses a subselect field", ->
-      parse("""select (select x from y) from a""").toString().should.eql """
-      SELECT (
-        SELECT `x`
-          FROM `y`
-      )
-        FROM `a`
-      """
-
-    it "parses an IN clause containing a list", ->
-      parse("""select * from a where x in (1,2,3)""").toString().should.eql """
-      SELECT *
-        FROM `a`
-        WHERE (`x` IN (1, 2, 3))
-      """
-
-    it "parses an IN clause containing a query", ->
-      parse("""select * from a where x in (select foo from bar)""").toString().should.eql """
-      SELECT *
-        FROM `a`
-        WHERE (`x` IN (
-          SELECT `foo`
-            FROM `bar`
-        ))
-      """
-
-    it "parses a NOT IN clause containing a query", ->
-      parse("""select * from a where x not in (select foo from bar)""").toString().should.eql """
-      SELECT *
-        FROM `a`
-        WHERE (`x` NOT IN (
-          SELECT `foo`
-            FROM `bar`
-        ))
-      """
-
-    it "parses an EXISTS clause containing a query", ->
-      parse("""select * from a where exists (select foo from bar)""").toString().should.eql """
-      SELECT *
-        FROM `a`
-        WHERE (EXISTS (
-          SELECT `foo`
-            FROM `bar`
-        ))
-      """
-
-  describe "aliases", ->
-    it "parses aliased table names", ->
-      parse("""select * from a b""").toString().should.eql """
-      SELECT *
-        FROM `a` AS `b`
-      """
-
-    it "parses aliased table names with as", ->
-      parse("""select * from a as b""").toString().should.eql """
-      SELECT *
-        FROM `a` AS `b`
-      """
-
-  describe "STARS", ->
-    it "parses stars as multiplication", ->
-      parse('SELECT * FROM foo WHERE a = 1*2').toString().should.eql """
-      SELECT *
-        FROM `foo`
-        WHERE (`a` = (1 * 2))
-      """
-
-  describe "Parameters", ->
-    it "parses query parameters", ->
-      parse('select * from foo where bar = $12').toString().should.eql """
-      SELECT *
-        FROM `foo`
-        WHERE (`bar` = $12)
-      """
-
diff --git a/test/grammar.spec.js b/test/grammar.spec.js
new file mode 100644
index 0000000..1d019c3
--- /dev/null
+++ b/test/grammar.spec.js
@@ -0,0 +1,257 @@
+const lexer = require('../src/lexer');
+const parser = require('../src/parser');
+
+function parse(query) {
+    return parser.parse(lexer.tokenize(query)).toString();
+}
+
+describe('SQL Grammar', function () {
+    describe('SELECT Queries', function () {
+        it('parses ORDER BY clauses', function () {
+            expect(parse('SELECT * FROM my_table ORDER BY x DESC')).toMatchSnapshot();
+        });
+
+        it('parses ORDER BY clauses with OFFSET n ROWS', function () {
+            expect(parse('SELECT * FROM my_table ORDER BY x DESC OFFSET 10 ROWS')).toMatchSnapshot();
+        });
+
+        it('parses ORDER BY clauses with OFFSET n ROW', function () {
+            expect(parse('SELECT * FROM my_table ORDER BY x DESC OFFSET 10 ROW')).toMatchSnapshot();
+        });
+
+        it('parses ORDER BY clauses with OFFSET n ROW FETCH FIRST n ONLY', function () {
+            expect(parse('SELECT * FROM my_table ORDER BY x DESC OFFSET 10 ROW FETCH FIRST 15 ROW ONLY')).toMatchSnapshot();
+        });
+
+        it('parses ORDER BY clauses with OFFSET n ROW FETCH NEXT n ONLY', function () {
+            expect(parse('SELECT * FROM my_table ORDER BY x DESC OFFSET 10 ROW FETCH NEXT 15 ROWS ONLY')).toMatchSnapshot();
+        });
+
+        it('parses GROUP BY clauses', function () {
+            expect(parse('SELECT * FROM my_table GROUP BY x, y')).toMatchSnapshot();
+        });
+
+        it('parses LIMIT clauses', function () {
+            expect(parse('SELECT * FROM my_table LIMIT 10')).toMatchSnapshot();
+        });
+
+        it('parses LIMIT clauses after ORDER BY', function () {
+            expect(parse('SELECT * FROM my_table ORDER BY cat DESC LIMIT 10')).toMatchSnapshot();
+        });
+
+        it('parses LIMIT clauses with comma separated offset', function () {
+            expect(parse('SELECT * FROM my_table LIMIT 30, 10')).toMatchSnapshot();
+        });
+
+        it('parses LIMIT clauses with OFFSET keyword', function () {
+            expect(parse('SELECT * FROM my_table LIMIT 10 OFFSET 30')).toMatchSnapshot();
+        });
+
+        it('parses SELECTs with FUNCTIONs without arguments', function () {
+            expect(parse('SELECT X(Y(Z())) FROM X')).toMatchSnapshot();
+        });
+
+        it('parses SELECTs with FUNCTIONs', function () {
+            expect(parse('SELECT a, COUNT(1, b) FROM my_table LIMIT 10')).toMatchSnapshot();
+        });
+
+        it('parses COUNT(DISTINCT field)', function () {
+            expect(parse('select a, count(distinct b) FROM my_table limit 10')).toMatchSnapshot();
+        });
+
+        it('parses WHERE clauses', function () {
+            expect(parse('SELECT * FROM my_table WHERE x > 1 AND y = \'foo\'')).toMatchSnapshot();
+        });
+
+        it('parses complex WHERE clauses', function () {
+            expect(parse('SELECT * FROM my_table WHERE a > 10 AND (a < 30 OR b = \'c\')')).toMatchSnapshot();
+        });
+
+        it('parses WHERE with REGEXP clauses', function () {
+            expect(parse('SELECT * FROM my_table WHERE a > 10 AND b REGEXP \'.*\' AND c = 4')).toMatchSnapshot();
+        });
+
+        it('parses WHERE with NOT REGEXP clauses', function () {
+            expect(parse('SELECT * FROM my_table WHERE a > 10 AND b NOT REGEXP \'.*\' AND c = 4')).toMatchSnapshot();
+        });
+
+        it('parses WHERE clauses with BETWEEN operator', function () {
+            expect(parse('SELECT * FROM my_table WHERE a > 10 AND b BETWEEN 4 AND 6 AND c = 4')).toMatchSnapshot();
+        });
+
+        it('parses WHERE with LIKE and NOT LIKE clauses', function () {
+            expect(parse('SELECT * FROM my_table WHERE foo LIKE \'%a\' AND bar NOT LIKE \'b%\'')).toMatchSnapshot();
+        });
+
+        it('parses WHERE with ILIKE and NOT ILIKE clauses', function () {
+            expect(parse('SELECT * FROM my_table WHERE foo ILIKE \'%a\' AND bar NOT ILIKE \'b%\'')).toMatchSnapshot();
+        });
+
+        it('parses WHERE with ORDER BY clauses', function () {
+            expect(parse('SELECT * FROM my_table WHERE x > 1 ORDER BY y')).toMatchSnapshot();
+        });
+
+        it('parses WHERE with multiple ORDER BY clauses', function () {
+            expect(parse('SELECT * FROM my_table WHERE x > 1 ORDER BY x, y DESC')).toMatchSnapshot();
+        });
+
+        it('parses WHERE with ORDER BY clauses with direction', function () {
+            expect(parse('SELECT * FROM my_table WHERE x > 1 ORDER BY y ASC')).toMatchSnapshot();
+        });
+
+        it('parses WHERE with GROUP BY clauses', function () {
+            expect(parse('SELECT * FROM my_table WHERE x > 1 GROUP BY x, y')).toMatchSnapshot();
+        });
+
+        it('parses WHERE with GROUP BY and ORDER BY clauses', function () {
+            expect(parse('SELECT * FROM my_table WHERE x > 1 GROUP BY x, y ORDER BY COUNT(y) ASC')).toMatchSnapshot();
+        });
+
+        it('parses WHERE with negative numbers and operaions', function () {
+            expect(parse('SELECT * FROM my_table WHERE foo < -5 - 4')).toMatchSnapshot();
+        });
+
+        it('parses GROUP BY and HAVING clauses', function () {
+            expect(parse('SELECT * FROM my_table GROUP BY x, y HAVING COUNT(`y`) > 1')).toMatchSnapshot();
+        });
+
+        it('parses UDFs', function () {
+            expect(parse('SELECT LENGTH(a) FROM my_table')).toMatchSnapshot();
+        });
+
+        it('parses expressions in place of fields', function () {
+            expect(parse('SELECT f+LENGTH(f)/3 AS f1 FROM my_table')).toMatchSnapshot();
+        });
+
+        it('supports booleans', function () {
+            expect(parse('SELECT null FROM my_table WHERE a = true')).toMatchSnapshot();
+        });
+
+        it('supports IS and IS NOT', function () {
+            expect(parse('SELECT * FROM my_table WHERE a IS NULL AND b IS NOT NULL')).toMatchSnapshot();
+        });
+
+        it('supports nested expressions', function () {
+            expect(parse('SELECT * FROM my_table WHERE MOD(LENGTH(a) + LENGTH(b), c)')).toMatchSnapshot();
+        });
+
+        it('supports nested fields using dot syntax', function () {
+            expect(parse('SELECT a.b.c FROM my_table WHERE a.b > 2')).toMatchSnapshot();
+        });
+
+        it('supports time window extensions', function () {
+            expect(parse('SELECT * FROM my_table.win:length(123)')).toMatchSnapshot();
+        });
+
+        it('parses sub selects', function () {
+            expect(parse('select * from (select * from my_table)')).toMatchSnapshot();
+        });
+
+        it('parses named sub selects', function () {
+            expect(parse('select * from (select * from my_table) t')).toMatchSnapshot();
+        });
+
+        it('parses single joins', function () {
+            expect(parse('select * from a join b on a.id = b.id')).toMatchSnapshot();
+        });
+
+        it('parses right outer joins', function () {
+            expect(parse('select * from a right outer join b on a.id = b.id')).toMatchSnapshot();
+        });
+
+        it('parses multiple joins', function () {
+            expect(parse('select * from a join b on a.id = b.id join c on a.id = c.id')).toMatchSnapshot();
+        });
+
+        it('parses UNIONs', function () {
+            expect(parse('select * from a union select * from b union select * from c')).toMatchSnapshot();
+        });
+
+        it('parses UNION ALL', function () {
+            expect(parse('select * from a union all select * from b')).toMatchSnapshot();
+        });
+    });
+
+    describe('string quoting', function () {
+        it('doesn\'t choke on escaped quotes', function () {
+            expect(parse('select * from a where foo = \'I\\\'m\'')).toMatchSnapshot();
+        });
+
+        it('parses single quote', function () {
+            expect(parse('select * from a where foo = \'\'\'\'')).toMatchSnapshot();
+        });
+
+        it('allows using double quotes', function () {
+            expect(parse('select * from a where foo = "a"')).toMatchSnapshot();
+        });
+
+        it('allows using two single quotes', function () {
+            expect(parse('select * from a where foo = \'I\'\'m\'')).toMatchSnapshot();
+        });
+
+        it('allows nesting different quote styles', function () {
+            expect(parse('select * from a where foo = "I\'m" ')).toMatchSnapshot();
+        });
+    });
+
+    describe('subselect clauses', function () {
+        it('parses a subselect field', function () {
+            expect(parse('select (select x from y) from a')).toMatchSnapshot();
+        });
+
+        it('parses an IN clause containing a list', function () {
+            expect(parse('select * from a where x in (1,2,3)')).toMatchSnapshot();
+        });
+
+        it('parses an IN clause containing a query', function () {
+            expect(parse('select * from a where x in (select foo from bar)')).toMatchSnapshot();
+        });
+
+        it('parses a NOT IN clause containing a query', function () {
+            expect(parse('select * from a where x not in (select foo from bar)')).toMatchSnapshot();
+        });
+
+        it('parses an EXISTS clause containing a query', function () {
+            expect(parse('select * from a where exists (select foo from bar)')).toMatchSnapshot();
+        });
+    });
+
+    describe('aliases', function () {
+        it('parses aliased table names', function () {
+            expect(parse('select * from a b')).toMatchSnapshot();
+        });
+
+        it('parses aliased table names with as', function () {
+            expect(parse('select * from a as b')).toMatchSnapshot();
+        });
+    });
+
+    describe('STARS', function () {
+        it('parses stars as multiplication', function () {
+            expect(parse('SELECT * FROM foo WHERE a = 1*2')).toMatchSnapshot();
+        });
+    });
+
+    describe('Parameters', function () {
+        it('parses query parameters', function () {
+            expect(parse('select * from foo where bar = $12')).toMatchSnapshot();
+        });
+    });
+
+    describe('functions', function () {
+        it('parses function with complex arguments', function () {
+            expect(parse('SELECT * FROM foo WHERE bar < DATE_SUB(NOW(), INTERVAL 14 DAYS)')).toMatchSnapshot();
+        });
+    });
+
+    describe('misc', function () {
+        it('parses case when statements', function () {
+            expect(parse('select case when foo = \'a\' then a when foo = \'b\' then b else c end from table')).toMatchSnapshot();
+        });
+
+        it('parses nested AND', function() {
+            expect(parse("select * from a where id = 1 AND (id = 2 AND type = 'foo') AND (id = 3 AND type = 'bar')")).toMatchSnapshot();
+        });
+    });
+
+});
diff --git a/test/lexer.spec.coffee b/test/lexer.spec.coffee
deleted file mode 100644
index 0769d49..0000000
--- a/test/lexer.spec.coffee
+++ /dev/null
@@ -1,65 +0,0 @@
-lexer = require('../lib/lexer')
-
-describe "SQL Lexer", ->
-  it "eats select queries", ->
-    tokens = lexer.tokenize("select * from my_table")
-    tokens.should.eql [
-      ["SELECT", "select", 1]
-      ["STAR", "*", 1]
-      ["FROM", "from", 1]
-      ["LITERAL", "my_table", 1]
-      ["EOF", "", 1]
-    ]
-
-  it "eats select queries with stars and multiplication", ->
-    tokens = lexer.tokenize("select * from my_table where foo = 1 * 2")
-    tokens.should.eql [
-      ["SELECT", "select", 1]
-      ["STAR", "*", 1]
-      ["FROM", "from", 1]
-      ["LITERAL", "my_table", 1]
-      ["WHERE", "where", 1]
-      ["LITERAL", "foo", 1]
-      ["OPERATOR", "=", 1]
-      ["NUMBER", "1", 1]
-      ["MATH_MULTI", "*", 1]
-      ["NUMBER", "2", 1]
-      ["EOF", "", 1]
-    ]
-
-
-  it "eats sub selects", ->
-    tokens = lexer.tokenize("select * from (select * from my_table) t")
-    tokens.should.eql [
-      ["SELECT", "select", 1]
-      ["STAR", "*", 1]
-      ["FROM", "from", 1]
-      [ 'LEFT_PAREN', '(', 1 ]
-      [ 'SELECT', 'select', 1 ]
-      [ 'STAR', '*', 1 ]
-      [ 'FROM', 'from', 1 ]
-      [ 'LITERAL', 'my_table', 1 ]
-      [ 'RIGHT_PAREN', ')', 1 ]
-      ["LITERAL", "t", 1]
-      ["EOF", "", 1]
-    ]
-
-  it "eats joins", ->
-    tokens = lexer.tokenize("select * from a join b on a.id = b.id")
-    tokens.should.eql [
-      ["SELECT", "select", 1]
-      ["STAR", "*", 1]
-      ["FROM", "from", 1]
-      [ 'LITERAL', 'a', 1 ]
-      [ 'JOIN', 'join', 1 ]
-      [ 'LITERAL', 'b', 1 ]
-      [ 'ON', 'on', 1 ]
-      [ 'LITERAL', 'a', 1 ]
-      [ 'DOT', '.', 1 ]
-      [ 'LITERAL', 'id', 1 ]
-      [ 'OPERATOR', '=', 1 ]
-      [ 'LITERAL', 'b', 1 ]
-      [ 'DOT', '.', 1 ]
-      [ 'LITERAL', 'id', 1 ]
-      ["EOF", "", 1]
-    ]
diff --git a/test/lexer.spec.js b/test/lexer.spec.js
new file mode 100644
index 0000000..142ac52
--- /dev/null
+++ b/test/lexer.spec.js
@@ -0,0 +1,259 @@
+const lexer = require('../src/lexer');
+
+// removes the last two params of each token (line and offset)
+function clean(tokens) {
+    return tokens.map(function (token) {
+        return token.slice(0, 2);
+    });
+}
+
+describe('SQL Lexer', function () {
+    it('eats select queries', function () {
+        const tokens = clean(lexer.tokenize('select * from my_table'));
+        expect(tokens).toEqual([
+            ['SELECT', 'select'],
+            ['STAR', '*'],
+            ['FROM', 'from'],
+            ['LITERAL', 'my_table'],
+            ['EOF', '']
+        ]);
+    });
+
+    it('eats select queries with named values', function () {
+        const tokens = clean(lexer.tokenize('select foo , bar from my_table'));
+        expect(tokens).toEqual([
+            ['SELECT', 'select'],
+            ['LITERAL', 'foo'],
+            ['SEPARATOR', ','],
+            ['LITERAL', 'bar'],
+            ['FROM', 'from'],
+            ['LITERAL', 'my_table'],
+            ['EOF', '']
+        ]);
+    });
+
+    it('eats select queries with named typed values', function () {
+        const tokens = clean(lexer.tokenize('select foo:boolean, bar:number from my_table'));
+        expect(tokens).toEqual([
+            ['SELECT', 'select'],
+            ['LITERAL', 'foo:boolean'],
+            ['SEPARATOR', ','],
+            ['LITERAL', 'bar:number'],
+            ['FROM', 'from'],
+            ['LITERAL', 'my_table'],
+            ['EOF', '']
+        ]);
+    });
+
+    it('eats select queries with with parameter', function () {
+        const tokens = clean(lexer.tokenize('select * from my_table where a = $foo'));
+        expect(tokens).toEqual([
+            ['SELECT', 'select'],
+            ['STAR', '*'],
+            ['FROM', 'from'],
+            ['LITERAL', 'my_table'],
+            ['WHERE', 'where'],
+            ['LITERAL', 'a'],
+            ['OPERATOR', '='],
+            ['PARAMETER', 'foo'],
+            ['EOF', '']
+        ]);
+    });
+
+    it('eats select queries with with parameter and type', function () {
+        const tokens = clean(lexer.tokenize('select * from my_table where a = $foo:number'));
+        expect(tokens).toEqual([
+            ['SELECT', 'select'],
+            ['STAR', '*'],
+            ['FROM', 'from'],
+            ['LITERAL', 'my_table'],
+            ['WHERE', 'where'],
+            ['LITERAL', 'a'],
+            ['OPERATOR', '='],
+            ['PARAMETER', 'foo:number'],
+            ['EOF', '']
+        ]);
+    });
+
+    it('eats select queries with stars and multiplication', function () {
+        const tokens = clean(lexer.tokenize('select * from my_table where foo = 1 * 2'));
+        expect(tokens).toEqual([
+            ['SELECT', 'select'],
+            ['STAR', '*'],
+            ['FROM', 'from'],
+            ['LITERAL', 'my_table'],
+            ['WHERE', 'where'],
+            ['LITERAL', 'foo'],
+            ['OPERATOR', '='],
+            ['NUMBER', '1'],
+            ['MATH_MULTI', '*'],
+            ['NUMBER', '2'],
+            ['EOF', '']
+        ]);
+    });
+
+    it('eats select queries with negative numbers', function () {
+        const tokens = clean(lexer.tokenize('select * from my_table where foo < -5'));
+        expect(tokens).toEqual([
+            ['SELECT', 'select'],
+            ['STAR', '*'],
+            ['FROM', 'from'],
+            ['LITERAL', 'my_table'],
+            ['WHERE', 'where'],
+            ['LITERAL', 'foo'],
+            ['OPERATOR', '<'],
+            ['NUMBER', '-5'],
+            ['EOF', '']
+        ]);
+    });
+
+    it('eats select queries with negative numbers and minus sign', function () {
+        const tokens = clean(lexer.tokenize('select * from my_table where foo < -5 - 5'));
+        expect(tokens).toEqual([
+            ['SELECT', 'select'],
+            ['STAR', '*'],
+            ['FROM', 'from'],
+            ['LITERAL', 'my_table'],
+            ['WHERE', 'where'],
+            ['LITERAL', 'foo'],
+            ['OPERATOR', '<'],
+            ['NUMBER', '-5'],
+            ['MATH', '-'],
+            ['NUMBER', '5'],
+            ['EOF', '']
+        ]);
+    });
+
+    it('eats sub selects', function () {
+        const tokens = clean(lexer.tokenize('select * from (select * from my_table) t'));
+        expect(tokens).toEqual([
+            ['SELECT', 'select'],
+            ['STAR', '*'],
+            ['FROM', 'from'],
+            ['LEFT_PAREN', '('],
+            ['SELECT', 'select'],
+            ['STAR', '*'],
+            ['FROM', 'from'],
+            ['LITERAL', 'my_table'],
+            ['RIGHT_PAREN', ')'],
+            ['LITERAL', 't'],
+            ['EOF', '']
+        ]);
+    });
+
+    it('eats joins', function () {
+        const tokens = clean(lexer.tokenize('select * from a join b on a.id = b.id'));
+        expect(tokens).toEqual([
+            ['SELECT', 'select'],
+            ['STAR', '*'],
+            ['FROM', 'from'],
+            ['LITERAL', 'a'],
+            ['JOIN', 'join'],
+            ['LITERAL', 'b'],
+            ['ON', 'on'],
+            ['LITERAL', 'a'],
+            ['DOT', '.'],
+            ['LITERAL', 'id'],
+            ['OPERATOR', '='],
+            ['LITERAL', 'b'],
+            ['DOT', '.'],
+            ['LITERAL', 'id'],
+            ['EOF', '']
+        ]);
+    });
+
+    it('eats insert queries', function () {
+        const tokens = clean(lexer.tokenize('insert into my_table values (\'a\',1)'));
+        expect(tokens).toEqual([
+            ['INSERT', 'insert'],
+            ['INTO', 'into'],
+            ['LITERAL', 'my_table'],
+            ['VALUES', 'values'],
+            ['LEFT_PAREN', '('],
+            ['STRING', 'a'],
+            ['SEPARATOR', ','],
+            ['NUMBER', '1'],
+            ['RIGHT_PAREN', ')'],
+            ['EOF', '']
+        ]);
+    });
+
+    it('eats insert queries with default values', function () {
+        const tokens = clean(lexer.tokenize('insert into my_table default values'));
+        expect(tokens).toEqual([
+            ['INSERT', 'insert'],
+            ['INTO', 'into'],
+            ['LITERAL', 'my_table'],
+            ['DEFAULT', 'default'],
+            ['VALUES', 'values'],
+            ['EOF', '']
+        ]);
+    });
+
+    it('eats insert queries with multiple rows', function () {
+        const tokens = clean(lexer.tokenize('insert into my_table values (\'a\'),(\'b\')'));
+        expect(tokens).toEqual([
+            ['INSERT', 'insert'],
+            ['INTO', 'into'],
+            ['LITERAL', 'my_table'],
+            ['VALUES', 'values'],
+            ['LEFT_PAREN', '('],
+            ['STRING', 'a'],
+            ['RIGHT_PAREN', ')'],
+            ['SEPARATOR', ','],
+            ['LEFT_PAREN', '('],
+            ['STRING', 'b'],
+            ['RIGHT_PAREN', ')'],
+            ['EOF', '']
+        ]);
+    });
+
+    it('eats insert queries with multiple rows and column names', function () {
+        const tokens = clean(lexer.tokenize('insert into my_table (foo) values (\'a\'),(\'b\')'));
+        expect(tokens).toEqual([
+            ['INSERT', 'insert'],
+            ['INTO', 'into'],
+            ['LITERAL', 'my_table'],
+            ['LEFT_PAREN', '('],
+            ['LITERAL', 'foo'],
+            ['RIGHT_PAREN', ')'],
+            ['VALUES', 'values'],
+            ['LEFT_PAREN', '('],
+            ['STRING', 'a'],
+            ['RIGHT_PAREN', ')'],
+            ['SEPARATOR', ','],
+            ['LEFT_PAREN', '('],
+            ['STRING', 'b'],
+            ['RIGHT_PAREN', ')'],
+            ['EOF', '']
+        ]);
+    });
+
+    it('eats case when', function () {
+        const tokens = clean(lexer.tokenize('select case when foo = \'a\' then a when foo = \'b\' then b else c end from table'));
+        expect(tokens).toEqual([
+            ['SELECT', 'select'],
+            ['CASE', 'case'],
+            ['WHEN', 'when'],
+            ['LITERAL', 'foo'],
+            ['OPERATOR', '='],
+            ['STRING', 'a'],
+            ['THEN', 'then'],
+            ['LITERAL', 'a'],
+            ['WHEN', 'when'],
+            ['LITERAL', 'foo'],
+            ['OPERATOR', '='],
+            ['STRING', 'b'],
+            ['THEN', 'then'],
+            ['LITERAL', 'b'],
+            ['ELSE', 'else'],
+            ['LITERAL', 'c'],
+            ['END', 'end'],
+            ['FROM', 'from'],
+            ['LITERAL', 'table'],
+            ['EOF', '']
+        ]);
+    });
+
+});
+
diff --git a/test/parser.spec.js b/test/parser.spec.js
new file mode 100644
index 0000000..a39377b
--- /dev/null
+++ b/test/parser.spec.js
@@ -0,0 +1,96 @@
+const lexer = require('../src/lexer');
+const parser = require('../src/parser');
+const nodes = require('../src/nodes');
+
+function parse(query) {
+    return parser.parse(lexer.tokenize(query));
+}
+
+describe('SQL Parser', function () {
+    it('parses simple query', function () {
+        const ast = parse('SELECT * FROM my_table');
+        expect(ast).toEqual({
+            'distinct': false,
+            'fields'  : [new nodes.Star],
+            'group'   : null,
+            'joins'   : [],
+            'limit'   : null,
+            'order'   : null,
+            'source'  : new nodes.Table(new nodes.LiteralValue('my_table'), null),
+            'unions'  : [],
+            'where'   : null
+        });
+    });
+
+    it('parses ORDER BY clauses', function () {
+        const ast = parse('SELECT * FROM my_table ORDER BY x DESC');
+        expect(ast.order).toEqual(
+            new nodes.Order([
+                new nodes.OrderArgument(new nodes.LiteralValue('x'), 'DESC')
+            ])
+        );
+    });
+
+    it('parses WHERE with function call', function () {
+        const ast = parse('SELECT * FROM my_table WHERE foo < NOW()');
+        expect(ast.where).toEqual(
+            new nodes.Where(
+                new nodes.Op('<',
+                    new nodes.LiteralValue('foo'),
+                    new nodes.FunctionValue('NOW', null, true))
+            )
+        );
+    });
+
+    it('parses basic WHERE', function () {
+        const ast = parse('SELECT * FROM my_table WHERE id >= 5 AND name LIKE \'foo\' AND ( bar IS NOT NULL OR date BETWEEN 41 AND 43 )');
+        expect(ast.where).toEqual(
+            new nodes.Where(
+                new nodes.Op('AND',
+                    new nodes.Op('AND',
+                        new nodes.Op('>=',
+                            new nodes.LiteralValue('id'),
+                            new nodes.NumberValue(5)
+                        ),
+                        new nodes.Op('LIKE',
+                            new nodes.LiteralValue('name'),
+                            new nodes.StringValue('foo', '\'')
+                        )
+                    ),
+                    new nodes.Op('OR',
+                        new nodes.Op('IS NOT',
+                            new nodes.LiteralValue('bar'),
+                            new nodes.BooleanValue('NULL')
+                        ),
+                        new nodes.Op('BETWEEN',
+                            new nodes.LiteralValue('date'),
+                            new nodes.BetweenOp([
+                                new nodes.NumberValue(41),
+                                new nodes.NumberValue(43)
+                            ])
+                        )
+                    )
+                )
+            )
+        );
+    });
+
+    it('parses function with complex arguments', function () {
+        const ast = parse('SELECT * FROM my_table WHERE foo < DATE_SUB(NOW(), INTERVAL 14 DAYS)');
+        expect(ast.where.conditions.right).toEqual(
+            new nodes.FunctionValue('DATE_SUB',
+                new nodes.ArgumentListValue([
+                    new nodes.FunctionValue('NOW', null, true),
+                    new nodes.WhitepaceList([
+                            new nodes.LiteralValue('INTERVAL'),
+                            new nodes.NumberValue(14),
+                            new nodes.LiteralValue('DAYS')
+                        ],
+                        true
+                    )
+                ]),
+                true
+            )
+        );
+    });
+});