From af07865ae2d3c11836ab5e01f17e97c3b2d5d662 Mon Sep 17 00:00:00 2001 From: Pavel Tiunov Date: Thu, 2 Apr 2020 00:03:30 -0700 Subject: [PATCH] feat: Basic query rewrites --- .../adapter/BaseQuery.js | 40 +- .../compiler/CubeValidator.js | 1 + .../cubejs-schema-compiler/generate-parser.sh | 3 + packages/cubejs-schema-compiler/package.json | 3 +- .../parser/GenericSql.g4 | 85 + .../parser/GenericSql.interp | 78 + .../parser/GenericSql.tokens | 47 + .../parser/GenericSqlLexer.interp | 98 ++ .../parser/GenericSqlLexer.js | 203 +++ .../parser/GenericSqlLexer.tokens | 47 + .../parser/GenericSqlListener.js | 132 ++ .../parser/GenericSqlParser.js | 1505 +++++++++++++++++ .../parser/SqlParser.js | 193 +++ .../test/SQLGenerationTest.js | 2 + .../test/SqlParserTest.js | 69 + packages/cubejs-schema-compiler/yarn.lock | 5 + packages/cubejs-server-core/core/index.js | 2 +- 17 files changed, 2507 insertions(+), 6 deletions(-) create mode 100755 packages/cubejs-schema-compiler/generate-parser.sh create mode 100644 packages/cubejs-schema-compiler/parser/GenericSql.g4 create mode 100644 packages/cubejs-schema-compiler/parser/GenericSql.interp create mode 100644 packages/cubejs-schema-compiler/parser/GenericSql.tokens create mode 100644 packages/cubejs-schema-compiler/parser/GenericSqlLexer.interp create mode 100644 packages/cubejs-schema-compiler/parser/GenericSqlLexer.js create mode 100644 packages/cubejs-schema-compiler/parser/GenericSqlLexer.tokens create mode 100644 packages/cubejs-schema-compiler/parser/GenericSqlListener.js create mode 100644 packages/cubejs-schema-compiler/parser/GenericSqlParser.js create mode 100644 packages/cubejs-schema-compiler/parser/SqlParser.js create mode 100644 packages/cubejs-schema-compiler/test/SqlParserTest.js diff --git a/packages/cubejs-schema-compiler/adapter/BaseQuery.js b/packages/cubejs-schema-compiler/adapter/BaseQuery.js index 91ba7a671ea5e..1b8c84c3927d5 100644 --- a/packages/cubejs-schema-compiler/adapter/BaseQuery.js +++ b/packages/cubejs-schema-compiler/adapter/BaseQuery.js @@ -11,6 +11,7 @@ const BaseFilter = require('./BaseFilter'); const BaseTimeDimension = require('./BaseTimeDimension'); const ParamAllocator = require('./ParamAllocator'); const PreAggregations = require('./PreAggregations'); +const SqlParser = require('../parser/SqlParser'); const DEFAULT_PREAGGREGATIONS_SCHEMA = `stb_pre_aggregations`; @@ -335,7 +336,10 @@ class BaseQuery { simpleQuery() { // eslint-disable-next-line prefer-template - return `${this.commonQuery()} ${this.baseWhere(this.allFilters)}` + + const inlineWhereConditions = []; + const commonQuery = this.rewriteInlineWhere(() => this.commonQuery(), inlineWhereConditions); + const inlineFilters = inlineWhereConditions.map(f => ({ filterToWhere: () => f })); + return `${commonQuery} ${this.baseWhere(this.allFilters.concat(inlineFilters))}` + this.groupByClause() + this.baseHaving(this.measureFilters) + this.orderBy() + @@ -619,13 +623,33 @@ class BaseQuery { return this.joinQuery(this.join, this.collectFromMembers(false, this.collectSubQueryDimensionsFor.bind(this))); } + rewriteInlineCubeSql(cube) { + const sql = this.cubeSql(cube); + const parser = new SqlParser(sql); + const cubeAlias = this.cubeAlias(cube); + if ( + this.safeEvaluateSymbolContext().inlineWhereConditions && + this.cubeEvaluator.cubeFromPath(cube).rewriteQueries && + parser.isSimpleAsteriskQuery() + ) { + this.safeEvaluateSymbolContext().inlineWhereConditions.push(parser.extractWhereConditions(cubeAlias)); + return [parser.extractTableFrom(), cubeAlias]; + } else { + return [sql, cubeAlias]; + } + } + joinQuery(join, subQueryDimensions) { const joins = join.joins.map( - j => `LEFT JOIN ${this.cubeSql(j.originalTo)} ${this.asSyntaxJoin} ${this.cubeAlias(j.originalTo)} - ON ${this.evaluateSql(j.originalFrom, j.join.sql)}` + j => { + const [cubeSql, cubeAlias] = this.rewriteInlineCubeSql(j.originalTo); + return `LEFT JOIN ${cubeSql} ${this.asSyntaxJoin} ${cubeAlias} + ON ${this.evaluateSql(j.originalFrom, j.join.sql)}`; + } ).concat(subQueryDimensions.map(d => this.subQueryJoin(d))); - return `${this.cubeSql(join.root)} ${this.asSyntaxJoin} ${this.cubeAlias(join.root)}\n${joins.join("\n")}`; + const [cubeSql, cubeAlias] = this.rewriteInlineCubeSql(join.root); + return `${cubeSql} ${this.asSyntaxJoin} ${cubeAlias}\n${joins.join("\n")}`; } subQueryJoin(dimension) { @@ -877,6 +901,14 @@ class BaseQuery { return R.uniq(context.subQueryDimensions); } + rewriteInlineWhere(fn, inlineWhereConditions) { + const context = { inlineWhereConditions }; + return this.evaluateSymbolSqlWithContext( + fn, + context + ); + } + groupByClause() { if (this.ungrouped) { return ''; diff --git a/packages/cubejs-schema-compiler/compiler/CubeValidator.js b/packages/cubejs-schema-compiler/compiler/CubeValidator.js index 6417ec03b1755..2207cb5bbbc6f 100644 --- a/packages/cubejs-schema-compiler/compiler/CubeValidator.js +++ b/packages/cubejs-schema-compiler/compiler/CubeValidator.js @@ -107,6 +107,7 @@ const cubeSchema = Joi.object().keys({ sqlAlias: Joi.string(), dataSource: Joi.string(), description: Joi.string(), + rewriteQueries: Joi.boolean(), joins: Joi.object().pattern(identifierRegex, Joi.object().keys({ sql: Joi.func().required(), relationship: Joi.any().valid('hasMany', 'belongsTo', 'hasOne').required() diff --git a/packages/cubejs-schema-compiler/generate-parser.sh b/packages/cubejs-schema-compiler/generate-parser.sh new file mode 100755 index 0000000000000..7299b7a43cb82 --- /dev/null +++ b/packages/cubejs-schema-compiler/generate-parser.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +cd parser && antlr -Dlanguage=JavaScript GenericSql.g4 \ No newline at end of file diff --git a/packages/cubejs-schema-compiler/package.json b/packages/cubejs-schema-compiler/package.json index 1b8c381b2fb17..8127c468ecc51 100644 --- a/packages/cubejs-schema-compiler/package.json +++ b/packages/cubejs-schema-compiler/package.json @@ -13,7 +13,7 @@ }, "scripts": { "test": "mocha", - "lint": "eslint adapter/*.js compiler/*.js extensions/*.js scaffolding/*.js" + "lint": "eslint adapter/*.js compiler/*.js extensions/*.js scaffolding/*.js parser/SqlParser.js" }, "dependencies": { "@babel/generator": "^7.4.0", @@ -23,6 +23,7 @@ "@babel/traverse": "^7.4.0", "@babel/types": "^7.4.0", "@hapi/joi": "^15.1.1", + "antlr4": "^4.8.0", "humps": "^2.0.1", "inflection": "^1.12.0", "moment-range": "^4.0.1", diff --git a/packages/cubejs-schema-compiler/parser/GenericSql.g4 b/packages/cubejs-schema-compiler/parser/GenericSql.g4 new file mode 100644 index 0000000000000..345f0eaeec4ab --- /dev/null +++ b/packages/cubejs-schema-compiler/parser/GenericSql.g4 @@ -0,0 +1,85 @@ +grammar GenericSql; + +statement: + query EOF | '(' query ')' EOF; + +query: + SELECT selectFields + FROM from=fromTables + (WHERE where=boolExp)?; + +fromTables: + aliasField; + +selectFields: + (field (',' field)*); + +field: + aliasField | ASTERISK; + +aliasField: + idPath (AS? identifier)?; + +boolExp: + exp | + exp AND exp | + exp OR exp | + NOT exp + ; + +exp: + exp binaryOperator exp | + exp unaryOperator | + idPath | + identifier '(' (exp (',' exp)*) ')' | + CAST '(' exp AS identifier ')' | + STRING | + numeric | + identifier | + INDEXED_PARAM | + '(' exp ')' + ; + +numeric: + DIGIT+ ('.' DIGIT+)? | + '.' DIGIT+; + +binaryOperator: + LT | LTE | GT | GTE | EQUALS | NOT_EQUALS; + +unaryOperator: + IS NULL | IS NOT NULL; + +idPath: + identifier ('.' identifier)*; + +identifier: + ID | + QUOTED_ID; + +SELECT: 'SELECT'; +ASTERISK: '*'; +FROM: 'FROM'; +WHERE: 'WHERE'; +AND: 'AND'; +OR: 'OR'; +NOT: 'NOT'; +AS: 'AS'; +LT: '<'; +LTE: '<='; +GT: '>'; +GTE: '>='; +EQUALS: '='; +NOT_EQUALS: '<>' | '!='; +IS: 'IS'; +NULL: 'NULL'; +CAST: 'CAST'; + +INDEXED_PARAM: '$' [0-9]+ '$'; +ID: [A-Z_@] [A-Z_@0-9]*; +DIGIT: [0-9]; +QUOTED_ID: ('"' (~'"')* '"') | ('`' (~'`')* '`'); +STRING: ('\'' (~ '\'' | '\'\'')* '\''); + + +WHITESPACE: [ \t\r\n] -> channel(HIDDEN); diff --git a/packages/cubejs-schema-compiler/parser/GenericSql.interp b/packages/cubejs-schema-compiler/parser/GenericSql.interp new file mode 100644 index 0000000000000..95ee8ab67826f --- /dev/null +++ b/packages/cubejs-schema-compiler/parser/GenericSql.interp @@ -0,0 +1,78 @@ +token literal names: +null +'(' +')' +',' +'.' +'SELECT' +'*' +'FROM' +'WHERE' +'AND' +'OR' +'NOT' +'AS' +'<' +'<=' +'>' +'>=' +'=' +null +'IS' +'NULL' +'CAST' +null +null +null +null +null +null + +token symbolic names: +null +null +null +null +null +SELECT +ASTERISK +FROM +WHERE +AND +OR +NOT +AS +LT +LTE +GT +GTE +EQUALS +NOT_EQUALS +IS +NULL +CAST +INDEXED_PARAM +ID +DIGIT +QUOTED_ID +STRING +WHITESPACE + +rule names: +statement +query +fromTables +selectFields +field +aliasField +boolExp +exp +numeric +binaryOperator +unaryOperator +idPath +identifier + + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 29, 163, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 5, 2, 37, 10, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 45, 10, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 7, 5, 52, 10, 5, 12, 5, 14, 5, 55, 11, 5, 3, 6, 3, 6, 5, 6, 59, 10, 6, 3, 7, 3, 7, 5, 7, 63, 10, 7, 3, 7, 5, 7, 66, 10, 7, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 5, 8, 79, 10, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 7, 9, 88, 10, 9, 12, 9, 14, 9, 91, 11, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 5, 9, 110, 10, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 7, 9, 118, 10, 9, 12, 9, 14, 9, 121, 11, 9, 3, 10, 6, 10, 124, 10, 10, 13, 10, 14, 10, 125, 3, 10, 3, 10, 6, 10, 130, 10, 10, 13, 10, 14, 10, 131, 5, 10, 134, 10, 10, 3, 10, 3, 10, 6, 10, 138, 10, 10, 13, 10, 14, 10, 139, 5, 10, 142, 10, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 5, 12, 151, 10, 12, 3, 13, 3, 13, 3, 13, 7, 13, 156, 10, 13, 12, 13, 14, 13, 159, 11, 13, 3, 14, 3, 14, 3, 14, 2, 3, 16, 15, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 2, 4, 3, 2, 15, 20, 4, 2, 25, 25, 27, 27, 2, 175, 2, 36, 3, 2, 2, 2, 4, 38, 3, 2, 2, 2, 6, 46, 3, 2, 2, 2, 8, 48, 3, 2, 2, 2, 10, 58, 3, 2, 2, 2, 12, 60, 3, 2, 2, 2, 14, 78, 3, 2, 2, 2, 16, 109, 3, 2, 2, 2, 18, 141, 3, 2, 2, 2, 20, 143, 3, 2, 2, 2, 22, 150, 3, 2, 2, 2, 24, 152, 3, 2, 2, 2, 26, 160, 3, 2, 2, 2, 28, 29, 5, 4, 3, 2, 29, 30, 7, 2, 2, 3, 30, 37, 3, 2, 2, 2, 31, 32, 7, 3, 2, 2, 32, 33, 5, 4, 3, 2, 33, 34, 7, 4, 2, 2, 34, 35, 7, 2, 2, 3, 35, 37, 3, 2, 2, 2, 36, 28, 3, 2, 2, 2, 36, 31, 3, 2, 2, 2, 37, 3, 3, 2, 2, 2, 38, 39, 7, 7, 2, 2, 39, 40, 5, 8, 5, 2, 40, 41, 7, 9, 2, 2, 41, 44, 5, 6, 4, 2, 42, 43, 7, 10, 2, 2, 43, 45, 5, 14, 8, 2, 44, 42, 3, 2, 2, 2, 44, 45, 3, 2, 2, 2, 45, 5, 3, 2, 2, 2, 46, 47, 5, 12, 7, 2, 47, 7, 3, 2, 2, 2, 48, 53, 5, 10, 6, 2, 49, 50, 7, 5, 2, 2, 50, 52, 5, 10, 6, 2, 51, 49, 3, 2, 2, 2, 52, 55, 3, 2, 2, 2, 53, 51, 3, 2, 2, 2, 53, 54, 3, 2, 2, 2, 54, 9, 3, 2, 2, 2, 55, 53, 3, 2, 2, 2, 56, 59, 5, 12, 7, 2, 57, 59, 7, 8, 2, 2, 58, 56, 3, 2, 2, 2, 58, 57, 3, 2, 2, 2, 59, 11, 3, 2, 2, 2, 60, 65, 5, 24, 13, 2, 61, 63, 7, 14, 2, 2, 62, 61, 3, 2, 2, 2, 62, 63, 3, 2, 2, 2, 63, 64, 3, 2, 2, 2, 64, 66, 5, 26, 14, 2, 65, 62, 3, 2, 2, 2, 65, 66, 3, 2, 2, 2, 66, 13, 3, 2, 2, 2, 67, 79, 5, 16, 9, 2, 68, 69, 5, 16, 9, 2, 69, 70, 7, 11, 2, 2, 70, 71, 5, 16, 9, 2, 71, 79, 3, 2, 2, 2, 72, 73, 5, 16, 9, 2, 73, 74, 7, 12, 2, 2, 74, 75, 5, 16, 9, 2, 75, 79, 3, 2, 2, 2, 76, 77, 7, 13, 2, 2, 77, 79, 5, 16, 9, 2, 78, 67, 3, 2, 2, 2, 78, 68, 3, 2, 2, 2, 78, 72, 3, 2, 2, 2, 78, 76, 3, 2, 2, 2, 79, 15, 3, 2, 2, 2, 80, 81, 8, 9, 1, 2, 81, 110, 5, 24, 13, 2, 82, 83, 5, 26, 14, 2, 83, 84, 7, 3, 2, 2, 84, 89, 5, 16, 9, 2, 85, 86, 7, 5, 2, 2, 86, 88, 5, 16, 9, 2, 87, 85, 3, 2, 2, 2, 88, 91, 3, 2, 2, 2, 89, 87, 3, 2, 2, 2, 89, 90, 3, 2, 2, 2, 90, 92, 3, 2, 2, 2, 91, 89, 3, 2, 2, 2, 92, 93, 7, 4, 2, 2, 93, 110, 3, 2, 2, 2, 94, 95, 7, 23, 2, 2, 95, 96, 7, 3, 2, 2, 96, 97, 5, 16, 9, 2, 97, 98, 7, 14, 2, 2, 98, 99, 5, 26, 14, 2, 99, 100, 7, 4, 2, 2, 100, 110, 3, 2, 2, 2, 101, 110, 7, 28, 2, 2, 102, 110, 5, 18, 10, 2, 103, 110, 5, 26, 14, 2, 104, 110, 7, 24, 2, 2, 105, 106, 7, 3, 2, 2, 106, 107, 5, 16, 9, 2, 107, 108, 7, 4, 2, 2, 108, 110, 3, 2, 2, 2, 109, 80, 3, 2, 2, 2, 109, 82, 3, 2, 2, 2, 109, 94, 3, 2, 2, 2, 109, 101, 3, 2, 2, 2, 109, 102, 3, 2, 2, 2, 109, 103, 3, 2, 2, 2, 109, 104, 3, 2, 2, 2, 109, 105, 3, 2, 2, 2, 110, 119, 3, 2, 2, 2, 111, 112, 12, 12, 2, 2, 112, 113, 5, 20, 11, 2, 113, 114, 5, 16, 9, 13, 114, 118, 3, 2, 2, 2, 115, 116, 12, 11, 2, 2, 116, 118, 5, 22, 12, 2, 117, 111, 3, 2, 2, 2, 117, 115, 3, 2, 2, 2, 118, 121, 3, 2, 2, 2, 119, 117, 3, 2, 2, 2, 119, 120, 3, 2, 2, 2, 120, 17, 3, 2, 2, 2, 121, 119, 3, 2, 2, 2, 122, 124, 7, 26, 2, 2, 123, 122, 3, 2, 2, 2, 124, 125, 3, 2, 2, 2, 125, 123, 3, 2, 2, 2, 125, 126, 3, 2, 2, 2, 126, 133, 3, 2, 2, 2, 127, 129, 7, 6, 2, 2, 128, 130, 7, 26, 2, 2, 129, 128, 3, 2, 2, 2, 130, 131, 3, 2, 2, 2, 131, 129, 3, 2, 2, 2, 131, 132, 3, 2, 2, 2, 132, 134, 3, 2, 2, 2, 133, 127, 3, 2, 2, 2, 133, 134, 3, 2, 2, 2, 134, 142, 3, 2, 2, 2, 135, 137, 7, 6, 2, 2, 136, 138, 7, 26, 2, 2, 137, 136, 3, 2, 2, 2, 138, 139, 3, 2, 2, 2, 139, 137, 3, 2, 2, 2, 139, 140, 3, 2, 2, 2, 140, 142, 3, 2, 2, 2, 141, 123, 3, 2, 2, 2, 141, 135, 3, 2, 2, 2, 142, 19, 3, 2, 2, 2, 143, 144, 9, 2, 2, 2, 144, 21, 3, 2, 2, 2, 145, 146, 7, 21, 2, 2, 146, 151, 7, 22, 2, 2, 147, 148, 7, 21, 2, 2, 148, 149, 7, 13, 2, 2, 149, 151, 7, 22, 2, 2, 150, 145, 3, 2, 2, 2, 150, 147, 3, 2, 2, 2, 151, 23, 3, 2, 2, 2, 152, 157, 5, 26, 14, 2, 153, 154, 7, 6, 2, 2, 154, 156, 5, 26, 14, 2, 155, 153, 3, 2, 2, 2, 156, 159, 3, 2, 2, 2, 157, 155, 3, 2, 2, 2, 157, 158, 3, 2, 2, 2, 158, 25, 3, 2, 2, 2, 159, 157, 3, 2, 2, 2, 160, 161, 9, 3, 2, 2, 161, 27, 3, 2, 2, 2, 20, 36, 44, 53, 58, 62, 65, 78, 89, 109, 117, 119, 125, 131, 133, 139, 141, 150, 157] \ No newline at end of file diff --git a/packages/cubejs-schema-compiler/parser/GenericSql.tokens b/packages/cubejs-schema-compiler/parser/GenericSql.tokens new file mode 100644 index 0000000000000..e9c75014b7298 --- /dev/null +++ b/packages/cubejs-schema-compiler/parser/GenericSql.tokens @@ -0,0 +1,47 @@ +T__0=1 +T__1=2 +T__2=3 +T__3=4 +SELECT=5 +ASTERISK=6 +FROM=7 +WHERE=8 +AND=9 +OR=10 +NOT=11 +AS=12 +LT=13 +LTE=14 +GT=15 +GTE=16 +EQUALS=17 +NOT_EQUALS=18 +IS=19 +NULL=20 +CAST=21 +INDEXED_PARAM=22 +ID=23 +DIGIT=24 +QUOTED_ID=25 +STRING=26 +WHITESPACE=27 +'('=1 +')'=2 +','=3 +'.'=4 +'SELECT'=5 +'*'=6 +'FROM'=7 +'WHERE'=8 +'AND'=9 +'OR'=10 +'NOT'=11 +'AS'=12 +'<'=13 +'<='=14 +'>'=15 +'>='=16 +'='=17 +'IS'=19 +'NULL'=20 +'CAST'=21 diff --git a/packages/cubejs-schema-compiler/parser/GenericSqlLexer.interp b/packages/cubejs-schema-compiler/parser/GenericSqlLexer.interp new file mode 100644 index 0000000000000..d2448b884be1a --- /dev/null +++ b/packages/cubejs-schema-compiler/parser/GenericSqlLexer.interp @@ -0,0 +1,98 @@ +token literal names: +null +'(' +')' +',' +'.' +'SELECT' +'*' +'FROM' +'WHERE' +'AND' +'OR' +'NOT' +'AS' +'<' +'<=' +'>' +'>=' +'=' +null +'IS' +'NULL' +'CAST' +null +null +null +null +null +null + +token symbolic names: +null +null +null +null +null +SELECT +ASTERISK +FROM +WHERE +AND +OR +NOT +AS +LT +LTE +GT +GTE +EQUALS +NOT_EQUALS +IS +NULL +CAST +INDEXED_PARAM +ID +DIGIT +QUOTED_ID +STRING +WHITESPACE + +rule names: +T__0 +T__1 +T__2 +T__3 +SELECT +ASTERISK +FROM +WHERE +AND +OR +NOT +AS +LT +LTE +GT +GTE +EQUALS +NOT_EQUALS +IS +NULL +CAST +INDEXED_PARAM +ID +DIGIT +QUOTED_ID +STRING +WHITESPACE + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN + +mode names: +DEFAULT_MODE + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 29, 180, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 19, 3, 19, 5, 19, 116, 10, 19, 3, 20, 3, 20, 3, 20, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 3, 23, 3, 23, 6, 23, 133, 10, 23, 13, 23, 14, 23, 134, 3, 23, 3, 23, 3, 24, 3, 24, 7, 24, 141, 10, 24, 12, 24, 14, 24, 144, 11, 24, 3, 25, 3, 25, 3, 26, 3, 26, 7, 26, 150, 10, 26, 12, 26, 14, 26, 153, 11, 26, 3, 26, 3, 26, 3, 26, 7, 26, 158, 10, 26, 12, 26, 14, 26, 161, 11, 26, 3, 26, 5, 26, 164, 10, 26, 3, 27, 3, 27, 3, 27, 3, 27, 7, 27, 170, 10, 27, 12, 27, 14, 27, 173, 11, 27, 3, 27, 3, 27, 3, 28, 3, 28, 3, 28, 3, 28, 2, 2, 29, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 31, 17, 33, 18, 35, 19, 37, 20, 39, 21, 41, 22, 43, 23, 45, 24, 47, 25, 49, 26, 51, 27, 53, 28, 55, 29, 3, 2, 9, 3, 2, 50, 59, 4, 2, 66, 92, 97, 97, 5, 2, 50, 59, 66, 92, 97, 97, 3, 2, 36, 36, 3, 2, 98, 98, 3, 2, 41, 41, 5, 2, 11, 12, 15, 15, 34, 34, 2, 187, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, 2, 41, 3, 2, 2, 2, 2, 43, 3, 2, 2, 2, 2, 45, 3, 2, 2, 2, 2, 47, 3, 2, 2, 2, 2, 49, 3, 2, 2, 2, 2, 51, 3, 2, 2, 2, 2, 53, 3, 2, 2, 2, 2, 55, 3, 2, 2, 2, 3, 57, 3, 2, 2, 2, 5, 59, 3, 2, 2, 2, 7, 61, 3, 2, 2, 2, 9, 63, 3, 2, 2, 2, 11, 65, 3, 2, 2, 2, 13, 72, 3, 2, 2, 2, 15, 74, 3, 2, 2, 2, 17, 79, 3, 2, 2, 2, 19, 85, 3, 2, 2, 2, 21, 89, 3, 2, 2, 2, 23, 92, 3, 2, 2, 2, 25, 96, 3, 2, 2, 2, 27, 99, 3, 2, 2, 2, 29, 101, 3, 2, 2, 2, 31, 104, 3, 2, 2, 2, 33, 106, 3, 2, 2, 2, 35, 109, 3, 2, 2, 2, 37, 115, 3, 2, 2, 2, 39, 117, 3, 2, 2, 2, 41, 120, 3, 2, 2, 2, 43, 125, 3, 2, 2, 2, 45, 130, 3, 2, 2, 2, 47, 138, 3, 2, 2, 2, 49, 145, 3, 2, 2, 2, 51, 163, 3, 2, 2, 2, 53, 165, 3, 2, 2, 2, 55, 176, 3, 2, 2, 2, 57, 58, 7, 42, 2, 2, 58, 4, 3, 2, 2, 2, 59, 60, 7, 43, 2, 2, 60, 6, 3, 2, 2, 2, 61, 62, 7, 46, 2, 2, 62, 8, 3, 2, 2, 2, 63, 64, 7, 48, 2, 2, 64, 10, 3, 2, 2, 2, 65, 66, 7, 85, 2, 2, 66, 67, 7, 71, 2, 2, 67, 68, 7, 78, 2, 2, 68, 69, 7, 71, 2, 2, 69, 70, 7, 69, 2, 2, 70, 71, 7, 86, 2, 2, 71, 12, 3, 2, 2, 2, 72, 73, 7, 44, 2, 2, 73, 14, 3, 2, 2, 2, 74, 75, 7, 72, 2, 2, 75, 76, 7, 84, 2, 2, 76, 77, 7, 81, 2, 2, 77, 78, 7, 79, 2, 2, 78, 16, 3, 2, 2, 2, 79, 80, 7, 89, 2, 2, 80, 81, 7, 74, 2, 2, 81, 82, 7, 71, 2, 2, 82, 83, 7, 84, 2, 2, 83, 84, 7, 71, 2, 2, 84, 18, 3, 2, 2, 2, 85, 86, 7, 67, 2, 2, 86, 87, 7, 80, 2, 2, 87, 88, 7, 70, 2, 2, 88, 20, 3, 2, 2, 2, 89, 90, 7, 81, 2, 2, 90, 91, 7, 84, 2, 2, 91, 22, 3, 2, 2, 2, 92, 93, 7, 80, 2, 2, 93, 94, 7, 81, 2, 2, 94, 95, 7, 86, 2, 2, 95, 24, 3, 2, 2, 2, 96, 97, 7, 67, 2, 2, 97, 98, 7, 85, 2, 2, 98, 26, 3, 2, 2, 2, 99, 100, 7, 62, 2, 2, 100, 28, 3, 2, 2, 2, 101, 102, 7, 62, 2, 2, 102, 103, 7, 63, 2, 2, 103, 30, 3, 2, 2, 2, 104, 105, 7, 64, 2, 2, 105, 32, 3, 2, 2, 2, 106, 107, 7, 64, 2, 2, 107, 108, 7, 63, 2, 2, 108, 34, 3, 2, 2, 2, 109, 110, 7, 63, 2, 2, 110, 36, 3, 2, 2, 2, 111, 112, 7, 62, 2, 2, 112, 116, 7, 64, 2, 2, 113, 114, 7, 35, 2, 2, 114, 116, 7, 63, 2, 2, 115, 111, 3, 2, 2, 2, 115, 113, 3, 2, 2, 2, 116, 38, 3, 2, 2, 2, 117, 118, 7, 75, 2, 2, 118, 119, 7, 85, 2, 2, 119, 40, 3, 2, 2, 2, 120, 121, 7, 80, 2, 2, 121, 122, 7, 87, 2, 2, 122, 123, 7, 78, 2, 2, 123, 124, 7, 78, 2, 2, 124, 42, 3, 2, 2, 2, 125, 126, 7, 69, 2, 2, 126, 127, 7, 67, 2, 2, 127, 128, 7, 85, 2, 2, 128, 129, 7, 86, 2, 2, 129, 44, 3, 2, 2, 2, 130, 132, 7, 38, 2, 2, 131, 133, 9, 2, 2, 2, 132, 131, 3, 2, 2, 2, 133, 134, 3, 2, 2, 2, 134, 132, 3, 2, 2, 2, 134, 135, 3, 2, 2, 2, 135, 136, 3, 2, 2, 2, 136, 137, 7, 38, 2, 2, 137, 46, 3, 2, 2, 2, 138, 142, 9, 3, 2, 2, 139, 141, 9, 4, 2, 2, 140, 139, 3, 2, 2, 2, 141, 144, 3, 2, 2, 2, 142, 140, 3, 2, 2, 2, 142, 143, 3, 2, 2, 2, 143, 48, 3, 2, 2, 2, 144, 142, 3, 2, 2, 2, 145, 146, 9, 2, 2, 2, 146, 50, 3, 2, 2, 2, 147, 151, 7, 36, 2, 2, 148, 150, 10, 5, 2, 2, 149, 148, 3, 2, 2, 2, 150, 153, 3, 2, 2, 2, 151, 149, 3, 2, 2, 2, 151, 152, 3, 2, 2, 2, 152, 154, 3, 2, 2, 2, 153, 151, 3, 2, 2, 2, 154, 164, 7, 36, 2, 2, 155, 159, 7, 98, 2, 2, 156, 158, 10, 6, 2, 2, 157, 156, 3, 2, 2, 2, 158, 161, 3, 2, 2, 2, 159, 157, 3, 2, 2, 2, 159, 160, 3, 2, 2, 2, 160, 162, 3, 2, 2, 2, 161, 159, 3, 2, 2, 2, 162, 164, 7, 98, 2, 2, 163, 147, 3, 2, 2, 2, 163, 155, 3, 2, 2, 2, 164, 52, 3, 2, 2, 2, 165, 171, 7, 41, 2, 2, 166, 170, 10, 7, 2, 2, 167, 168, 7, 41, 2, 2, 168, 170, 7, 41, 2, 2, 169, 166, 3, 2, 2, 2, 169, 167, 3, 2, 2, 2, 170, 173, 3, 2, 2, 2, 171, 169, 3, 2, 2, 2, 171, 172, 3, 2, 2, 2, 172, 174, 3, 2, 2, 2, 173, 171, 3, 2, 2, 2, 174, 175, 7, 41, 2, 2, 175, 54, 3, 2, 2, 2, 176, 177, 9, 8, 2, 2, 177, 178, 3, 2, 2, 2, 178, 179, 8, 28, 2, 2, 179, 56, 3, 2, 2, 2, 11, 2, 115, 134, 142, 151, 159, 163, 169, 171, 3, 2, 3, 2] \ No newline at end of file diff --git a/packages/cubejs-schema-compiler/parser/GenericSqlLexer.js b/packages/cubejs-schema-compiler/parser/GenericSqlLexer.js new file mode 100644 index 0000000000000..4fd35bf64ff15 --- /dev/null +++ b/packages/cubejs-schema-compiler/parser/GenericSqlLexer.js @@ -0,0 +1,203 @@ +// Generated from GenericSql.g4 by ANTLR 4.8 +// jshint ignore: start +var antlr4 = require('antlr4/index'); + + + +var serializedATN = ["\u0003\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964", + "\u0002\u001d\u00b4\b\u0001\u0004\u0002\t\u0002\u0004\u0003\t\u0003\u0004", + "\u0004\t\u0004\u0004\u0005\t\u0005\u0004\u0006\t\u0006\u0004\u0007\t", + "\u0007\u0004\b\t\b\u0004\t\t\t\u0004\n\t\n\u0004\u000b\t\u000b\u0004", + "\f\t\f\u0004\r\t\r\u0004\u000e\t\u000e\u0004\u000f\t\u000f\u0004\u0010", + "\t\u0010\u0004\u0011\t\u0011\u0004\u0012\t\u0012\u0004\u0013\t\u0013", + "\u0004\u0014\t\u0014\u0004\u0015\t\u0015\u0004\u0016\t\u0016\u0004\u0017", + "\t\u0017\u0004\u0018\t\u0018\u0004\u0019\t\u0019\u0004\u001a\t\u001a", + "\u0004\u001b\t\u001b\u0004\u001c\t\u001c\u0003\u0002\u0003\u0002\u0003", + "\u0003\u0003\u0003\u0003\u0004\u0003\u0004\u0003\u0005\u0003\u0005\u0003", + "\u0006\u0003\u0006\u0003\u0006\u0003\u0006\u0003\u0006\u0003\u0006\u0003", + "\u0006\u0003\u0007\u0003\u0007\u0003\b\u0003\b\u0003\b\u0003\b\u0003", + "\b\u0003\t\u0003\t\u0003\t\u0003\t\u0003\t\u0003\t\u0003\n\u0003\n\u0003", + "\n\u0003\n\u0003\u000b\u0003\u000b\u0003\u000b\u0003\f\u0003\f\u0003", + "\f\u0003\f\u0003\r\u0003\r\u0003\r\u0003\u000e\u0003\u000e\u0003\u000f", + "\u0003\u000f\u0003\u000f\u0003\u0010\u0003\u0010\u0003\u0011\u0003\u0011", + "\u0003\u0011\u0003\u0012\u0003\u0012\u0003\u0013\u0003\u0013\u0003\u0013", + "\u0003\u0013\u0005\u0013t\n\u0013\u0003\u0014\u0003\u0014\u0003\u0014", + "\u0003\u0015\u0003\u0015\u0003\u0015\u0003\u0015\u0003\u0015\u0003\u0016", + "\u0003\u0016\u0003\u0016\u0003\u0016\u0003\u0016\u0003\u0017\u0003\u0017", + "\u0006\u0017\u0085\n\u0017\r\u0017\u000e\u0017\u0086\u0003\u0017\u0003", + "\u0017\u0003\u0018\u0003\u0018\u0007\u0018\u008d\n\u0018\f\u0018\u000e", + "\u0018\u0090\u000b\u0018\u0003\u0019\u0003\u0019\u0003\u001a\u0003\u001a", + "\u0007\u001a\u0096\n\u001a\f\u001a\u000e\u001a\u0099\u000b\u001a\u0003", + "\u001a\u0003\u001a\u0003\u001a\u0007\u001a\u009e\n\u001a\f\u001a\u000e", + "\u001a\u00a1\u000b\u001a\u0003\u001a\u0005\u001a\u00a4\n\u001a\u0003", + "\u001b\u0003\u001b\u0003\u001b\u0003\u001b\u0007\u001b\u00aa\n\u001b", + "\f\u001b\u000e\u001b\u00ad\u000b\u001b\u0003\u001b\u0003\u001b\u0003", + "\u001c\u0003\u001c\u0003\u001c\u0003\u001c\u0002\u0002\u001d\u0003\u0003", + "\u0005\u0004\u0007\u0005\t\u0006\u000b\u0007\r\b\u000f\t\u0011\n\u0013", + "\u000b\u0015\f\u0017\r\u0019\u000e\u001b\u000f\u001d\u0010\u001f\u0011", + "!\u0012#\u0013%\u0014\'\u0015)\u0016+\u0017-\u0018/\u00191\u001a3\u001b", + "5\u001c7\u001d\u0003\u0002\t\u0003\u00022;\u0004\u0002B\\aa\u0005\u0002", + "2;B\\aa\u0003\u0002$$\u0003\u0002bb\u0003\u0002))\u0005\u0002\u000b", + "\f\u000f\u000f\"\"\u0002\u00bb\u0002\u0003\u0003\u0002\u0002\u0002\u0002", + "\u0005\u0003\u0002\u0002\u0002\u0002\u0007\u0003\u0002\u0002\u0002\u0002", + "\t\u0003\u0002\u0002\u0002\u0002\u000b\u0003\u0002\u0002\u0002\u0002", + "\r\u0003\u0002\u0002\u0002\u0002\u000f\u0003\u0002\u0002\u0002\u0002", + "\u0011\u0003\u0002\u0002\u0002\u0002\u0013\u0003\u0002\u0002\u0002\u0002", + "\u0015\u0003\u0002\u0002\u0002\u0002\u0017\u0003\u0002\u0002\u0002\u0002", + "\u0019\u0003\u0002\u0002\u0002\u0002\u001b\u0003\u0002\u0002\u0002\u0002", + "\u001d\u0003\u0002\u0002\u0002\u0002\u001f\u0003\u0002\u0002\u0002\u0002", + "!\u0003\u0002\u0002\u0002\u0002#\u0003\u0002\u0002\u0002\u0002%\u0003", + "\u0002\u0002\u0002\u0002\'\u0003\u0002\u0002\u0002\u0002)\u0003\u0002", + "\u0002\u0002\u0002+\u0003\u0002\u0002\u0002\u0002-\u0003\u0002\u0002", + "\u0002\u0002/\u0003\u0002\u0002\u0002\u00021\u0003\u0002\u0002\u0002", + "\u00023\u0003\u0002\u0002\u0002\u00025\u0003\u0002\u0002\u0002\u0002", + "7\u0003\u0002\u0002\u0002\u00039\u0003\u0002\u0002\u0002\u0005;\u0003", + "\u0002\u0002\u0002\u0007=\u0003\u0002\u0002\u0002\t?\u0003\u0002\u0002", + "\u0002\u000bA\u0003\u0002\u0002\u0002\rH\u0003\u0002\u0002\u0002\u000f", + "J\u0003\u0002\u0002\u0002\u0011O\u0003\u0002\u0002\u0002\u0013U\u0003", + "\u0002\u0002\u0002\u0015Y\u0003\u0002\u0002\u0002\u0017\\\u0003\u0002", + "\u0002\u0002\u0019`\u0003\u0002\u0002\u0002\u001bc\u0003\u0002\u0002", + "\u0002\u001de\u0003\u0002\u0002\u0002\u001fh\u0003\u0002\u0002\u0002", + "!j\u0003\u0002\u0002\u0002#m\u0003\u0002\u0002\u0002%s\u0003\u0002\u0002", + "\u0002\'u\u0003\u0002\u0002\u0002)x\u0003\u0002\u0002\u0002+}\u0003", + "\u0002\u0002\u0002-\u0082\u0003\u0002\u0002\u0002/\u008a\u0003\u0002", + "\u0002\u00021\u0091\u0003\u0002\u0002\u00023\u00a3\u0003\u0002\u0002", + "\u00025\u00a5\u0003\u0002\u0002\u00027\u00b0\u0003\u0002\u0002\u0002", + "9:\u0007*\u0002\u0002:\u0004\u0003\u0002\u0002\u0002;<\u0007+\u0002", + "\u0002<\u0006\u0003\u0002\u0002\u0002=>\u0007.\u0002\u0002>\b\u0003", + "\u0002\u0002\u0002?@\u00070\u0002\u0002@\n\u0003\u0002\u0002\u0002A", + "B\u0007U\u0002\u0002BC\u0007G\u0002\u0002CD\u0007N\u0002\u0002DE\u0007", + "G\u0002\u0002EF\u0007E\u0002\u0002FG\u0007V\u0002\u0002G\f\u0003\u0002", + "\u0002\u0002HI\u0007,\u0002\u0002I\u000e\u0003\u0002\u0002\u0002JK\u0007", + "H\u0002\u0002KL\u0007T\u0002\u0002LM\u0007Q\u0002\u0002MN\u0007O\u0002", + "\u0002N\u0010\u0003\u0002\u0002\u0002OP\u0007Y\u0002\u0002PQ\u0007J", + "\u0002\u0002QR\u0007G\u0002\u0002RS\u0007T\u0002\u0002ST\u0007G\u0002", + "\u0002T\u0012\u0003\u0002\u0002\u0002UV\u0007C\u0002\u0002VW\u0007P", + "\u0002\u0002WX\u0007F\u0002\u0002X\u0014\u0003\u0002\u0002\u0002YZ\u0007", + "Q\u0002\u0002Z[\u0007T\u0002\u0002[\u0016\u0003\u0002\u0002\u0002\\", + "]\u0007P\u0002\u0002]^\u0007Q\u0002\u0002^_\u0007V\u0002\u0002_\u0018", + "\u0003\u0002\u0002\u0002`a\u0007C\u0002\u0002ab\u0007U\u0002\u0002b", + "\u001a\u0003\u0002\u0002\u0002cd\u0007>\u0002\u0002d\u001c\u0003\u0002", + "\u0002\u0002ef\u0007>\u0002\u0002fg\u0007?\u0002\u0002g\u001e\u0003", + "\u0002\u0002\u0002hi\u0007@\u0002\u0002i \u0003\u0002\u0002\u0002jk", + "\u0007@\u0002\u0002kl\u0007?\u0002\u0002l\"\u0003\u0002\u0002\u0002", + "mn\u0007?\u0002\u0002n$\u0003\u0002\u0002\u0002op\u0007>\u0002\u0002", + "pt\u0007@\u0002\u0002qr\u0007#\u0002\u0002rt\u0007?\u0002\u0002so\u0003", + "\u0002\u0002\u0002sq\u0003\u0002\u0002\u0002t&\u0003\u0002\u0002\u0002", + "uv\u0007K\u0002\u0002vw\u0007U\u0002\u0002w(\u0003\u0002\u0002\u0002", + "xy\u0007P\u0002\u0002yz\u0007W\u0002\u0002z{\u0007N\u0002\u0002{|\u0007", + "N\u0002\u0002|*\u0003\u0002\u0002\u0002}~\u0007E\u0002\u0002~\u007f", + "\u0007C\u0002\u0002\u007f\u0080\u0007U\u0002\u0002\u0080\u0081\u0007", + "V\u0002\u0002\u0081,\u0003\u0002\u0002\u0002\u0082\u0084\u0007&\u0002", + "\u0002\u0083\u0085\t\u0002\u0002\u0002\u0084\u0083\u0003\u0002\u0002", + "\u0002\u0085\u0086\u0003\u0002\u0002\u0002\u0086\u0084\u0003\u0002\u0002", + "\u0002\u0086\u0087\u0003\u0002\u0002\u0002\u0087\u0088\u0003\u0002\u0002", + "\u0002\u0088\u0089\u0007&\u0002\u0002\u0089.\u0003\u0002\u0002\u0002", + "\u008a\u008e\t\u0003\u0002\u0002\u008b\u008d\t\u0004\u0002\u0002\u008c", + "\u008b\u0003\u0002\u0002\u0002\u008d\u0090\u0003\u0002\u0002\u0002\u008e", + "\u008c\u0003\u0002\u0002\u0002\u008e\u008f\u0003\u0002\u0002\u0002\u008f", + "0\u0003\u0002\u0002\u0002\u0090\u008e\u0003\u0002\u0002\u0002\u0091", + "\u0092\t\u0002\u0002\u0002\u00922\u0003\u0002\u0002\u0002\u0093\u0097", + "\u0007$\u0002\u0002\u0094\u0096\n\u0005\u0002\u0002\u0095\u0094\u0003", + "\u0002\u0002\u0002\u0096\u0099\u0003\u0002\u0002\u0002\u0097\u0095\u0003", + "\u0002\u0002\u0002\u0097\u0098\u0003\u0002\u0002\u0002\u0098\u009a\u0003", + "\u0002\u0002\u0002\u0099\u0097\u0003\u0002\u0002\u0002\u009a\u00a4\u0007", + "$\u0002\u0002\u009b\u009f\u0007b\u0002\u0002\u009c\u009e\n\u0006\u0002", + "\u0002\u009d\u009c\u0003\u0002\u0002\u0002\u009e\u00a1\u0003\u0002\u0002", + "\u0002\u009f\u009d\u0003\u0002\u0002\u0002\u009f\u00a0\u0003\u0002\u0002", + "\u0002\u00a0\u00a2\u0003\u0002\u0002\u0002\u00a1\u009f\u0003\u0002\u0002", + "\u0002\u00a2\u00a4\u0007b\u0002\u0002\u00a3\u0093\u0003\u0002\u0002", + "\u0002\u00a3\u009b\u0003\u0002\u0002\u0002\u00a44\u0003\u0002\u0002", + "\u0002\u00a5\u00ab\u0007)\u0002\u0002\u00a6\u00aa\n\u0007\u0002\u0002", + "\u00a7\u00a8\u0007)\u0002\u0002\u00a8\u00aa\u0007)\u0002\u0002\u00a9", + "\u00a6\u0003\u0002\u0002\u0002\u00a9\u00a7\u0003\u0002\u0002\u0002\u00aa", + "\u00ad\u0003\u0002\u0002\u0002\u00ab\u00a9\u0003\u0002\u0002\u0002\u00ab", + "\u00ac\u0003\u0002\u0002\u0002\u00ac\u00ae\u0003\u0002\u0002\u0002\u00ad", + "\u00ab\u0003\u0002\u0002\u0002\u00ae\u00af\u0007)\u0002\u0002\u00af", + "6\u0003\u0002\u0002\u0002\u00b0\u00b1\t\b\u0002\u0002\u00b1\u00b2\u0003", + "\u0002\u0002\u0002\u00b2\u00b3\b\u001c\u0002\u0002\u00b38\u0003\u0002", + "\u0002\u0002\u000b\u0002s\u0086\u008e\u0097\u009f\u00a3\u00a9\u00ab", + "\u0003\u0002\u0003\u0002"].join(""); + + +var atn = new antlr4.atn.ATNDeserializer().deserialize(serializedATN); + +var decisionsToDFA = atn.decisionToState.map( function(ds, index) { return new antlr4.dfa.DFA(ds, index); }); + +function GenericSqlLexer(input) { + antlr4.Lexer.call(this, input); + this._interp = new antlr4.atn.LexerATNSimulator(this, atn, decisionsToDFA, new antlr4.PredictionContextCache()); + return this; +} + +GenericSqlLexer.prototype = Object.create(antlr4.Lexer.prototype); +GenericSqlLexer.prototype.constructor = GenericSqlLexer; + +Object.defineProperty(GenericSqlLexer.prototype, "atn", { + get : function() { + return atn; + } +}); + +GenericSqlLexer.EOF = antlr4.Token.EOF; +GenericSqlLexer.T__0 = 1; +GenericSqlLexer.T__1 = 2; +GenericSqlLexer.T__2 = 3; +GenericSqlLexer.T__3 = 4; +GenericSqlLexer.SELECT = 5; +GenericSqlLexer.ASTERISK = 6; +GenericSqlLexer.FROM = 7; +GenericSqlLexer.WHERE = 8; +GenericSqlLexer.AND = 9; +GenericSqlLexer.OR = 10; +GenericSqlLexer.NOT = 11; +GenericSqlLexer.AS = 12; +GenericSqlLexer.LT = 13; +GenericSqlLexer.LTE = 14; +GenericSqlLexer.GT = 15; +GenericSqlLexer.GTE = 16; +GenericSqlLexer.EQUALS = 17; +GenericSqlLexer.NOT_EQUALS = 18; +GenericSqlLexer.IS = 19; +GenericSqlLexer.NULL = 20; +GenericSqlLexer.CAST = 21; +GenericSqlLexer.INDEXED_PARAM = 22; +GenericSqlLexer.ID = 23; +GenericSqlLexer.DIGIT = 24; +GenericSqlLexer.QUOTED_ID = 25; +GenericSqlLexer.STRING = 26; +GenericSqlLexer.WHITESPACE = 27; + +GenericSqlLexer.prototype.channelNames = [ "DEFAULT_TOKEN_CHANNEL", "HIDDEN" ]; + +GenericSqlLexer.prototype.modeNames = [ "DEFAULT_MODE" ]; + +GenericSqlLexer.prototype.literalNames = [ null, "'('", "')'", "','", "'.'", + "'SELECT'", "'*'", "'FROM'", + "'WHERE'", "'AND'", "'OR'", "'NOT'", + "'AS'", "'<'", "'<='", "'>'", + "'>='", "'='", null, "'IS'", + "'NULL'", "'CAST'" ]; + +GenericSqlLexer.prototype.symbolicNames = [ null, null, null, null, null, + "SELECT", "ASTERISK", "FROM", + "WHERE", "AND", "OR", "NOT", + "AS", "LT", "LTE", "GT", "GTE", + "EQUALS", "NOT_EQUALS", "IS", + "NULL", "CAST", "INDEXED_PARAM", + "ID", "DIGIT", "QUOTED_ID", + "STRING", "WHITESPACE" ]; + +GenericSqlLexer.prototype.ruleNames = [ "T__0", "T__1", "T__2", "T__3", + "SELECT", "ASTERISK", "FROM", "WHERE", + "AND", "OR", "NOT", "AS", "LT", + "LTE", "GT", "GTE", "EQUALS", "NOT_EQUALS", + "IS", "NULL", "CAST", "INDEXED_PARAM", + "ID", "DIGIT", "QUOTED_ID", "STRING", + "WHITESPACE" ]; + +GenericSqlLexer.prototype.grammarFileName = "GenericSql.g4"; + + +exports.GenericSqlLexer = GenericSqlLexer; + diff --git a/packages/cubejs-schema-compiler/parser/GenericSqlLexer.tokens b/packages/cubejs-schema-compiler/parser/GenericSqlLexer.tokens new file mode 100644 index 0000000000000..e9c75014b7298 --- /dev/null +++ b/packages/cubejs-schema-compiler/parser/GenericSqlLexer.tokens @@ -0,0 +1,47 @@ +T__0=1 +T__1=2 +T__2=3 +T__3=4 +SELECT=5 +ASTERISK=6 +FROM=7 +WHERE=8 +AND=9 +OR=10 +NOT=11 +AS=12 +LT=13 +LTE=14 +GT=15 +GTE=16 +EQUALS=17 +NOT_EQUALS=18 +IS=19 +NULL=20 +CAST=21 +INDEXED_PARAM=22 +ID=23 +DIGIT=24 +QUOTED_ID=25 +STRING=26 +WHITESPACE=27 +'('=1 +')'=2 +','=3 +'.'=4 +'SELECT'=5 +'*'=6 +'FROM'=7 +'WHERE'=8 +'AND'=9 +'OR'=10 +'NOT'=11 +'AS'=12 +'<'=13 +'<='=14 +'>'=15 +'>='=16 +'='=17 +'IS'=19 +'NULL'=20 +'CAST'=21 diff --git a/packages/cubejs-schema-compiler/parser/GenericSqlListener.js b/packages/cubejs-schema-compiler/parser/GenericSqlListener.js new file mode 100644 index 0000000000000..da32bead5f955 --- /dev/null +++ b/packages/cubejs-schema-compiler/parser/GenericSqlListener.js @@ -0,0 +1,132 @@ +// Generated from GenericSql.g4 by ANTLR 4.8 +// jshint ignore: start +var antlr4 = require('antlr4/index'); + +// This class defines a complete listener for a parse tree produced by GenericSqlParser. +function GenericSqlListener() { + antlr4.tree.ParseTreeListener.call(this); + return this; +} + +GenericSqlListener.prototype = Object.create(antlr4.tree.ParseTreeListener.prototype); +GenericSqlListener.prototype.constructor = GenericSqlListener; + +// Enter a parse tree produced by GenericSqlParser#statement. +GenericSqlListener.prototype.enterStatement = function(ctx) { +}; + +// Exit a parse tree produced by GenericSqlParser#statement. +GenericSqlListener.prototype.exitStatement = function(ctx) { +}; + + +// Enter a parse tree produced by GenericSqlParser#query. +GenericSqlListener.prototype.enterQuery = function(ctx) { +}; + +// Exit a parse tree produced by GenericSqlParser#query. +GenericSqlListener.prototype.exitQuery = function(ctx) { +}; + + +// Enter a parse tree produced by GenericSqlParser#fromTables. +GenericSqlListener.prototype.enterFromTables = function(ctx) { +}; + +// Exit a parse tree produced by GenericSqlParser#fromTables. +GenericSqlListener.prototype.exitFromTables = function(ctx) { +}; + + +// Enter a parse tree produced by GenericSqlParser#selectFields. +GenericSqlListener.prototype.enterSelectFields = function(ctx) { +}; + +// Exit a parse tree produced by GenericSqlParser#selectFields. +GenericSqlListener.prototype.exitSelectFields = function(ctx) { +}; + + +// Enter a parse tree produced by GenericSqlParser#field. +GenericSqlListener.prototype.enterField = function(ctx) { +}; + +// Exit a parse tree produced by GenericSqlParser#field. +GenericSqlListener.prototype.exitField = function(ctx) { +}; + + +// Enter a parse tree produced by GenericSqlParser#aliasField. +GenericSqlListener.prototype.enterAliasField = function(ctx) { +}; + +// Exit a parse tree produced by GenericSqlParser#aliasField. +GenericSqlListener.prototype.exitAliasField = function(ctx) { +}; + + +// Enter a parse tree produced by GenericSqlParser#boolExp. +GenericSqlListener.prototype.enterBoolExp = function(ctx) { +}; + +// Exit a parse tree produced by GenericSqlParser#boolExp. +GenericSqlListener.prototype.exitBoolExp = function(ctx) { +}; + + +// Enter a parse tree produced by GenericSqlParser#exp. +GenericSqlListener.prototype.enterExp = function(ctx) { +}; + +// Exit a parse tree produced by GenericSqlParser#exp. +GenericSqlListener.prototype.exitExp = function(ctx) { +}; + + +// Enter a parse tree produced by GenericSqlParser#numeric. +GenericSqlListener.prototype.enterNumeric = function(ctx) { +}; + +// Exit a parse tree produced by GenericSqlParser#numeric. +GenericSqlListener.prototype.exitNumeric = function(ctx) { +}; + + +// Enter a parse tree produced by GenericSqlParser#binaryOperator. +GenericSqlListener.prototype.enterBinaryOperator = function(ctx) { +}; + +// Exit a parse tree produced by GenericSqlParser#binaryOperator. +GenericSqlListener.prototype.exitBinaryOperator = function(ctx) { +}; + + +// Enter a parse tree produced by GenericSqlParser#unaryOperator. +GenericSqlListener.prototype.enterUnaryOperator = function(ctx) { +}; + +// Exit a parse tree produced by GenericSqlParser#unaryOperator. +GenericSqlListener.prototype.exitUnaryOperator = function(ctx) { +}; + + +// Enter a parse tree produced by GenericSqlParser#idPath. +GenericSqlListener.prototype.enterIdPath = function(ctx) { +}; + +// Exit a parse tree produced by GenericSqlParser#idPath. +GenericSqlListener.prototype.exitIdPath = function(ctx) { +}; + + +// Enter a parse tree produced by GenericSqlParser#identifier. +GenericSqlListener.prototype.enterIdentifier = function(ctx) { +}; + +// Exit a parse tree produced by GenericSqlParser#identifier. +GenericSqlListener.prototype.exitIdentifier = function(ctx) { +}; + + + +exports.GenericSqlListener = GenericSqlListener; \ No newline at end of file diff --git a/packages/cubejs-schema-compiler/parser/GenericSqlParser.js b/packages/cubejs-schema-compiler/parser/GenericSqlParser.js new file mode 100644 index 0000000000000..d9f0d4673178c --- /dev/null +++ b/packages/cubejs-schema-compiler/parser/GenericSqlParser.js @@ -0,0 +1,1505 @@ +// Generated from GenericSql.g4 by ANTLR 4.8 +// jshint ignore: start +var antlr4 = require('antlr4/index'); +var GenericSqlListener = require('./GenericSqlListener').GenericSqlListener; +var grammarFileName = "GenericSql.g4"; + + +var serializedATN = ["\u0003\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964", + "\u0003\u001d\u00a3\u0004\u0002\t\u0002\u0004\u0003\t\u0003\u0004\u0004", + "\t\u0004\u0004\u0005\t\u0005\u0004\u0006\t\u0006\u0004\u0007\t\u0007", + "\u0004\b\t\b\u0004\t\t\t\u0004\n\t\n\u0004\u000b\t\u000b\u0004\f\t\f", + "\u0004\r\t\r\u0004\u000e\t\u000e\u0003\u0002\u0003\u0002\u0003\u0002", + "\u0003\u0002\u0003\u0002\u0003\u0002\u0003\u0002\u0003\u0002\u0005\u0002", + "%\n\u0002\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003", + "\u0003\u0003\u0005\u0003-\n\u0003\u0003\u0004\u0003\u0004\u0003\u0005", + "\u0003\u0005\u0003\u0005\u0007\u00054\n\u0005\f\u0005\u000e\u00057\u000b", + "\u0005\u0003\u0006\u0003\u0006\u0005\u0006;\n\u0006\u0003\u0007\u0003", + "\u0007\u0005\u0007?\n\u0007\u0003\u0007\u0005\u0007B\n\u0007\u0003\b", + "\u0003\b\u0003\b\u0003\b\u0003\b\u0003\b\u0003\b\u0003\b\u0003\b\u0003", + "\b\u0003\b\u0005\bO\n\b\u0003\t\u0003\t\u0003\t\u0003\t\u0003\t\u0003", + "\t\u0003\t\u0007\tX\n\t\f\t\u000e\t[\u000b\t\u0003\t\u0003\t\u0003\t", + "\u0003\t\u0003\t\u0003\t\u0003\t\u0003\t\u0003\t\u0003\t\u0003\t\u0003", + "\t\u0003\t\u0003\t\u0003\t\u0003\t\u0003\t\u0005\tn\n\t\u0003\t\u0003", + "\t\u0003\t\u0003\t\u0003\t\u0003\t\u0007\tv\n\t\f\t\u000e\ty\u000b\t", + "\u0003\n\u0006\n|\n\n\r\n\u000e\n}\u0003\n\u0003\n\u0006\n\u0082\n\n", + "\r\n\u000e\n\u0083\u0005\n\u0086\n\n\u0003\n\u0003\n\u0006\n\u008a\n", + "\n\r\n\u000e\n\u008b\u0005\n\u008e\n\n\u0003\u000b\u0003\u000b\u0003", + "\f\u0003\f\u0003\f\u0003\f\u0003\f\u0005\f\u0097\n\f\u0003\r\u0003\r", + "\u0003\r\u0007\r\u009c\n\r\f\r\u000e\r\u009f\u000b\r\u0003\u000e\u0003", + "\u000e\u0003\u000e\u0002\u0003\u0010\u000f\u0002\u0004\u0006\b\n\f\u000e", + "\u0010\u0012\u0014\u0016\u0018\u001a\u0002\u0004\u0003\u0002\u000f\u0014", + "\u0004\u0002\u0019\u0019\u001b\u001b\u0002\u00af\u0002$\u0003\u0002", + "\u0002\u0002\u0004&\u0003\u0002\u0002\u0002\u0006.\u0003\u0002\u0002", + "\u0002\b0\u0003\u0002\u0002\u0002\n:\u0003\u0002\u0002\u0002\f<\u0003", + "\u0002\u0002\u0002\u000eN\u0003\u0002\u0002\u0002\u0010m\u0003\u0002", + "\u0002\u0002\u0012\u008d\u0003\u0002\u0002\u0002\u0014\u008f\u0003\u0002", + "\u0002\u0002\u0016\u0096\u0003\u0002\u0002\u0002\u0018\u0098\u0003\u0002", + "\u0002\u0002\u001a\u00a0\u0003\u0002\u0002\u0002\u001c\u001d\u0005\u0004", + "\u0003\u0002\u001d\u001e\u0007\u0002\u0002\u0003\u001e%\u0003\u0002", + "\u0002\u0002\u001f \u0007\u0003\u0002\u0002 !\u0005\u0004\u0003\u0002", + "!\"\u0007\u0004\u0002\u0002\"#\u0007\u0002\u0002\u0003#%\u0003\u0002", + "\u0002\u0002$\u001c\u0003\u0002\u0002\u0002$\u001f\u0003\u0002\u0002", + "\u0002%\u0003\u0003\u0002\u0002\u0002&\'\u0007\u0007\u0002\u0002\'(", + "\u0005\b\u0005\u0002()\u0007\t\u0002\u0002),\u0005\u0006\u0004\u0002", + "*+\u0007\n\u0002\u0002+-\u0005\u000e\b\u0002,*\u0003\u0002\u0002\u0002", + ",-\u0003\u0002\u0002\u0002-\u0005\u0003\u0002\u0002\u0002./\u0005\f", + "\u0007\u0002/\u0007\u0003\u0002\u0002\u000205\u0005\n\u0006\u000212", + "\u0007\u0005\u0002\u000224\u0005\n\u0006\u000231\u0003\u0002\u0002\u0002", + "47\u0003\u0002\u0002\u000253\u0003\u0002\u0002\u000256\u0003\u0002\u0002", + "\u00026\t\u0003\u0002\u0002\u000275\u0003\u0002\u0002\u00028;\u0005", + "\f\u0007\u00029;\u0007\b\u0002\u0002:8\u0003\u0002\u0002\u0002:9\u0003", + "\u0002\u0002\u0002;\u000b\u0003\u0002\u0002\u0002=\u0003\u0002\u0002\u0002>?\u0003\u0002\u0002", + "\u0002?@\u0003\u0002\u0002\u0002@B\u0005\u001a\u000e\u0002A>\u0003\u0002", + "\u0002\u0002AB\u0003\u0002\u0002\u0002B\r\u0003\u0002\u0002\u0002CO", + "\u0005\u0010\t\u0002DE\u0005\u0010\t\u0002EF\u0007\u000b\u0002\u0002", + "FG\u0005\u0010\t\u0002GO\u0003\u0002\u0002\u0002HI\u0005\u0010\t\u0002", + "IJ\u0007\f\u0002\u0002JK\u0005\u0010\t\u0002KO\u0003\u0002\u0002\u0002", + "LM\u0007\r\u0002\u0002MO\u0005\u0010\t\u0002NC\u0003\u0002\u0002\u0002", + "ND\u0003\u0002\u0002\u0002NH\u0003\u0002\u0002\u0002NL\u0003\u0002\u0002", + "\u0002O\u000f\u0003\u0002\u0002\u0002PQ\b\t\u0001\u0002Qn\u0005\u0018", + "\r\u0002RS\u0005\u001a\u000e\u0002ST\u0007\u0003\u0002\u0002TY\u0005", + "\u0010\t\u0002UV\u0007\u0005\u0002\u0002VX\u0005\u0010\t\u0002WU\u0003", + "\u0002\u0002\u0002X[\u0003\u0002\u0002\u0002YW\u0003\u0002\u0002\u0002", + "YZ\u0003\u0002\u0002\u0002Z\\\u0003\u0002\u0002\u0002[Y\u0003\u0002", + "\u0002\u0002\\]\u0007\u0004\u0002\u0002]n\u0003\u0002\u0002\u0002^_", + "\u0007\u0017\u0002\u0002_`\u0007\u0003\u0002\u0002`a\u0005\u0010\t\u0002", + "ab\u0007\u000e\u0002\u0002bc\u0005\u001a\u000e\u0002cd\u0007\u0004\u0002", + "\u0002dn\u0003\u0002\u0002\u0002en\u0007\u001c\u0002\u0002fn\u0005\u0012", + "\n\u0002gn\u0005\u001a\u000e\u0002hn\u0007\u0018\u0002\u0002ij\u0007", + "\u0003\u0002\u0002jk\u0005\u0010\t\u0002kl\u0007\u0004\u0002\u0002l", + "n\u0003\u0002\u0002\u0002mP\u0003\u0002\u0002\u0002mR\u0003\u0002\u0002", + "\u0002m^\u0003\u0002\u0002\u0002me\u0003\u0002\u0002\u0002mf\u0003\u0002", + "\u0002\u0002mg\u0003\u0002\u0002\u0002mh\u0003\u0002\u0002\u0002mi\u0003", + "\u0002\u0002\u0002nw\u0003\u0002\u0002\u0002op\f\f\u0002\u0002pq\u0005", + "\u0014\u000b\u0002qr\u0005\u0010\t\rrv\u0003\u0002\u0002\u0002st\f\u000b", + "\u0002\u0002tv\u0005\u0016\f\u0002uo\u0003\u0002\u0002\u0002us\u0003", + "\u0002\u0002\u0002vy\u0003\u0002\u0002\u0002wu\u0003\u0002\u0002\u0002", + "wx\u0003\u0002\u0002\u0002x\u0011\u0003\u0002\u0002\u0002yw\u0003\u0002", + "\u0002\u0002z|\u0007\u001a\u0002\u0002{z\u0003\u0002\u0002\u0002|}\u0003", + "\u0002\u0002\u0002}{\u0003\u0002\u0002\u0002}~\u0003\u0002\u0002\u0002", + "~\u0085\u0003\u0002\u0002\u0002\u007f\u0081\u0007\u0006\u0002\u0002", + "\u0080\u0082\u0007\u001a\u0002\u0002\u0081\u0080\u0003\u0002\u0002\u0002", + "\u0082\u0083\u0003\u0002\u0002\u0002\u0083\u0081\u0003\u0002\u0002\u0002", + "\u0083\u0084\u0003\u0002\u0002\u0002\u0084\u0086\u0003\u0002\u0002\u0002", + "\u0085\u007f\u0003\u0002\u0002\u0002\u0085\u0086\u0003\u0002\u0002\u0002", + "\u0086\u008e\u0003\u0002\u0002\u0002\u0087\u0089\u0007\u0006\u0002\u0002", + "\u0088\u008a\u0007\u001a\u0002\u0002\u0089\u0088\u0003\u0002\u0002\u0002", + "\u008a\u008b\u0003\u0002\u0002\u0002\u008b\u0089\u0003\u0002\u0002\u0002", + "\u008b\u008c\u0003\u0002\u0002\u0002\u008c\u008e\u0003\u0002\u0002\u0002", + "\u008d{\u0003\u0002\u0002\u0002\u008d\u0087\u0003\u0002\u0002\u0002", + "\u008e\u0013\u0003\u0002\u0002\u0002\u008f\u0090\t\u0002\u0002\u0002", + "\u0090\u0015\u0003\u0002\u0002\u0002\u0091\u0092\u0007\u0015\u0002\u0002", + "\u0092\u0097\u0007\u0016\u0002\u0002\u0093\u0094\u0007\u0015\u0002\u0002", + "\u0094\u0095\u0007\r\u0002\u0002\u0095\u0097\u0007\u0016\u0002\u0002", + "\u0096\u0091\u0003\u0002\u0002\u0002\u0096\u0093\u0003\u0002\u0002\u0002", + "\u0097\u0017\u0003\u0002\u0002\u0002\u0098\u009d\u0005\u001a\u000e\u0002", + "\u0099\u009a\u0007\u0006\u0002\u0002\u009a\u009c\u0005\u001a\u000e\u0002", + "\u009b\u0099\u0003\u0002\u0002\u0002\u009c\u009f\u0003\u0002\u0002\u0002", + "\u009d\u009b\u0003\u0002\u0002\u0002\u009d\u009e\u0003\u0002\u0002\u0002", + "\u009e\u0019\u0003\u0002\u0002\u0002\u009f\u009d\u0003\u0002\u0002\u0002", + "\u00a0\u00a1\t\u0003\u0002\u0002\u00a1\u001b\u0003\u0002\u0002\u0002", + "\u0014$,5:>ANYmuw}\u0083\u0085\u008b\u008d\u0096\u009d"].join(""); + + +var atn = new antlr4.atn.ATNDeserializer().deserialize(serializedATN); + +var decisionsToDFA = atn.decisionToState.map( function(ds, index) { return new antlr4.dfa.DFA(ds, index); }); + +var sharedContextCache = new antlr4.PredictionContextCache(); + +var literalNames = [ null, "'('", "')'", "','", "'.'", "'SELECT'", "'*'", + "'FROM'", "'WHERE'", "'AND'", "'OR'", "'NOT'", "'AS'", + "'<'", "'<='", "'>'", "'>='", "'='", null, "'IS'", + "'NULL'", "'CAST'" ]; + +var symbolicNames = [ null, null, null, null, null, "SELECT", "ASTERISK", + "FROM", "WHERE", "AND", "OR", "NOT", "AS", "LT", "LTE", + "GT", "GTE", "EQUALS", "NOT_EQUALS", "IS", "NULL", + "CAST", "INDEXED_PARAM", "ID", "DIGIT", "QUOTED_ID", + "STRING", "WHITESPACE" ]; + +var ruleNames = [ "statement", "query", "fromTables", "selectFields", "field", + "aliasField", "boolExp", "exp", "numeric", "binaryOperator", + "unaryOperator", "idPath", "identifier" ]; + +function GenericSqlParser (input) { + antlr4.Parser.call(this, input); + this._interp = new antlr4.atn.ParserATNSimulator(this, atn, decisionsToDFA, sharedContextCache); + this.ruleNames = ruleNames; + this.literalNames = literalNames; + this.symbolicNames = symbolicNames; + return this; +} + +GenericSqlParser.prototype = Object.create(antlr4.Parser.prototype); +GenericSqlParser.prototype.constructor = GenericSqlParser; + +Object.defineProperty(GenericSqlParser.prototype, "atn", { + get : function() { + return atn; + } +}); + +GenericSqlParser.EOF = antlr4.Token.EOF; +GenericSqlParser.T__0 = 1; +GenericSqlParser.T__1 = 2; +GenericSqlParser.T__2 = 3; +GenericSqlParser.T__3 = 4; +GenericSqlParser.SELECT = 5; +GenericSqlParser.ASTERISK = 6; +GenericSqlParser.FROM = 7; +GenericSqlParser.WHERE = 8; +GenericSqlParser.AND = 9; +GenericSqlParser.OR = 10; +GenericSqlParser.NOT = 11; +GenericSqlParser.AS = 12; +GenericSqlParser.LT = 13; +GenericSqlParser.LTE = 14; +GenericSqlParser.GT = 15; +GenericSqlParser.GTE = 16; +GenericSqlParser.EQUALS = 17; +GenericSqlParser.NOT_EQUALS = 18; +GenericSqlParser.IS = 19; +GenericSqlParser.NULL = 20; +GenericSqlParser.CAST = 21; +GenericSqlParser.INDEXED_PARAM = 22; +GenericSqlParser.ID = 23; +GenericSqlParser.DIGIT = 24; +GenericSqlParser.QUOTED_ID = 25; +GenericSqlParser.STRING = 26; +GenericSqlParser.WHITESPACE = 27; + +GenericSqlParser.RULE_statement = 0; +GenericSqlParser.RULE_query = 1; +GenericSqlParser.RULE_fromTables = 2; +GenericSqlParser.RULE_selectFields = 3; +GenericSqlParser.RULE_field = 4; +GenericSqlParser.RULE_aliasField = 5; +GenericSqlParser.RULE_boolExp = 6; +GenericSqlParser.RULE_exp = 7; +GenericSqlParser.RULE_numeric = 8; +GenericSqlParser.RULE_binaryOperator = 9; +GenericSqlParser.RULE_unaryOperator = 10; +GenericSqlParser.RULE_idPath = 11; +GenericSqlParser.RULE_identifier = 12; + + +function StatementContext(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + antlr4.ParserRuleContext.call(this, parent, invokingState); + this.parser = parser; + this.ruleIndex = GenericSqlParser.RULE_statement; + return this; +} + +StatementContext.prototype = Object.create(antlr4.ParserRuleContext.prototype); +StatementContext.prototype.constructor = StatementContext; + +StatementContext.prototype.query = function() { + return this.getTypedRuleContext(QueryContext,0); +}; + +StatementContext.prototype.EOF = function() { + return this.getToken(GenericSqlParser.EOF, 0); +}; + +StatementContext.prototype.enterRule = function(listener) { + if(listener instanceof GenericSqlListener ) { + listener.enterStatement(this); + } +}; + +StatementContext.prototype.exitRule = function(listener) { + if(listener instanceof GenericSqlListener ) { + listener.exitStatement(this); + } +}; + + + + +GenericSqlParser.StatementContext = StatementContext; + +GenericSqlParser.prototype.statement = function() { + + var localctx = new StatementContext(this, this._ctx, this.state); + this.enterRule(localctx, 0, GenericSqlParser.RULE_statement); + try { + this.state = 34; + this._errHandler.sync(this); + switch(this._input.LA(1)) { + case GenericSqlParser.SELECT: + this.enterOuterAlt(localctx, 1); + this.state = 26; + this.query(); + this.state = 27; + this.match(GenericSqlParser.EOF); + break; + case GenericSqlParser.T__0: + this.enterOuterAlt(localctx, 2); + this.state = 29; + this.match(GenericSqlParser.T__0); + this.state = 30; + this.query(); + this.state = 31; + this.match(GenericSqlParser.T__1); + this.state = 32; + this.match(GenericSqlParser.EOF); + break; + default: + throw new antlr4.error.NoViableAltException(this); + } + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; +}; + + +function QueryContext(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + antlr4.ParserRuleContext.call(this, parent, invokingState); + this.parser = parser; + this.ruleIndex = GenericSqlParser.RULE_query; + this.from = null; // FromTablesContext + this.where = null; // BoolExpContext + return this; +} + +QueryContext.prototype = Object.create(antlr4.ParserRuleContext.prototype); +QueryContext.prototype.constructor = QueryContext; + +QueryContext.prototype.SELECT = function() { + return this.getToken(GenericSqlParser.SELECT, 0); +}; + +QueryContext.prototype.selectFields = function() { + return this.getTypedRuleContext(SelectFieldsContext,0); +}; + +QueryContext.prototype.FROM = function() { + return this.getToken(GenericSqlParser.FROM, 0); +}; + +QueryContext.prototype.fromTables = function() { + return this.getTypedRuleContext(FromTablesContext,0); +}; + +QueryContext.prototype.WHERE = function() { + return this.getToken(GenericSqlParser.WHERE, 0); +}; + +QueryContext.prototype.boolExp = function() { + return this.getTypedRuleContext(BoolExpContext,0); +}; + +QueryContext.prototype.enterRule = function(listener) { + if(listener instanceof GenericSqlListener ) { + listener.enterQuery(this); + } +}; + +QueryContext.prototype.exitRule = function(listener) { + if(listener instanceof GenericSqlListener ) { + listener.exitQuery(this); + } +}; + + + + +GenericSqlParser.QueryContext = QueryContext; + +GenericSqlParser.prototype.query = function() { + + var localctx = new QueryContext(this, this._ctx, this.state); + this.enterRule(localctx, 2, GenericSqlParser.RULE_query); + var _la = 0; // Token type + try { + this.enterOuterAlt(localctx, 1); + this.state = 36; + this.match(GenericSqlParser.SELECT); + this.state = 37; + this.selectFields(); + this.state = 38; + this.match(GenericSqlParser.FROM); + this.state = 39; + localctx.from = this.fromTables(); + this.state = 42; + this._errHandler.sync(this); + _la = this._input.LA(1); + if(_la===GenericSqlParser.WHERE) { + this.state = 40; + this.match(GenericSqlParser.WHERE); + this.state = 41; + localctx.where = this.boolExp(); + } + + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; +}; + + +function FromTablesContext(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + antlr4.ParserRuleContext.call(this, parent, invokingState); + this.parser = parser; + this.ruleIndex = GenericSqlParser.RULE_fromTables; + return this; +} + +FromTablesContext.prototype = Object.create(antlr4.ParserRuleContext.prototype); +FromTablesContext.prototype.constructor = FromTablesContext; + +FromTablesContext.prototype.aliasField = function() { + return this.getTypedRuleContext(AliasFieldContext,0); +}; + +FromTablesContext.prototype.enterRule = function(listener) { + if(listener instanceof GenericSqlListener ) { + listener.enterFromTables(this); + } +}; + +FromTablesContext.prototype.exitRule = function(listener) { + if(listener instanceof GenericSqlListener ) { + listener.exitFromTables(this); + } +}; + + + + +GenericSqlParser.FromTablesContext = FromTablesContext; + +GenericSqlParser.prototype.fromTables = function() { + + var localctx = new FromTablesContext(this, this._ctx, this.state); + this.enterRule(localctx, 4, GenericSqlParser.RULE_fromTables); + try { + this.enterOuterAlt(localctx, 1); + this.state = 44; + this.aliasField(); + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; +}; + + +function SelectFieldsContext(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + antlr4.ParserRuleContext.call(this, parent, invokingState); + this.parser = parser; + this.ruleIndex = GenericSqlParser.RULE_selectFields; + return this; +} + +SelectFieldsContext.prototype = Object.create(antlr4.ParserRuleContext.prototype); +SelectFieldsContext.prototype.constructor = SelectFieldsContext; + +SelectFieldsContext.prototype.field = function(i) { + if(i===undefined) { + i = null; + } + if(i===null) { + return this.getTypedRuleContexts(FieldContext); + } else { + return this.getTypedRuleContext(FieldContext,i); + } +}; + +SelectFieldsContext.prototype.enterRule = function(listener) { + if(listener instanceof GenericSqlListener ) { + listener.enterSelectFields(this); + } +}; + +SelectFieldsContext.prototype.exitRule = function(listener) { + if(listener instanceof GenericSqlListener ) { + listener.exitSelectFields(this); + } +}; + + + + +GenericSqlParser.SelectFieldsContext = SelectFieldsContext; + +GenericSqlParser.prototype.selectFields = function() { + + var localctx = new SelectFieldsContext(this, this._ctx, this.state); + this.enterRule(localctx, 6, GenericSqlParser.RULE_selectFields); + var _la = 0; // Token type + try { + this.enterOuterAlt(localctx, 1); + this.state = 46; + this.field(); + this.state = 51; + this._errHandler.sync(this); + _la = this._input.LA(1); + while(_la===GenericSqlParser.T__2) { + this.state = 47; + this.match(GenericSqlParser.T__2); + this.state = 48; + this.field(); + this.state = 53; + this._errHandler.sync(this); + _la = this._input.LA(1); + } + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; +}; + + +function FieldContext(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + antlr4.ParserRuleContext.call(this, parent, invokingState); + this.parser = parser; + this.ruleIndex = GenericSqlParser.RULE_field; + return this; +} + +FieldContext.prototype = Object.create(antlr4.ParserRuleContext.prototype); +FieldContext.prototype.constructor = FieldContext; + +FieldContext.prototype.aliasField = function() { + return this.getTypedRuleContext(AliasFieldContext,0); +}; + +FieldContext.prototype.ASTERISK = function() { + return this.getToken(GenericSqlParser.ASTERISK, 0); +}; + +FieldContext.prototype.enterRule = function(listener) { + if(listener instanceof GenericSqlListener ) { + listener.enterField(this); + } +}; + +FieldContext.prototype.exitRule = function(listener) { + if(listener instanceof GenericSqlListener ) { + listener.exitField(this); + } +}; + + + + +GenericSqlParser.FieldContext = FieldContext; + +GenericSqlParser.prototype.field = function() { + + var localctx = new FieldContext(this, this._ctx, this.state); + this.enterRule(localctx, 8, GenericSqlParser.RULE_field); + try { + this.state = 56; + this._errHandler.sync(this); + switch(this._input.LA(1)) { + case GenericSqlParser.ID: + case GenericSqlParser.QUOTED_ID: + this.enterOuterAlt(localctx, 1); + this.state = 54; + this.aliasField(); + break; + case GenericSqlParser.ASTERISK: + this.enterOuterAlt(localctx, 2); + this.state = 55; + this.match(GenericSqlParser.ASTERISK); + break; + default: + throw new antlr4.error.NoViableAltException(this); + } + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; +}; + + +function AliasFieldContext(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + antlr4.ParserRuleContext.call(this, parent, invokingState); + this.parser = parser; + this.ruleIndex = GenericSqlParser.RULE_aliasField; + return this; +} + +AliasFieldContext.prototype = Object.create(antlr4.ParserRuleContext.prototype); +AliasFieldContext.prototype.constructor = AliasFieldContext; + +AliasFieldContext.prototype.idPath = function() { + return this.getTypedRuleContext(IdPathContext,0); +}; + +AliasFieldContext.prototype.identifier = function() { + return this.getTypedRuleContext(IdentifierContext,0); +}; + +AliasFieldContext.prototype.AS = function() { + return this.getToken(GenericSqlParser.AS, 0); +}; + +AliasFieldContext.prototype.enterRule = function(listener) { + if(listener instanceof GenericSqlListener ) { + listener.enterAliasField(this); + } +}; + +AliasFieldContext.prototype.exitRule = function(listener) { + if(listener instanceof GenericSqlListener ) { + listener.exitAliasField(this); + } +}; + + + + +GenericSqlParser.AliasFieldContext = AliasFieldContext; + +GenericSqlParser.prototype.aliasField = function() { + + var localctx = new AliasFieldContext(this, this._ctx, this.state); + this.enterRule(localctx, 10, GenericSqlParser.RULE_aliasField); + var _la = 0; // Token type + try { + this.enterOuterAlt(localctx, 1); + this.state = 58; + this.idPath(); + this.state = 63; + this._errHandler.sync(this); + _la = this._input.LA(1); + if((((_la) & ~0x1f) == 0 && ((1 << _la) & ((1 << GenericSqlParser.AS) | (1 << GenericSqlParser.ID) | (1 << GenericSqlParser.QUOTED_ID))) !== 0)) { + this.state = 60; + this._errHandler.sync(this); + _la = this._input.LA(1); + if(_la===GenericSqlParser.AS) { + this.state = 59; + this.match(GenericSqlParser.AS); + } + + this.state = 62; + this.identifier(); + } + + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; +}; + + +function BoolExpContext(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + antlr4.ParserRuleContext.call(this, parent, invokingState); + this.parser = parser; + this.ruleIndex = GenericSqlParser.RULE_boolExp; + return this; +} + +BoolExpContext.prototype = Object.create(antlr4.ParserRuleContext.prototype); +BoolExpContext.prototype.constructor = BoolExpContext; + +BoolExpContext.prototype.exp = function(i) { + if(i===undefined) { + i = null; + } + if(i===null) { + return this.getTypedRuleContexts(ExpContext); + } else { + return this.getTypedRuleContext(ExpContext,i); + } +}; + +BoolExpContext.prototype.AND = function() { + return this.getToken(GenericSqlParser.AND, 0); +}; + +BoolExpContext.prototype.OR = function() { + return this.getToken(GenericSqlParser.OR, 0); +}; + +BoolExpContext.prototype.NOT = function() { + return this.getToken(GenericSqlParser.NOT, 0); +}; + +BoolExpContext.prototype.enterRule = function(listener) { + if(listener instanceof GenericSqlListener ) { + listener.enterBoolExp(this); + } +}; + +BoolExpContext.prototype.exitRule = function(listener) { + if(listener instanceof GenericSqlListener ) { + listener.exitBoolExp(this); + } +}; + + + + +GenericSqlParser.BoolExpContext = BoolExpContext; + +GenericSqlParser.prototype.boolExp = function() { + + var localctx = new BoolExpContext(this, this._ctx, this.state); + this.enterRule(localctx, 12, GenericSqlParser.RULE_boolExp); + try { + this.state = 76; + this._errHandler.sync(this); + var la_ = this._interp.adaptivePredict(this._input,6,this._ctx); + switch(la_) { + case 1: + this.enterOuterAlt(localctx, 1); + this.state = 65; + this.exp(0); + break; + + case 2: + this.enterOuterAlt(localctx, 2); + this.state = 66; + this.exp(0); + this.state = 67; + this.match(GenericSqlParser.AND); + this.state = 68; + this.exp(0); + break; + + case 3: + this.enterOuterAlt(localctx, 3); + this.state = 70; + this.exp(0); + this.state = 71; + this.match(GenericSqlParser.OR); + this.state = 72; + this.exp(0); + break; + + case 4: + this.enterOuterAlt(localctx, 4); + this.state = 74; + this.match(GenericSqlParser.NOT); + this.state = 75; + this.exp(0); + break; + + } + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; +}; + + +function ExpContext(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + antlr4.ParserRuleContext.call(this, parent, invokingState); + this.parser = parser; + this.ruleIndex = GenericSqlParser.RULE_exp; + return this; +} + +ExpContext.prototype = Object.create(antlr4.ParserRuleContext.prototype); +ExpContext.prototype.constructor = ExpContext; + +ExpContext.prototype.idPath = function() { + return this.getTypedRuleContext(IdPathContext,0); +}; + +ExpContext.prototype.identifier = function() { + return this.getTypedRuleContext(IdentifierContext,0); +}; + +ExpContext.prototype.exp = function(i) { + if(i===undefined) { + i = null; + } + if(i===null) { + return this.getTypedRuleContexts(ExpContext); + } else { + return this.getTypedRuleContext(ExpContext,i); + } +}; + +ExpContext.prototype.CAST = function() { + return this.getToken(GenericSqlParser.CAST, 0); +}; + +ExpContext.prototype.AS = function() { + return this.getToken(GenericSqlParser.AS, 0); +}; + +ExpContext.prototype.STRING = function() { + return this.getToken(GenericSqlParser.STRING, 0); +}; + +ExpContext.prototype.numeric = function() { + return this.getTypedRuleContext(NumericContext,0); +}; + +ExpContext.prototype.INDEXED_PARAM = function() { + return this.getToken(GenericSqlParser.INDEXED_PARAM, 0); +}; + +ExpContext.prototype.binaryOperator = function() { + return this.getTypedRuleContext(BinaryOperatorContext,0); +}; + +ExpContext.prototype.unaryOperator = function() { + return this.getTypedRuleContext(UnaryOperatorContext,0); +}; + +ExpContext.prototype.enterRule = function(listener) { + if(listener instanceof GenericSqlListener ) { + listener.enterExp(this); + } +}; + +ExpContext.prototype.exitRule = function(listener) { + if(listener instanceof GenericSqlListener ) { + listener.exitExp(this); + } +}; + + + +GenericSqlParser.prototype.exp = function(_p) { + if(_p===undefined) { + _p = 0; + } + var _parentctx = this._ctx; + var _parentState = this.state; + var localctx = new ExpContext(this, this._ctx, _parentState); + var _prevctx = localctx; + var _startState = 14; + this.enterRecursionRule(localctx, 14, GenericSqlParser.RULE_exp, _p); + var _la = 0; // Token type + try { + this.enterOuterAlt(localctx, 1); + this.state = 107; + this._errHandler.sync(this); + var la_ = this._interp.adaptivePredict(this._input,8,this._ctx); + switch(la_) { + case 1: + this.state = 79; + this.idPath(); + break; + + case 2: + this.state = 80; + this.identifier(); + this.state = 81; + this.match(GenericSqlParser.T__0); + + this.state = 82; + this.exp(0); + this.state = 87; + this._errHandler.sync(this); + _la = this._input.LA(1); + while(_la===GenericSqlParser.T__2) { + this.state = 83; + this.match(GenericSqlParser.T__2); + this.state = 84; + this.exp(0); + this.state = 89; + this._errHandler.sync(this); + _la = this._input.LA(1); + } + this.state = 90; + this.match(GenericSqlParser.T__1); + break; + + case 3: + this.state = 92; + this.match(GenericSqlParser.CAST); + this.state = 93; + this.match(GenericSqlParser.T__0); + this.state = 94; + this.exp(0); + this.state = 95; + this.match(GenericSqlParser.AS); + this.state = 96; + this.identifier(); + this.state = 97; + this.match(GenericSqlParser.T__1); + break; + + case 4: + this.state = 99; + this.match(GenericSqlParser.STRING); + break; + + case 5: + this.state = 100; + this.numeric(); + break; + + case 6: + this.state = 101; + this.identifier(); + break; + + case 7: + this.state = 102; + this.match(GenericSqlParser.INDEXED_PARAM); + break; + + case 8: + this.state = 103; + this.match(GenericSqlParser.T__0); + this.state = 104; + this.exp(0); + this.state = 105; + this.match(GenericSqlParser.T__1); + break; + + } + this._ctx.stop = this._input.LT(-1); + this.state = 117; + this._errHandler.sync(this); + var _alt = this._interp.adaptivePredict(this._input,10,this._ctx) + while(_alt!=2 && _alt!=antlr4.atn.ATN.INVALID_ALT_NUMBER) { + if(_alt===1) { + if(this._parseListeners!==null) { + this.triggerExitRuleEvent(); + } + _prevctx = localctx; + this.state = 115; + this._errHandler.sync(this); + var la_ = this._interp.adaptivePredict(this._input,9,this._ctx); + switch(la_) { + case 1: + localctx = new ExpContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, GenericSqlParser.RULE_exp); + this.state = 109; + if (!( this.precpred(this._ctx, 10))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 10)"); + } + this.state = 110; + this.binaryOperator(); + this.state = 111; + this.exp(11); + break; + + case 2: + localctx = new ExpContext(this, _parentctx, _parentState); + this.pushNewRecursionContext(localctx, _startState, GenericSqlParser.RULE_exp); + this.state = 113; + if (!( this.precpred(this._ctx, 9))) { + throw new antlr4.error.FailedPredicateException(this, "this.precpred(this._ctx, 9)"); + } + this.state = 114; + this.unaryOperator(); + break; + + } + } + this.state = 119; + this._errHandler.sync(this); + _alt = this._interp.adaptivePredict(this._input,10,this._ctx); + } + + } catch( error) { + if(error instanceof antlr4.error.RecognitionException) { + localctx.exception = error; + this._errHandler.reportError(this, error); + this._errHandler.recover(this, error); + } else { + throw error; + } + } finally { + this.unrollRecursionContexts(_parentctx) + } + return localctx; +}; + + +function NumericContext(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + antlr4.ParserRuleContext.call(this, parent, invokingState); + this.parser = parser; + this.ruleIndex = GenericSqlParser.RULE_numeric; + return this; +} + +NumericContext.prototype = Object.create(antlr4.ParserRuleContext.prototype); +NumericContext.prototype.constructor = NumericContext; + +NumericContext.prototype.DIGIT = function(i) { + if(i===undefined) { + i = null; + } + if(i===null) { + return this.getTokens(GenericSqlParser.DIGIT); + } else { + return this.getToken(GenericSqlParser.DIGIT, i); + } +}; + + +NumericContext.prototype.enterRule = function(listener) { + if(listener instanceof GenericSqlListener ) { + listener.enterNumeric(this); + } +}; + +NumericContext.prototype.exitRule = function(listener) { + if(listener instanceof GenericSqlListener ) { + listener.exitNumeric(this); + } +}; + + + + +GenericSqlParser.NumericContext = NumericContext; + +GenericSqlParser.prototype.numeric = function() { + + var localctx = new NumericContext(this, this._ctx, this.state); + this.enterRule(localctx, 16, GenericSqlParser.RULE_numeric); + try { + this.state = 139; + this._errHandler.sync(this); + switch(this._input.LA(1)) { + case GenericSqlParser.DIGIT: + this.enterOuterAlt(localctx, 1); + this.state = 121; + this._errHandler.sync(this); + var _alt = 1; + do { + switch (_alt) { + case 1: + this.state = 120; + this.match(GenericSqlParser.DIGIT); + break; + default: + throw new antlr4.error.NoViableAltException(this); + } + this.state = 123; + this._errHandler.sync(this); + _alt = this._interp.adaptivePredict(this._input,11, this._ctx); + } while ( _alt!=2 && _alt!=antlr4.atn.ATN.INVALID_ALT_NUMBER ); + this.state = 131; + this._errHandler.sync(this); + var la_ = this._interp.adaptivePredict(this._input,13,this._ctx); + if(la_===1) { + this.state = 125; + this.match(GenericSqlParser.T__3); + this.state = 127; + this._errHandler.sync(this); + var _alt = 1; + do { + switch (_alt) { + case 1: + this.state = 126; + this.match(GenericSqlParser.DIGIT); + break; + default: + throw new antlr4.error.NoViableAltException(this); + } + this.state = 129; + this._errHandler.sync(this); + _alt = this._interp.adaptivePredict(this._input,12, this._ctx); + } while ( _alt!=2 && _alt!=antlr4.atn.ATN.INVALID_ALT_NUMBER ); + + } + break; + case GenericSqlParser.T__3: + this.enterOuterAlt(localctx, 2); + this.state = 133; + this.match(GenericSqlParser.T__3); + this.state = 135; + this._errHandler.sync(this); + var _alt = 1; + do { + switch (_alt) { + case 1: + this.state = 134; + this.match(GenericSqlParser.DIGIT); + break; + default: + throw new antlr4.error.NoViableAltException(this); + } + this.state = 137; + this._errHandler.sync(this); + _alt = this._interp.adaptivePredict(this._input,14, this._ctx); + } while ( _alt!=2 && _alt!=antlr4.atn.ATN.INVALID_ALT_NUMBER ); + break; + default: + throw new antlr4.error.NoViableAltException(this); + } + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; +}; + + +function BinaryOperatorContext(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + antlr4.ParserRuleContext.call(this, parent, invokingState); + this.parser = parser; + this.ruleIndex = GenericSqlParser.RULE_binaryOperator; + return this; +} + +BinaryOperatorContext.prototype = Object.create(antlr4.ParserRuleContext.prototype); +BinaryOperatorContext.prototype.constructor = BinaryOperatorContext; + +BinaryOperatorContext.prototype.LT = function() { + return this.getToken(GenericSqlParser.LT, 0); +}; + +BinaryOperatorContext.prototype.LTE = function() { + return this.getToken(GenericSqlParser.LTE, 0); +}; + +BinaryOperatorContext.prototype.GT = function() { + return this.getToken(GenericSqlParser.GT, 0); +}; + +BinaryOperatorContext.prototype.GTE = function() { + return this.getToken(GenericSqlParser.GTE, 0); +}; + +BinaryOperatorContext.prototype.EQUALS = function() { + return this.getToken(GenericSqlParser.EQUALS, 0); +}; + +BinaryOperatorContext.prototype.NOT_EQUALS = function() { + return this.getToken(GenericSqlParser.NOT_EQUALS, 0); +}; + +BinaryOperatorContext.prototype.enterRule = function(listener) { + if(listener instanceof GenericSqlListener ) { + listener.enterBinaryOperator(this); + } +}; + +BinaryOperatorContext.prototype.exitRule = function(listener) { + if(listener instanceof GenericSqlListener ) { + listener.exitBinaryOperator(this); + } +}; + + + + +GenericSqlParser.BinaryOperatorContext = BinaryOperatorContext; + +GenericSqlParser.prototype.binaryOperator = function() { + + var localctx = new BinaryOperatorContext(this, this._ctx, this.state); + this.enterRule(localctx, 18, GenericSqlParser.RULE_binaryOperator); + var _la = 0; // Token type + try { + this.enterOuterAlt(localctx, 1); + this.state = 141; + _la = this._input.LA(1); + if(!((((_la) & ~0x1f) == 0 && ((1 << _la) & ((1 << GenericSqlParser.LT) | (1 << GenericSqlParser.LTE) | (1 << GenericSqlParser.GT) | (1 << GenericSqlParser.GTE) | (1 << GenericSqlParser.EQUALS) | (1 << GenericSqlParser.NOT_EQUALS))) !== 0))) { + this._errHandler.recoverInline(this); + } + else { + this._errHandler.reportMatch(this); + this.consume(); + } + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; +}; + + +function UnaryOperatorContext(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + antlr4.ParserRuleContext.call(this, parent, invokingState); + this.parser = parser; + this.ruleIndex = GenericSqlParser.RULE_unaryOperator; + return this; +} + +UnaryOperatorContext.prototype = Object.create(antlr4.ParserRuleContext.prototype); +UnaryOperatorContext.prototype.constructor = UnaryOperatorContext; + +UnaryOperatorContext.prototype.IS = function() { + return this.getToken(GenericSqlParser.IS, 0); +}; + +UnaryOperatorContext.prototype.NULL = function() { + return this.getToken(GenericSqlParser.NULL, 0); +}; + +UnaryOperatorContext.prototype.NOT = function() { + return this.getToken(GenericSqlParser.NOT, 0); +}; + +UnaryOperatorContext.prototype.enterRule = function(listener) { + if(listener instanceof GenericSqlListener ) { + listener.enterUnaryOperator(this); + } +}; + +UnaryOperatorContext.prototype.exitRule = function(listener) { + if(listener instanceof GenericSqlListener ) { + listener.exitUnaryOperator(this); + } +}; + + + + +GenericSqlParser.UnaryOperatorContext = UnaryOperatorContext; + +GenericSqlParser.prototype.unaryOperator = function() { + + var localctx = new UnaryOperatorContext(this, this._ctx, this.state); + this.enterRule(localctx, 20, GenericSqlParser.RULE_unaryOperator); + try { + this.state = 148; + this._errHandler.sync(this); + var la_ = this._interp.adaptivePredict(this._input,16,this._ctx); + switch(la_) { + case 1: + this.enterOuterAlt(localctx, 1); + this.state = 143; + this.match(GenericSqlParser.IS); + this.state = 144; + this.match(GenericSqlParser.NULL); + break; + + case 2: + this.enterOuterAlt(localctx, 2); + this.state = 145; + this.match(GenericSqlParser.IS); + this.state = 146; + this.match(GenericSqlParser.NOT); + this.state = 147; + this.match(GenericSqlParser.NULL); + break; + + } + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; +}; + + +function IdPathContext(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + antlr4.ParserRuleContext.call(this, parent, invokingState); + this.parser = parser; + this.ruleIndex = GenericSqlParser.RULE_idPath; + return this; +} + +IdPathContext.prototype = Object.create(antlr4.ParserRuleContext.prototype); +IdPathContext.prototype.constructor = IdPathContext; + +IdPathContext.prototype.identifier = function(i) { + if(i===undefined) { + i = null; + } + if(i===null) { + return this.getTypedRuleContexts(IdentifierContext); + } else { + return this.getTypedRuleContext(IdentifierContext,i); + } +}; + +IdPathContext.prototype.enterRule = function(listener) { + if(listener instanceof GenericSqlListener ) { + listener.enterIdPath(this); + } +}; + +IdPathContext.prototype.exitRule = function(listener) { + if(listener instanceof GenericSqlListener ) { + listener.exitIdPath(this); + } +}; + + + + +GenericSqlParser.IdPathContext = IdPathContext; + +GenericSqlParser.prototype.idPath = function() { + + var localctx = new IdPathContext(this, this._ctx, this.state); + this.enterRule(localctx, 22, GenericSqlParser.RULE_idPath); + try { + this.enterOuterAlt(localctx, 1); + this.state = 150; + this.identifier(); + this.state = 155; + this._errHandler.sync(this); + var _alt = this._interp.adaptivePredict(this._input,17,this._ctx) + while(_alt!=2 && _alt!=antlr4.atn.ATN.INVALID_ALT_NUMBER) { + if(_alt===1) { + this.state = 151; + this.match(GenericSqlParser.T__3); + this.state = 152; + this.identifier(); + } + this.state = 157; + this._errHandler.sync(this); + _alt = this._interp.adaptivePredict(this._input,17,this._ctx); + } + + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; +}; + + +function IdentifierContext(parser, parent, invokingState) { + if(parent===undefined) { + parent = null; + } + if(invokingState===undefined || invokingState===null) { + invokingState = -1; + } + antlr4.ParserRuleContext.call(this, parent, invokingState); + this.parser = parser; + this.ruleIndex = GenericSqlParser.RULE_identifier; + return this; +} + +IdentifierContext.prototype = Object.create(antlr4.ParserRuleContext.prototype); +IdentifierContext.prototype.constructor = IdentifierContext; + +IdentifierContext.prototype.ID = function() { + return this.getToken(GenericSqlParser.ID, 0); +}; + +IdentifierContext.prototype.QUOTED_ID = function() { + return this.getToken(GenericSqlParser.QUOTED_ID, 0); +}; + +IdentifierContext.prototype.enterRule = function(listener) { + if(listener instanceof GenericSqlListener ) { + listener.enterIdentifier(this); + } +}; + +IdentifierContext.prototype.exitRule = function(listener) { + if(listener instanceof GenericSqlListener ) { + listener.exitIdentifier(this); + } +}; + + + + +GenericSqlParser.IdentifierContext = IdentifierContext; + +GenericSqlParser.prototype.identifier = function() { + + var localctx = new IdentifierContext(this, this._ctx, this.state); + this.enterRule(localctx, 24, GenericSqlParser.RULE_identifier); + var _la = 0; // Token type + try { + this.enterOuterAlt(localctx, 1); + this.state = 158; + _la = this._input.LA(1); + if(!(_la===GenericSqlParser.ID || _la===GenericSqlParser.QUOTED_ID)) { + this._errHandler.recoverInline(this); + } + else { + this._errHandler.reportMatch(this); + this.consume(); + } + } catch (re) { + if(re instanceof antlr4.error.RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } finally { + this.exitRule(); + } + return localctx; +}; + + +GenericSqlParser.prototype.sempred = function(localctx, ruleIndex, predIndex) { + switch(ruleIndex) { + case 7: + return this.exp_sempred(localctx, predIndex); + default: + throw "No predicate with index:" + ruleIndex; + } +}; + +GenericSqlParser.prototype.exp_sempred = function(localctx, predIndex) { + switch(predIndex) { + case 0: + return this.precpred(this._ctx, 10); + case 1: + return this.precpred(this._ctx, 9); + default: + throw "No predicate with index:" + predIndex; + } +}; + + +exports.GenericSqlParser = GenericSqlParser; diff --git a/packages/cubejs-schema-compiler/parser/SqlParser.js b/packages/cubejs-schema-compiler/parser/SqlParser.js new file mode 100644 index 0000000000000..a98e7da00af18 --- /dev/null +++ b/packages/cubejs-schema-compiler/parser/SqlParser.js @@ -0,0 +1,193 @@ +const antlr4 = require('antlr4'); +const R = require('ramda'); +const { GenericSqlLexer } = require('./GenericSqlLexer'); +const { GenericSqlParser } = require('./GenericSqlParser'); +const UserError = require('../compiler/UserError'); + +const { + QueryContext, SelectFieldsContext, IdPathContext, AliasFieldContext +} = GenericSqlParser; + +const nodeVisitor = (visitor) => ({ + visitChildren(ctx) { + if (!ctx) { + return; + } + + visitor.visitNode(ctx); + + if (ctx.children) { + ctx.children.forEach(child => { + if (child.children && child.children.length) { + child.accept(this); + } + }); + } + } +}); + +class SqlParser { + constructor(sql) { + this.sql = sql; + this.ast = this.parse(); + } + + static sqlUpperCase(sql) { + let result = ''; + let openChar; + for (let i = 0; i < sql.length; i++) { + if (openChar) { + if (openChar === '\'' && sql[i] === openChar && sql[i + 1] === openChar) { + result += sql[i]; + i++; + } else if (sql[i] === openChar) { + openChar = null; + } + result += sql[i]; + } else { + if (sql[i] === '\'' || sql[i] === '"' || sql[i] === '`') { + openChar = sql[i]; + } + result += sql[i].toUpperCase(); + } + } + if (openChar) { + throw new Error(`Unterminated string: ${sql}`); + } + return result; + } + + parse() { + const { sql } = this; + const chars = new antlr4.InputStream(SqlParser.sqlUpperCase(sql)); + chars.getText = (start, stop) => { + // eslint-disable-next-line no-underscore-dangle + if (stop >= this._size) { + // eslint-disable-next-line no-underscore-dangle + stop = this._size - 1; + } + // eslint-disable-next-line no-underscore-dangle + if (start >= this._size) { + return ""; + } else { + return sql.slice(start, stop + 1); + } + }; + const lexer = new GenericSqlLexer(chars); + const tokens = new antlr4.CommonTokenStream(lexer); + const parser = new GenericSqlParser(tokens); + parser.buildParseTrees = true; + const errors = []; + this.errors = errors; + parser.removeErrorListeners(); + + class ExprErrorListener extends antlr4.error.ErrorListener { + syntaxError(recognizer, offendingSymbol, line, column, msg, err) { + errors.push({ + msg, column, err, line, recognizer, offendingSymbol + }); + } + } + + parser.addErrorListener(new ExprErrorListener()); + + return parser.statement(); + } + + canParse() { + return !this.errors.length; + } + + throwErrorsIfAny() { + if (this.errors.length) { + throw new UserError(`SQL Parsing Error:\n${this.errors.map(({ msg, column, line }) => `${line}:${column} ${msg}`).join('\n')}`); + } + } + + isSimpleAsteriskQuery() { + if (!this.canParse()) { + return false; + } + + let result = false; + + this.ast.accept(nodeVisitor({ + visitNode(ctx) { + if (ctx instanceof QueryContext) { + const selectItems = ctx.getTypedRuleContexts(SelectFieldsContext); + if (selectItems.length === 1 && selectItems[0].getText() === '*') { + result = true; + } + } + } + })); + return result; + } + + extractWhereConditions(tableAlias) { + this.throwErrorsIfAny(); + let result = ''; + + const { sql } = this; + + let cursor = 0; + let end = 0; + let originalAlias; + + const whereBuildingVisitor = nodeVisitor({ + visitNode(ctx) { + if (ctx instanceof IdPathContext) { + result += sql.substring(cursor, ctx.start.start); + cursor = ctx.start.start; + if (ctx.children[0].getText() === originalAlias) { + const withoutFirst = R.drop(1, ctx.children); + result += [tableAlias].concat(withoutFirst.map(c => c.getText())).join(''); + cursor = ctx.stop.stop + 1; + } else if (ctx.children.length === 1) { + result += [tableAlias, '.'].concat(ctx.children.map(c => c.getText())).join(''); + cursor = ctx.stop.stop + 1; + } else { + result += sql.substring(cursor, ctx.stop.stop); + cursor = ctx.stop.stop; + } + } + } + }); + + this.ast.accept(nodeVisitor({ + visitNode(ctx) { + if (ctx instanceof QueryContext && ctx.from && ctx.where) { + const aliasField = ctx.from.getTypedRuleContexts(AliasFieldContext)[0]; + const lastNode = aliasField.children[aliasField.children.length - 1]; + if (lastNode instanceof IdPathContext) { + originalAlias = lastNode.children[lastNode.children.length - 1].getText(); + } else { + originalAlias = lastNode.getText(); + } + cursor = ctx.where.start.start; + end = ctx.where.stop.stop + 1; + ctx.where.accept(whereBuildingVisitor); + } + } + })); + result += sql.substring(cursor, end); + return result; + } + + extractTableFrom() { + this.throwErrorsIfAny(); + let result = null; + + this.ast.accept(nodeVisitor({ + visitNode(ctx) { + if (ctx instanceof QueryContext && ctx.from) { + const aliasField = ctx.from.getTypedRuleContexts(AliasFieldContext)[0]; + result = aliasField.children[0].getText(); + } + } + })); + return result; + } +} + +module.exports = SqlParser; diff --git a/packages/cubejs-schema-compiler/test/SQLGenerationTest.js b/packages/cubejs-schema-compiler/test/SQLGenerationTest.js index a8d732384e939..ac1963c45ff54 100644 --- a/packages/cubejs-schema-compiler/test/SQLGenerationTest.js +++ b/packages/cubejs-schema-compiler/test/SQLGenerationTest.js @@ -28,6 +28,8 @@ describe('SQL Generation', function test() { \${USER_CONTEXT.sourceArray.filter(sourceArray => \`source in (\${sourceArray.join(',')})\`)} \`, + rewriteQueries: true, + refreshKey: { sql: 'SELECT 1', }, diff --git a/packages/cubejs-schema-compiler/test/SqlParserTest.js b/packages/cubejs-schema-compiler/test/SqlParserTest.js new file mode 100644 index 0000000000000..fa38a7f92b0dd --- /dev/null +++ b/packages/cubejs-schema-compiler/test/SqlParserTest.js @@ -0,0 +1,69 @@ +/* eslint-disable quote-props */ +/* globals it,describe */ +const SqlParser = require('../parser/SqlParser'); +require('should'); + +describe('SqlParser', () => { + it('basic where', () => { + const sqlParser = new SqlParser(`select + * + from + some.ttt + WHERE + CAST( + CONCAT( + SUBSTRING($1$, 1, 13), + ':00:00' + ) AS DATETIME + ) <= ttt.date_hour + AND ttt.date_hour <= CAST( + CONCAT( + SUBSTRING($2$, 1, 13), + ':00:00' + ) AS DATETIME + )`); + sqlParser.isSimpleAsteriskQuery().should.be.deepEqual(true); + sqlParser.extractWhereConditions('x').should.be.deepEqual(`CAST( + CONCAT( + SUBSTRING($1$, 1, 13), + ':00:00' + ) AS DATETIME + ) <= x.date_hour + AND x.date_hour <= CAST( + CONCAT( + SUBSTRING($2$, 1, 13), + ':00:00' + ) AS DATETIME + )`); + }); + + it('non aliased', () => { + const sqlParser = new SqlParser(`select + * + from + some.ttt + WHERE a is null`); + sqlParser.isSimpleAsteriskQuery().should.be.deepEqual(true); + sqlParser.extractWhereConditions('x').should.be.deepEqual(`x.a is null`); + }); + + it('do not honor group by', () => { + const sqlParser = new SqlParser(`select + asd + from + some.ttt + GROUP BY 1 + `); + sqlParser.isSimpleAsteriskQuery().should.be.deepEqual(false); + }); + + it('wrapped', () => { + const sqlParser = new SqlParser(`(select + * + from + some.ttt WHERE 1 = 1) + `); + sqlParser.isSimpleAsteriskQuery().should.be.deepEqual(true); + sqlParser.extractWhereConditions('x').should.be.deepEqual('1 = 1'); + }); +}); diff --git a/packages/cubejs-schema-compiler/yarn.lock b/packages/cubejs-schema-compiler/yarn.lock index 03f1e7565e135..f7adadbe04b8f 100644 --- a/packages/cubejs-schema-compiler/yarn.lock +++ b/packages/cubejs-schema-compiler/yarn.lock @@ -888,6 +888,11 @@ ansi-styles@^4.1.0: "@types/color-name" "^1.1.1" color-convert "^2.0.1" +antlr4@^4.8.0: + version "4.8.0" + resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.8.0.tgz#f938ec171be7fc2855cd3a533e87647185b32b6a" + integrity sha512-en/MxQ4OkPgGJQ3wD/muzj1uDnFSzdFIhc2+c6bHZokWkuBb6RRvFjpWhPxWLbgQvaEzldJZ0GSQpfSAaE3hqg== + any-promise@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" diff --git a/packages/cubejs-server-core/core/index.js b/packages/cubejs-server-core/core/index.js index 715ea12e72203..1a61e73a79a73 100644 --- a/packages/cubejs-server-core/core/index.js +++ b/packages/cubejs-server-core/core/index.js @@ -58,7 +58,7 @@ const devLogger = (level) => (type, { error, warning, ...message }) => { const withColor = (str, color = colors.green) => `\u001b[${color}m${str}\u001b[0m`; const format = ({ - requestId, duration, allSqlLines, query, values, queryKey, showRestParams, ...json + requestId, duration, allSqlLines, query, values, showRestParams, ...json }) => { const restParams = JSON.stringify(json, null, 2); const durationStr = duration ? `(${duration}ms)` : '';