diff --git a/core/index.html b/core/index.html new file mode 100644 index 0000000..244d42f --- /dev/null +++ b/core/index.html @@ -0,0 +1,9 @@ + +
+ + + + 1 + + + \ No newline at end of file diff --git a/core/sqlSyntaxParser.js b/core/sqlSyntaxParser.js new file mode 100644 index 0000000..c3581a6 --- /dev/null +++ b/core/sqlSyntaxParser.js @@ -0,0 +1,9191 @@ +// Licensed to Cloudera, Inc. under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. Cloudera, Inc. licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +var SqlParseSupport = (function () { + + // endsWith polyfill from hue_utils.js, needed as workers live in their own js environment + if (!String.prototype.endsWith) { + String.prototype.endsWith = function (searchString, position) { + var subjectString = this.toString(); + if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) { + position = subjectString.length; + } + position -= searchString.length; + var lastIndex = subjectString.lastIndexOf(searchString, position); + return lastIndex !== -1 && lastIndex === position; + }; + } + + /** + * Calculates the Optimal String Alignment distance between two strings. Returns 0 when the strings are equal and the + * distance when not, distances is less than or equal to the length of the longest string. + * + * @param strA + * @param strB + * @param [ignoreCase] + * @returns {number} The similarity + */ + var stringDistance = function (strA, strB, ignoreCase) { + if (ignoreCase) { + strA = strA.toLowerCase(); + strB = strB.toLowerCase(); + } + + // TODO: Consider other algorithms for performance + var strALength = strA.length; + var strBLength = strB.length; + if (strALength === 0) { + return strBLength; + } + if (strBLength === 0) { + return strALength; + } + + var distances = new Array(strALength); + + var cost, deletion, insertion, substitution, transposition; + for (var i = 0; i <= strALength; i++) { + distances[i] = new Array(strBLength); + distances[i][0] = i; + for (var j = 1; j <= strBLength; j++) { + if (!i){ + distances[0][j] = j; + } else { + cost = strA[i-1] === strB[j-1] ? 0 : 1; + deletion = distances[i - 1][j] + 1; + insertion = distances[i][j - 1] + 1; + substitution = distances[i - 1][j - 1] + cost; + if (deletion <= insertion && deletion <= substitution) { + distances[i][j] = deletion; + } else if (insertion <= deletion && insertion <= substitution) { + distances[i][j] = insertion; + } else { + distances[i][j] = substitution; + } + + if (i > 1 && j > 1 && strA[i] === strB[j - 1] && strA[i - 1] === strB[j]) { + transposition = distances[i - 2][j - 2] + cost; + if (transposition < distances[i][j]) { + distances[i][j] = transposition; + } + } + } + } + } + + return distances[strALength][strBLength]; + }; + + var equalIgnoreCase = function (a, b) { + return a && b && a.toLowerCase() === b.toLowerCase(); + }; + + var initSqlParser = function (parser) { + + var SIMPLE_TABLE_REF_SUGGESTIONS = ['suggestJoinConditions', 'suggestAggregateFunctions', 'suggestFilters', 'suggestGroupBys', 'suggestOrderBys']; + + parser.prepareNewStatement = function () { + linkTablePrimaries(); + parser.commitLocations(); + + delete parser.yy.lateralViews; + delete parser.yy.latestCommonTableExpressions; + delete parser.yy.correlatedSubQuery; + parser.yy.subQueries = []; + parser.yy.selectListAliases = []; + parser.yy.latestTablePrimaries = []; + + prioritizeSuggestions(); + }; + + parser.yy.parseError = function (message, error) { + parser.yy.errors.push(error); + return message; + }; + + parser.addCommonTableExpressions = function (identifiers) { + parser.yy.result.commonTableExpressions = identifiers; + parser.yy.latestCommonTableExpressions = identifiers; + }; + + parser.isInSubquery = function () { + return !!parser.yy.primariesStack.length + }; + + parser.pushQueryState = function () { + parser.yy.resultStack.push(parser.yy.result); + parser.yy.locationsStack.push(parser.yy.locations); + parser.yy.lateralViewsStack.push(parser.yy.lateralViews); + parser.yy.selectListAliasesStack.push(parser.yy.selectListAliases); + parser.yy.primariesStack.push(parser.yy.latestTablePrimaries); + parser.yy.subQueriesStack.push(parser.yy.subQueries); + + parser.yy.result = {}; + parser.yy.locations = []; + parser.yy.selectListAliases = []; // Not allowed in correlated sub-queries + parser.yy.lateralViews = []; // Not allowed in correlated sub-queries + + if (parser.yy.correlatedSubQuery) { + parser.yy.latestTablePrimaries = parser.yy.latestTablePrimaries.concat(); + parser.yy.subQueries = parser.yy.subQueries.concat(); + } else { + parser.yy.latestTablePrimaries = []; + parser.yy.subQueries = []; + } + }; + + parser.popQueryState = function (subQuery) { + linkTablePrimaries(); + parser.commitLocations(); + + if (Object.keys(parser.yy.result).length === 0) { + parser.yy.result = parser.yy.resultStack.pop(); + } else { + parser.yy.resultStack.pop(); + } + var oldSubQueries = parser.yy.subQueries; + parser.yy.subQueries = parser.yy.subQueriesStack.pop(); + if (subQuery) { + if (oldSubQueries.length > 0) { + subQuery.subQueries = oldSubQueries; + } + parser.yy.subQueries.push(subQuery); + } + + parser.yy.lateralViews = parser.yy.lateralViewsStack.pop(); + parser.yy.latestTablePrimaries = parser.yy.primariesStack.pop(); + parser.yy.locations = parser.yy.locationsStack.pop(); + parser.yy.selectListAliases = parser.yy.selectListAliasesStack.pop(); + }; + + parser.suggestSelectListAliases = function () { + if (parser.yy.selectListAliases && parser.yy.selectListAliases.length > 0 && parser.yy.result.suggestColumns + && (typeof parser.yy.result.suggestColumns.identifierChain === 'undefined' || parser.yy.result.suggestColumns.identifierChain.length === 0)) { + parser.yy.result.suggestColumnAliases = parser.yy.selectListAliases; + } + }; + + parser.isHive = function () { + return parser.yy.activeDialect === 'hive'; + }; + + parser.isImpala = function () { + return parser.yy.activeDialect === 'impala'; + }; + + parser.mergeSuggestKeywords = function () { + var result = []; + Array.prototype.slice.call(arguments).forEach(function (suggestion) { + if (typeof suggestion !== 'undefined' && typeof suggestion.suggestKeywords !== 'undefined') { + result = result.concat(suggestion.suggestKeywords); + } + }); + if (result.length > 0) { + return {suggestKeywords: result}; + } + return {}; + }; + + parser.suggestValueExpressionKeywords = function (valueExpression, extras) { + var expressionKeywords = parser.getValueExpressionKeywords(valueExpression, extras); + parser.suggestKeywords(expressionKeywords.suggestKeywords); + if (expressionKeywords.suggestColRefKeywords) { + parser.suggestColRefKeywords(expressionKeywords.suggestColRefKeywords); + } + if (valueExpression.lastType) { + parser.addColRefIfExists(valueExpression.lastType); + } else { + parser.addColRefIfExists(valueExpression); + } + }; + + parser.getSelectListKeywords = function (excludeAsterisk) { + var keywords = [{ value: 'CASE', weight: 450 }, 'FALSE', 'TRUE', 'NULL']; + if (!excludeAsterisk) { + keywords.push({ value: '*', weight: 10000 }); + } + if (parser.isHive()) { + keywords = keywords.concat(['EXISTS', 'NOT']); + } + return keywords; + }; + + parser.getValueExpressionKeywords = function (valueExpression, extras) { + var types = valueExpression.lastType ? valueExpression.lastType.types : valueExpression.types; + // We could have valueExpression.columnReference to suggest based on column type + var keywords = ['<', '<=', '<=>', '<>', '=', '>', '>=', 'BETWEEN', 'IN', 'IS NOT NULL', 'IS NULL', 'IS NOT TRUE', 'IS TRUE', 'IS NOT FALSE', 'IS FALSE', 'NOT BETWEEN', 'NOT IN']; + if (parser.isImpala()) { + keywords = keywords.concat(['IS DISTINCT FROM', 'IS NOT DISTINCT FROM', 'IS NOT UNKNOWN', 'IS UNKNOWN']); + } + if (extras) { + keywords = keywords.concat(extras); + } + if (valueExpression.suggestKeywords) { + keywords = keywords.concat(valueExpression.suggestKeywords); + } + if (types.length === 1 && types[0] === 'COLREF') { + return { + suggestKeywords: keywords, + suggestColRefKeywords: { + BOOLEAN: ['AND', 'OR'], + NUMBER: ['+', '-', '*', '/', '%', 'DIV'], + STRING: parser.isImpala() ? ['ILIKE', 'IREGEXP', 'LIKE', 'NOT LIKE', 'REGEXP', 'RLIKE'] : ['LIKE', 'NOT LIKE', 'REGEXP', 'RLIKE'] + } + } + } + if (typeof SqlFunctions === 'undefined' || SqlFunctions.matchesType(parser.yy.activeDialect, ['BOOLEAN'], types)) { + keywords = keywords.concat(['AND', 'OR']); + } + if (typeof SqlFunctions === 'undefined' || SqlFunctions.matchesType(parser.yy.activeDialect, ['NUMBER'], types)) { + keywords = keywords.concat(['+', '-', '*', '/', '%', 'DIV']); + } + if (typeof SqlFunctions === 'undefined' || SqlFunctions.matchesType(parser.yy.activeDialect, ['STRING'], types)) { + keywords = keywords.concat(parser.isImpala() ? ['ILIKE', 'IREGEXP', 'LIKE', 'NOT LIKE', 'REGEXP', 'RLIKE'] : ['LIKE', 'NOT LIKE', 'REGEXP', 'RLIKE']); + } + return { suggestKeywords: keywords }; + }; + + parser.getTypeKeywords = function () { + if (parser.isHive()) { + return ['BIGINT', 'BINARY', 'BOOLEAN', 'CHAR', 'DATE', 'DECIMAL', 'DOUBLE', 'DOUBLE PRECISION', 'FLOAT', 'INT', 'SMALLINT', 'TIMESTAMP', 'STRING', 'TINYINT', 'VARCHAR']; + } + if (parser.isImpala()) { + return ['BIGINT', 'BOOLEAN', 'CHAR', 'DECIMAL', 'DOUBLE', 'FLOAT', 'INT', 'REAL', 'SMALLINT', 'TIMESTAMP', 'STRING', 'TINYINT', 'VARCHAR']; + } + return ['BIGINT', 'BOOLEAN', 'CHAR', 'DECIMAL', 'DOUBLE', 'FLOAT', 'INT', 'SMALLINT', 'TIMESTAMP', 'STRING', 'TINYINT', 'VARCHAR']; + }; + + parser.getColumnDataTypeKeywords = function () { + if (parser.isHive()) { + return parser.getTypeKeywords().concat(['ARRAY<>', 'MAP<>', 'STRUCT<>', 'UNIONTYPE<>']); + } + if (parser.isImpala()) { + return parser.getTypeKeywords().concat(['ARRAY<>', 'MAP<>', 'STRUCT<>']); + } + return parser.getTypeKeywords(); + }; + + parser.addColRefIfExists = function (valueExpression) { + if (valueExpression.columnReference) { + parser.yy.result.colRef = {identifierChain: valueExpression.columnReference}; + } + }; + + parser.selectListNoTableSuggest = function (selectListEdit, hasDistinctOrAll) { + if (selectListEdit.cursorAtStart) { + var keywords = parser.getSelectListKeywords(); + if (!hasDistinctOrAll) { + keywords = keywords.concat([{ value: 'ALL', weight: 2 }, { value: 'DISTINCT', weight: 2 }]); + } + if (parser.isImpala()) { + keywords.push('STRAIGHT_JOIN'); + } + parser.suggestKeywords(keywords); + } else { + parser.checkForKeywords(selectListEdit); + } + if (selectListEdit.suggestFunctions) { + parser.suggestFunctions(); + } + if (selectListEdit.suggestColumns) { + parser.suggestColumns(); + } + if (selectListEdit.suggestAggregateFunctions && (!hasDistinctOrAll || hasDistinctOrAll === 'ALL')) { + parser.suggestAggregateFunctions(); + parser.suggestAnalyticFunctions(); + } + }; + + parser.suggestJoinConditions = function (details) { + parser.yy.result.suggestJoinConditions = details || {}; + if (parser.yy.latestTablePrimaries && !parser.yy.result.suggestJoinConditions.tablePrimaries) { + parser.yy.result.suggestJoinConditions.tablePrimaries = parser.yy.latestTablePrimaries.concat(); + } + }; + + parser.suggestJoins = function (details) { + parser.yy.result.suggestJoins = details || {}; + }; + + parser.valueExpressionSuggest = function (oppositeValueExpression, operator) { + if (oppositeValueExpression && oppositeValueExpression.columnReference) { + parser.suggestValues(); + parser.yy.result.colRef = {identifierChain: oppositeValueExpression.columnReference}; + } + parser.suggestColumns(); + parser.suggestFunctions(); + var keywords = [{ value: 'CASE', weight: 450 }, { value: 'FALSE', weight: 450 }, { value: 'NULL', weight: 450 }, { value: 'TRUE', weight: 450 }]; + if (parser.isHive() || typeof oppositeValueExpression === 'undefined' || typeof operator === 'undefined') { + keywords = keywords.concat(['EXISTS', 'NOT']); + } + if (oppositeValueExpression && oppositeValueExpression.types[0] === 'NUMBER') { + parser.applyTypeToSuggestions(['NUMBER']); + } else if (parser.isImpala() && (typeof operator === 'undefined' || operator === '-' || operator === '+')) { + keywords.push('INTERVAL'); + } + parser.suggestKeywords(keywords); + }; + + parser.applyTypeToSuggestions = function (types) { + if (types[0] === 'BOOLEAN') { + return; + } + if (parser.yy.result.suggestFunctions && !parser.yy.result.suggestFunctions.types) { + parser.yy.result.suggestFunctions.types = types; + } + if (parser.yy.result.suggestColumns && !parser.yy.result.suggestColumns.types) { + parser.yy.result.suggestColumns.types = types; + } + }; + + parser.findCaseType = function (whenThenList) { + var types = {}; + whenThenList.caseTypes.forEach(function (valueExpression) { + valueExpression.types.forEach(function (type) { + types[type] = true; + }); + }); + if (Object.keys(types).length === 1) { + return {types: [Object.keys(types)[0]]}; + } + return {types: ['T']}; + }; + + parser.findReturnTypes = function (functionName) { + return typeof SqlFunctions === 'undefined' ? ['T'] : SqlFunctions.getReturnTypes(parser.yy.activeDialect, functionName.toLowerCase()); + }; + + parser.applyArgumentTypesToSuggestions = function (functionName, position) { + var foundArguments = typeof SqlFunctions === 'undefined' ? ['T'] : SqlFunctions.getArgumentTypes(parser.yy.activeDialect, functionName.toLowerCase(), position); + if (foundArguments.length == 0 && parser.yy.result.suggestColumns) { + delete parser.yy.result.suggestColumns; + delete parser.yy.result.suggestKeyValues; + delete parser.yy.result.suggestValues; + delete parser.yy.result.suggestFunctions; + delete parser.yy.result.suggestIdentifiers; + delete parser.yy.result.suggestKeywords; + } else { + parser.applyTypeToSuggestions(foundArguments); + } + }; + + var getCleanImpalaPrimaries = function (primaries) { + var cleanPrimaries = []; + for (var i = primaries.length - 1; i >= 0; i--) { + var cleanPrimary = primaries[i]; + if (cleanPrimary.identifierChain && cleanPrimary.identifierChain.length > 0) { + for (var j = i - 1; j >=0; j--) { + var parentPrimary = primaries[j]; + if (parentPrimary.alias && cleanPrimary.identifierChain[0].name === parentPrimary.alias) { + var restOfChain = cleanPrimary.identifierChain.concat(); + restOfChain.shift(); + if (cleanPrimary.alias) { + cleanPrimary = { identifierChain: parentPrimary.identifierChain.concat(restOfChain), alias: cleanPrimary.alias, impalaComplex: true }; + } else { + cleanPrimary = { identifierChain: parentPrimary.identifierChain.concat(restOfChain), impalaComplex: true }; + } + } + } + } + cleanPrimaries.push(cleanPrimary); + } + return cleanPrimaries; + }; + + parser.commitLocations = function () { + if (parser.yy.locations.length === 0) { + return; + } + + var tablePrimaries = parser.yy.latestTablePrimaries; + + if (parser.isImpala()) { + tablePrimaries = []; + getCleanImpalaPrimaries(parser.yy.latestTablePrimaries).forEach(function (primary) { + var cleanPrimary = primary; + if (primary.identifierChain && primary.identifierChain.length > 0) { + for (var j = parser.yy.primariesStack.length - 1; j >= 0; j--) { + getCleanImpalaPrimaries(parser.yy.primariesStack[j]).every(function (parentPrimary) { + if (parentPrimary.alias && parentPrimary.alias === primary.identifierChain[0].name) { + var identifierChain = primary.identifierChain.concat(); + identifierChain.shift(); + cleanPrimary = { identifierChain: parentPrimary.identifierChain.concat(identifierChain) }; + if (primary.alias) { + cleanPrimary.alias = primary.alias; + } + return false; + } + return true; + }); + } + } + tablePrimaries.unshift(cleanPrimary); + }); + } + var i = parser.yy.locations.length; + + while (i--) { + var location = parser.yy.locations[i]; + if (location.type === 'variable' && location.colRef) { + parser.expandIdentifierChain({ wrapper: location.colRef, tablePrimaries: tablePrimaries, isColumnWrapper: true }); + delete location.colRef.linked; + } + + // Impala can have references to previous tables after FROM, i.e. FROM testTable t, t.testArray + // In this testArray would be marked a type table so we need to switch it to column. + if (location.type === 'table' && typeof location.identifierChain !== 'undefined' && location.identifierChain.length > 1 && tablePrimaries) { + var allPrimaries = tablePrimaries; + parser.yy.primariesStack.forEach(function (parentPrimaries) { + allPrimaries = getCleanImpalaPrimaries(parentPrimaries).concat(allPrimaries); + }); + var found = allPrimaries.filter(function (primary) { + return equalIgnoreCase(primary.alias, location.identifierChain[0].name); + }); + if (found.length > 0) { + location.type = 'column'; + } + } + + if (location.type === 'database' && typeof location.identifierChain !== 'undefined' && location.identifierChain.length > 0 && tablePrimaries) { + var allPrimaries = tablePrimaries; + parser.yy.primariesStack.forEach(function (parentPrimaries) { + allPrimaries = getCleanImpalaPrimaries(parentPrimaries).concat(allPrimaries); + }); + var foundAlias = allPrimaries.filter(function (primary) { + return equalIgnoreCase(primary.alias, location.identifierChain[0].name); + }); + if (foundAlias.length > 0 && parser.isImpala()) { + // Impala complex reference in FROM clause, i.e. FROM testTable t, t.testMap tm + location.type = 'table'; + parser.expandIdentifierChain({ tablePrimaries: allPrimaries, wrapper: location, anyOwner: true }); + location.type = location.identifierChain.length === 1 ? 'table' : 'complex'; + continue; + } + } + + if (location.type === 'unknown') { + if (typeof location.identifierChain !== 'undefined' && location.identifierChain.length > 0 && location.identifierChain.length <= 2 && tablePrimaries) { + var found = tablePrimaries.filter(function (primary) { + return equalIgnoreCase(primary.alias, location.identifierChain[0].name) || (primary.identifierChain && equalIgnoreCase(primary.identifierChain[0].name, location.identifierChain[0].name)); + }); + if (!found.length && location.firstInChain) { + found = tablePrimaries.filter(function (primary) { + return !primary.alias && primary.identifierChain && equalIgnoreCase(primary.identifierChain[primary.identifierChain.length - 1].name, location.identifierChain[0].name); + }); + } + + if (found.length) { + if (found[0].identifierChain.length > 1 && location.identifierChain.length === 1 && equalIgnoreCase(found[0].identifierChain[0].name, location.identifierChain[0].name)) { + location.type = 'database'; + } else if (found[0].alias && equalIgnoreCase(location.identifierChain[0].name, found[0].alias) && location.identifierChain.length > 1) { + location.type = 'column'; + parser.expandIdentifierChain({ tablePrimaries: tablePrimaries, wrapper: location, anyOwner: true }); + } else if (!found[0].alias && found[0].identifierChain && equalIgnoreCase(location.identifierChain[0].name, found[0].identifierChain[found[0].identifierChain.length - 1].name) && location.identifierChain.length > 1) { + location.type = 'column'; + parser.expandIdentifierChain({ tablePrimaries: tablePrimaries, wrapper: location, anyOwner: true }); + } else { + location.type = found[0].impalaComplex ? 'column' : 'table'; + parser.expandIdentifierChain({ tablePrimaries: tablePrimaries, wrapper: location, anyOwner: true }); + } + } else { + if (parser.yy.subQueries) { + found = parser.yy.subQueries.filter(function (subQuery) { + return equalIgnoreCase(subQuery.alias, location.identifierChain[0].name); + }); + if (found.length > 0) { + location.type = 'subQuery'; + location.identifierChain = [{subQuery: found[0].alias}]; + } + } + } + } + } + + if (location.type === 'asterisk' && !location.linked) { + + if (tablePrimaries && tablePrimaries.length > 0) { + location.tables = []; + location.linked = false; + if (!location.identifierChain) { + location.identifierChain = [{ asterisk: true }]; + } + parser.expandIdentifierChain({ tablePrimaries: tablePrimaries, wrapper: location, anyOwner: false }); + if (location.tables.length === 0) { + parser.yy.locations.splice(i, 1); + } + } else { + parser.yy.locations.splice(i, 1); + } + } + + if (location.type === 'table' && typeof location.identifierChain !== 'undefined' && location.identifierChain.length === 1 && location.identifierChain[0].name) { + // Could be a cte reference + parser.yy.locations.some(function (otherLocation) { + if (otherLocation.type === 'alias' && otherLocation.source === 'cte' && SqlUtils.identifierEquals(otherLocation.alias, location.identifierChain[0].name)) { + // TODO: Possibly add the other location if we want to show the link in the future. + // i.e. highlight select definition on hover over alias, also for subquery references. + location.type = 'alias'; + location.target = 'cte'; + location.alias = location.identifierChain[0].name; + delete location.identifierChain; + return true; + } + }); + } + + if (location.type === 'table' && (typeof location.identifierChain === 'undefined' || location.identifierChain.length === 0)) { + parser.yy.locations.splice(i, 1); + } + + if (location.type === 'unknown') { + location.type = 'column'; + } + + // A column location might refer to a previously defined alias, i.e. last 'foo' in "SELECT cast(id AS int) foo FROM tbl ORDER BY foo;" + if (location.type === 'column') { + for (var j = i - 1; j >= 0; j--) { + var otherLocation = parser.yy.locations[j]; + if (otherLocation.type === 'alias' && otherLocation.source === 'column' && location.identifierChain && location.identifierChain.length === 1 && location.identifierChain[0].name && otherLocation.alias && location.identifierChain[0].name.toLowerCase() === otherLocation.alias.toLowerCase()) { + location.type = 'alias'; + location.source = 'column'; + location.alias = location.identifierChain[0].name; + delete location.identifierChain; + location.parentLocation = otherLocation.parentLocation; + break; + } + } + } + + if (location.type === 'column') { + if (parser.isHive() && !location.linked) { + location.identifierChain = parser.expandLateralViews(parser.yy.lateralViews, location.identifierChain); + } + + var initialIdentifierChain = location.identifierChain ? location.identifierChain.concat() : undefined; + + parser.expandIdentifierChain({ tablePrimaries: tablePrimaries, wrapper: location, anyOwner: true, isColumnWrapper: true, isColumnLocation: true }); + + if (typeof location.identifierChain === 'undefined') { + parser.yy.locations.splice(i, 1); + } else if (location.identifierChain.length === 0 && initialIdentifierChain && initialIdentifierChain.length === 1) { + // This is for the case "SELECT tblOrColName FROM db.tblOrColName"; + location.identifierChain = initialIdentifierChain; + } + } + if (location.type === 'column' && location.identifierChain) { + if (location.identifierChain.length > 1 && location.tables && location.tables.length > 0) { + location.type = 'complex'; + } + } + delete location.firstInChain; + if (location.type !== 'column' && location.type !== 'complex') { + delete location.qualified; + } else if (typeof location.qualified === 'undefined') { + location.qualified = false; + } + } + + if (parser.yy.locations.length > 0) { + parser.yy.allLocations = parser.yy.allLocations.concat(parser.yy.locations); + parser.yy.locations = []; + } + }; + + var prioritizeSuggestions = function () { + parser.yy.result.lowerCase = parser.yy.lowerCase || false; + + var cteIndex = {}; + + if (typeof parser.yy.latestCommonTableExpressions !== 'undefined') { + parser.yy.latestCommonTableExpressions.forEach(function (cte) { + cteIndex[cte.alias.toLowerCase()] = cte; + }) + } + + SIMPLE_TABLE_REF_SUGGESTIONS.forEach(function (suggestionType) { + if (suggestionType !== 'suggestAggregateFunctions' && typeof parser.yy.result[suggestionType] !== 'undefined' && parser.yy.result[suggestionType].tables.length === 0) { + delete parser.yy.result[suggestionType]; + } else if (typeof parser.yy.result[suggestionType] !== 'undefined' && typeof parser.yy.result[suggestionType].tables !== 'undefined') { + for (var i = parser.yy.result[suggestionType].tables.length - 1; i >= 0; i--) { + var table = parser.yy.result[suggestionType].tables[i]; + if (table.identifierChain.length === 1 && typeof table.identifierChain[0].name !== 'undefined' && typeof cteIndex[table.identifierChain[0].name.toLowerCase()] !== 'undefined') { + parser.yy.result[suggestionType].tables.splice(i, 1); + } + } + } + }); + + if (typeof parser.yy.result.colRef !== 'undefined') { + if (!parser.yy.result.colRef.linked || typeof parser.yy.result.colRef.identifierChain === 'undefined' || parser.yy.result.colRef.identifierChain.length === 0) { + delete parser.yy.result.colRef; + if (typeof parser.yy.result.suggestColRefKeywords !== 'undefined') { + Object.keys(parser.yy.result.suggestColRefKeywords).forEach(function (type) { + parser.yy.result.suggestKeywords = parser.yy.result.suggestKeywords.concat(parser.createWeightedKeywords(parser.yy.result.suggestColRefKeywords[type], -1)); + }); + delete parser.yy.result.suggestColRefKeywords; + } + if (parser.yy.result.suggestColumns && parser.yy.result.suggestColumns.types.length === 1 && parser.yy.result.suggestColumns.types[0] === 'COLREF') { + parser.yy.result.suggestColumns.types = ['T']; + } + delete parser.yy.result.suggestValues; + } + } + + if (typeof parser.yy.result.colRef !== 'undefined') { + if (!parser.yy.result.suggestValues && !parser.yy.result.suggestColRefKeywords && + (!parser.yy.result.suggestColumns || + parser.yy.result.suggestColumns.types[0] !== 'COLREF')) { + delete parser.yy.result.colRef; + } + } + if (typeof parser.yy.result.suggestIdentifiers !== 'undefined' && parser.yy.result.suggestIdentifiers.length > 0) { + delete parser.yy.result.suggestTables; + delete parser.yy.result.suggestDatabases; + } + if (typeof parser.yy.result.suggestColumns !== 'undefined') { + var suggestColumns = parser.yy.result.suggestColumns; + if (typeof suggestColumns.tables === 'undefined' || suggestColumns.tables.length === 0) { + // Impala supports statements like SELECT * FROM tbl1, tbl2 WHERE db.tbl1.col = tbl2.bla + if (parser.yy.result.suggestColumns.linked && parser.isImpala() && typeof suggestColumns.identifierChain !== 'undefined' && suggestColumns.identifierChain.length > 0) { + if (suggestColumns.identifierChain.length === 1) { + parser.yy.result.suggestTables = suggestColumns; + delete parser.yy.result.suggestColumns + } else { + suggestColumns.tables = [{identifierChain: suggestColumns.identifierChain}]; + delete suggestColumns.identifierChain; + } + } else { + delete parser.yy.result.suggestColumns; + delete parser.yy.result.subQueries; + } + } else { + delete parser.yy.result.suggestTables; + delete parser.yy.result.suggestDatabases; + + suggestColumns.tables.forEach(function (table) { + if (typeof table.identifierChain !== 'undefined' && table.identifierChain.length === 1 && typeof table.identifierChain[0].name !== 'undefined') { + var cte = cteIndex[table.identifierChain[0].name.toLowerCase()]; + if (typeof cte !== 'undefined') { + delete table.identifierChain[0].name; + table.identifierChain[0].cte = cte.alias; + } + } else if (typeof table.identifierChain === 'undefined' && table.subQuery) { + table.identifierChain = [{ subQuery: table.subQuery }]; + delete table.subQuery; + } + }); + + if (typeof suggestColumns.identifierChain !== 'undefined' && suggestColumns.identifierChain.length === 0) { + delete suggestColumns.identifierChain; + } + } + } else { + delete parser.yy.result.subQueries; + } + + if (typeof parser.yy.result.suggestJoinConditions !== 'undefined') { + if (typeof parser.yy.result.suggestJoinConditions.tables === 'undefined' || parser.yy.result.suggestJoinConditions.tables.length === 0) { + delete parser.yy.result.suggestJoinConditions; + } + } + + if (typeof parser.yy.result.suggestTables !== 'undefined' && typeof parser.yy.latestCommonTableExpressions !== 'undefined') { + var ctes = []; + parser.yy.latestCommonTableExpressions.forEach(function (cte) { + var suggestion = {name: cte.alias}; + if (parser.yy.result.suggestTables.prependFrom) { + suggestion.prependFrom = true + } + if (parser.yy.result.suggestTables.prependQuestionMark) { + suggestion.prependQuestionMark = true; + } + ctes.push(suggestion); + }); + if (ctes.length > 0) { + parser.yy.result.suggestCommonTableExpressions = ctes; + } + } + }; + + /** + * Impala supports referencing maps and arrays in the the table reference list i.e. + * + * SELECT m['foo'].bar.| FROM someDb.someTable t, t.someMap m; + * + * From this the tablePrimaries would look like: + * + * [ { alias: 't', identifierChain: [ { name: 'someDb' }, { name: 'someTable' } ] }, + * { alias: 'm', identifierChain: [ { name: 't' }, { name: 'someMap' } ] } ] + * + * with an identifierChain from the select list: + * + * [ { name: 'm', keySet: true }, { name: 'bar' } ] + * + * Calling this would return an expanded identifierChain, given the above it would be: + * + * [ { name: 't' }, { name: 'someMap', keySet: true }, { name: 'bar' } ] + */ + parser.expandImpalaIdentifierChain = function (tablePrimaries, identifierChain) { + var expandedChain = identifierChain.concat(); // Clone in case it's called multiple times. + if (typeof expandedChain === 'undefined' || expandedChain.length === 0) { + return identifierChain; + } + var expand = function (identifier, expandedChain) { + var foundPrimary = tablePrimaries.filter(function (tablePrimary) { + var primaryIdentifier = tablePrimary.alias; + if (!primaryIdentifier && tablePrimary.identifierChain && tablePrimary.identifierChain.length > 0) { + primaryIdentifier = tablePrimary.identifierChain[tablePrimary.identifierChain.length - 1].name; + } + return equalIgnoreCase(primaryIdentifier, identifier); + }); + + if (foundPrimary.length === 1 && foundPrimary[0].identifierChain) { + var parentPrimary = tablePrimaries.filter(function (tablePrimary) { + return equalIgnoreCase(tablePrimary.alias, foundPrimary[0].identifierChain[0].name); + }); + if (parentPrimary.length === 1) { + var keySet = expandedChain[0].keySet; + var secondPart = expandedChain.slice(1); + var firstPart = []; + // Clone to make sure we don't add keySet to the primaries + foundPrimary[0].identifierChain.forEach(function (identifier) { + firstPart.push({name: identifier.name}); + }); + if (keySet && firstPart.length > 0) { + firstPart[firstPart.length - 1].keySet = true; + } + + if (firstPart.length === 0 || typeof secondPart === 'undefined' || secondPart.length === 0) { + return firstPart; + } + var result = firstPart.concat(secondPart); + if (result.length > 0) { + return expand(firstPart[0].name, result); + } else { + return result; + } + } + } + return expandedChain; + }; + return expand(expandedChain[0].name, expandedChain); + }; + + parser.identifyPartials = function (beforeCursor, afterCursor) { + var beforeMatch = beforeCursor.match(/[0-9a-zA-Z_]*$/); + var afterMatch = afterCursor.match(/^[0-9a-zA-Z_]*(?:\((?:[^)]*\))?)?/); + return {left: beforeMatch ? beforeMatch[0].length : 0, right: afterMatch ? afterMatch[0].length : 0}; + }; + + parser.expandLateralViews = function (lateralViews, originalIdentifierChain, columnSuggestion) { + var identifierChain = originalIdentifierChain.concat(); // Clone in case it's re-used + var firstIdentifier = identifierChain[0]; + if (typeof lateralViews !== 'undefined') { + lateralViews.concat().reverse().forEach(function (lateralView) { + if (!lateralView.udtf.expression.columnReference) { + return; + } + if (equalIgnoreCase(firstIdentifier.name, lateralView.tableAlias) && identifierChain.length > 1) { + identifierChain.shift(); + firstIdentifier = identifierChain[0]; + if (columnSuggestion) { + delete parser.yy.result.suggestKeywords; + } + } else if (equalIgnoreCase(firstIdentifier.name, lateralView.tableAlias) && identifierChain.length === 1 && typeof parser.yy.result.suggestColumns !== 'undefined') { + if (columnSuggestion) { + if (typeof parser.yy.result.suggestIdentifiers === 'undefined') { + parser.yy.result.suggestIdentifiers = []; + } + lateralView.columnAliases.forEach(function (columnAlias) { + parser.yy.result.suggestIdentifiers.push({name: columnAlias, type: 'alias'}); + }); + delete parser.yy.result.suggestColumns; + delete parser.yy.result.suggestKeywords; + } + return identifierChain; + } + if (lateralView.columnAliases.indexOf(firstIdentifier.name) !== -1) { + if (lateralView.columnAliases.length === 2 && lateralView.udtf.function.toLowerCase() === 'explode' && equalIgnoreCase(firstIdentifier.name, lateralView.columnAliases[0])) { + identifierChain[0] = {name: 'key'}; + } else if (lateralView.columnAliases.length === 2 && lateralView.udtf.function.toLowerCase() === 'explode' && equalIgnoreCase(firstIdentifier.name, lateralView.columnAliases[1])) { + identifierChain[0] = {name: 'value'}; + } else { + identifierChain[0] = {name: 'item'}; + } + identifierChain = lateralView.udtf.expression.columnReference.concat(identifierChain); + firstIdentifier = identifierChain[0]; + } + }); + } + return identifierChain; + }; + + var addCleanTablePrimary = function (tables, tablePrimary) { + if (tablePrimary.alias) { + tables.push({alias: tablePrimary.alias, identifierChain: tablePrimary.identifierChain}); + } else { + tables.push({identifierChain: tablePrimary.identifierChain}); + } + }; + + parser.expandIdentifierChain = function (options) { + var wrapper = options.wrapper; + var anyOwner = options.anyOwner; + var isColumnWrapper = options.isColumnWrapper; + var isColumnLocation = options.isColumnLocation; + var tablePrimaries = options.tablePrimaries || parser.yy.latestTablePrimaries; + + if (typeof wrapper.identifierChain === 'undefined' || typeof tablePrimaries === 'undefined') { + return; + } + var identifierChain = wrapper.identifierChain.concat(); + + if (tablePrimaries.length === 0) { + delete wrapper.identifierChain; + return; + } + + if (!anyOwner) { + tablePrimaries = filterTablePrimariesForOwner(tablePrimaries, wrapper.owner); + } + + if (identifierChain.length > 0 && identifierChain[identifierChain.length - 1].asterisk) { + var tables = []; + tablePrimaries.forEach(function (tablePrimary) { + if (identifierChain.length > 1 && !tablePrimary.subQueryAlias) { + if (identifierChain.length === 2 && equalIgnoreCase(tablePrimary.alias, identifierChain[0].name)) { + addCleanTablePrimary(tables, tablePrimary); + } else if (identifierChain.length === 2 && equalIgnoreCase(tablePrimary.identifierChain[0].name, identifierChain[0].name)) { + addCleanTablePrimary(tables, tablePrimary); + } else if (identifierChain.length === 3 && tablePrimary.identifierChain.length > 1 && + equalIgnoreCase(tablePrimary.identifierChain[0].name, identifierChain[0].name) && + equalIgnoreCase(tablePrimary.identifierChain[1].name, identifierChain[1].name)) { + addCleanTablePrimary(tables, tablePrimary); + } + } else { + if (tablePrimary.subQueryAlias) { + tables.push({identifierChain: [{subQuery: tablePrimary.subQueryAlias}]}); + } else { + addCleanTablePrimary(tables, tablePrimary); + } + } + }); + // Possible Joins + if (tables.length > 0) { + wrapper.tables = tables; + delete wrapper.identifierChain; + return; + } + } + + // Impala can have references to maps or array, i.e. FROM table t, t.map m + // We need to replace those in the identifierChain + if (parser.isImpala()) { + var lengthBefore = identifierChain.length; + identifierChain = parser.expandImpalaIdentifierChain(tablePrimaries, identifierChain); + // Change type of any locations marked as table + if (wrapper.type === 'table' && identifierChain.length > lengthBefore) { + wrapper.type = 'column'; + } + wrapper.identifierChain = identifierChain; + } + // Expand exploded views in the identifier chain + if (parser.isHive() && identifierChain.length > 0) { + identifierChain = parser.expandLateralViews(parser.yy.lateralViews, identifierChain); + wrapper.identifierChain = identifierChain; + } + + // IdentifierChain contains a possibly started identifier or empty, example: a.b.c = ['a', 'b', 'c'] + // Reduce the tablePrimaries to the one that matches the first identifier if found + var foundPrimary; + var doubleMatch = false; + var aliasMatch = false; + if (identifierChain.length > 0) { + for (var i = 0; i < tablePrimaries.length; i++) { + if (tablePrimaries[i].subQueryAlias) { + if (equalIgnoreCase(tablePrimaries[i].subQueryAlias, identifierChain[0].name)) { + foundPrimary = tablePrimaries[i]; + } + } else if (equalIgnoreCase(tablePrimaries[i].alias, identifierChain[0].name)) { + foundPrimary = tablePrimaries[i]; + aliasMatch = true; + break; + } else if (tablePrimaries[i].identifierChain.length > 1 && identifierChain.length > 1 && + equalIgnoreCase(tablePrimaries[i].identifierChain[0].name, identifierChain[0].name) && + equalIgnoreCase(tablePrimaries[i].identifierChain[1].name, identifierChain[1].name)) { + foundPrimary = tablePrimaries[i]; + doubleMatch = true; + break; + } else if (!foundPrimary && equalIgnoreCase(tablePrimaries[i].identifierChain[0].name, identifierChain[0].name) && identifierChain.length > (isColumnLocation ? 1 : 0)) { + foundPrimary = tablePrimaries[i]; + // No break as first two can still match. + } else if (!foundPrimary && tablePrimaries[i].identifierChain.length > 1 && !tablePrimaries[i].alias + && equalIgnoreCase(tablePrimaries[i].identifierChain[tablePrimaries[i].identifierChain.length - 1].name, identifierChain[0].name)) { + // This is for the case SELECT baa. FROM bla.baa, blo.boo; + foundPrimary = tablePrimaries[i]; + break; + } + } + } + + if (foundPrimary) { + if (foundPrimary.impalaComplex && wrapper.type === 'column') { + wrapper.type = 'complex'; + } + identifierChain.shift(); + if (doubleMatch) { + identifierChain.shift(); + } + } else if (tablePrimaries.length === 1 && !isColumnWrapper) { + foundPrimary = tablePrimaries[0]; + } + + if (foundPrimary) { + if (isColumnWrapper) { + wrapper.identifierChain = identifierChain; + if (foundPrimary.subQueryAlias) { + wrapper.tables = [{ subQuery: foundPrimary.subQueryAlias }]; + } else if (foundPrimary.alias) { + if (!isColumnLocation && isColumnWrapper && aliasMatch) { + // TODO: add alias on table in suggestColumns (needs support in sqlAutocomplete3.js) + // the case is: SELECT cu.| FROM customers cu; + // This prevents alias from being added automatically in sqlAutocompleter3.js + wrapper.tables = [{ identifierChain: foundPrimary.identifierChain }]; + } else { + wrapper.tables = [{ identifierChain: foundPrimary.identifierChain, alias: foundPrimary.alias }]; + } + } else { + wrapper.tables = [{ identifierChain: foundPrimary.identifierChain }]; + } + } else { + if (foundPrimary.subQueryAlias) { + identifierChain.unshift({ subQuery: foundPrimary.subQueryAlias }); + } else { + identifierChain = foundPrimary.identifierChain.concat(identifierChain); + } + if (wrapper.tables) { + wrapper.tables.push({identifierChain: identifierChain}); + delete wrapper.identifierChain; + } else { + wrapper.identifierChain = identifierChain; + } + } + } else { + if (isColumnWrapper) { + wrapper.tables = []; + } + tablePrimaries.forEach(function (tablePrimary) { + var targetTable = tablePrimary.subQueryAlias ? { subQuery: tablePrimary.subQueryAlias } : { identifierChain: tablePrimary.identifierChain } ; + if (tablePrimary.alias) { + targetTable.alias = tablePrimary.alias; + } + if (wrapper.tables) { + wrapper.tables.push(targetTable) + } + }); + } + delete wrapper.owner; + wrapper.linked = true; + }; + + var suggestLateralViewAliasesAsIdentifiers = function () { + if (typeof parser.yy.lateralViews === 'undefined' || parser.yy.lateralViews.length === 0) { + return; + } + if (typeof parser.yy.result.suggestIdentifiers === 'undefined') { + parser.yy.result.suggestIdentifiers = []; + } + parser.yy.lateralViews.forEach(function (lateralView) { + if (typeof lateralView.tableAlias !== 'undefined') { + parser.yy.result.suggestIdentifiers.push({name: lateralView.tableAlias + '.', type: 'alias'}); + } + lateralView.columnAliases.forEach(function (columnAlias) { + parser.yy.result.suggestIdentifiers.push({name: columnAlias, type: 'alias'}); + }); + }); + if (parser.yy.result.suggestIdentifiers.length === 0) { + delete parser.yy.result.suggestIdentifiers; + } + }; + + var filterTablePrimariesForOwner = function (tablePrimaries, owner) { + var result = []; + tablePrimaries.forEach(function (primary) { + if (typeof owner === 'undefined' && typeof primary.owner === 'undefined') { + result.push(primary); + } else if (owner === primary.owner) { + result.push(primary); + } + }); + return result; + }; + + var convertTablePrimariesToSuggestions = function (tablePrimaries) { + var tables = []; + var identifiers = []; + tablePrimaries.forEach(function (tablePrimary) { + if (tablePrimary.identifierChain && tablePrimary.identifierChain.length > 0) { + var table = {identifierChain: tablePrimary.identifierChain}; + if (tablePrimary.alias) { + table.alias = tablePrimary.alias; + identifiers.push({name: table.alias + '.', type: 'alias'}); + if (parser.isImpala()) { + var testForImpalaAlias = [{name: table.alias}]; + var result = parser.expandImpalaIdentifierChain(tablePrimaries, testForImpalaAlias); + if (result.length > 1) { + // Continue if it's a reference to a complex type + return; + } + } + } else { + var lastIdentifier = tablePrimary.identifierChain[tablePrimary.identifierChain.length - 1]; + if (typeof lastIdentifier.name !== 'undefined') { + identifiers.push({name: lastIdentifier.name + '.', type: 'table'}); + } else if (typeof lastIdentifier.subQuery !== 'undefined') { + identifiers.push({name: lastIdentifier.subQuery + '.', type: 'sub-query'}); + } + } + tables.push(table); + } else if (tablePrimary.subQueryAlias) { + identifiers.push({name: tablePrimary.subQueryAlias + '.', type: 'sub-query'}); + tables.push({identifierChain: [{subQuery: tablePrimary.subQueryAlias}]}); + } + }); + if (identifiers.length > 0) { + if (typeof parser.yy.result.suggestIdentifiers === 'undefined') { + parser.yy.result.suggestIdentifiers = identifiers; + } else { + parser.yy.result.suggestIdentifiers = identifiers.concat(parser.yy.result.suggestIdentifiers); + } + } + parser.yy.result.suggestColumns.tables = tables; + if (parser.yy.result.suggestColumns.identifierChain && parser.yy.result.suggestColumns.identifierChain.length === 0) { + delete parser.yy.result.suggestColumns.identifierChain; + } + parser.yy.result.suggestColumns.linked = true; + }; + + var linkTablePrimaries = function () { + if (!parser.yy.cursorFound || typeof parser.yy.latestTablePrimaries === 'undefined') { + return; + } + + SIMPLE_TABLE_REF_SUGGESTIONS.forEach(function (suggestionType) { + if (typeof parser.yy.result[suggestionType] !== 'undefined' && parser.yy.result[suggestionType].tablePrimaries && !parser.yy.result[suggestionType].linked) { + parser.yy.result[suggestionType].tables = []; + parser.yy.result[suggestionType].tablePrimaries.forEach(function (tablePrimary) { + if (!tablePrimary.subQueryAlias) { + parser.yy.result[suggestionType].tables.push(tablePrimary.alias ? { + identifierChain: tablePrimary.identifierChain.concat(), + alias: tablePrimary.alias + } : {identifierChain: tablePrimary.identifierChain.concat()}); + } + }); + delete parser.yy.result[suggestionType].tablePrimaries; + parser.yy.result[suggestionType].linked = true; + } + }); + + if (typeof parser.yy.result.suggestColumns !== 'undefined' && !parser.yy.result.suggestColumns.linked) { + var tablePrimaries = filterTablePrimariesForOwner(parser.yy.latestTablePrimaries, parser.yy.result.suggestColumns.owner); + if (!parser.yy.result.suggestColumns.tables) { + parser.yy.result.suggestColumns.tables = []; + } + if (parser.yy.subQueries.length > 0) { + parser.yy.result.subQueries = parser.yy.subQueries; + } + if (typeof parser.yy.result.suggestColumns.identifierChain === 'undefined' || parser.yy.result.suggestColumns.identifierChain.length === 0) { + if (tablePrimaries.length > 1) { + convertTablePrimariesToSuggestions(tablePrimaries); + } else { + suggestLateralViewAliasesAsIdentifiers(); + if (tablePrimaries.length === 1 && (tablePrimaries[0].alias || tablePrimaries[0].subQueryAlias)) { + convertTablePrimariesToSuggestions(tablePrimaries); + } + parser.expandIdentifierChain({ wrapper: parser.yy.result.suggestColumns, anyOwner: false, isColumnWrapper: true }); + } + } else { + // Expand exploded views in the identifier chain + if (parser.isHive() && !parser.yy.result.suggestColumns.linked) { + var originalLength = parser.yy.result.suggestColumns.identifierChain.length; + parser.yy.result.suggestColumns.identifierChain = parser.expandLateralViews(parser.yy.lateralViews, parser.yy.result.suggestColumns.identifierChain, true); + // Drop '*' keyword for lateral views + if (typeof parser.yy.result.suggestColumns !== 'undefined') { + if (parser.yy.result.suggestColumns.identifierChain.length > originalLength && + typeof parser.yy.result.suggestKeywords !== 'undefined' && + parser.yy.result.suggestKeywords.length === 1 && + parser.yy.result.suggestKeywords[0].value === '*') { + delete parser.yy.result.suggestKeywords; + } + parser.expandIdentifierChain({ wrapper: parser.yy.result.suggestColumns, anyOwner: false, isColumnWrapper: true }); + } + } else { + parser.expandIdentifierChain({ wrapper: parser.yy.result.suggestColumns, anyOwner: false, isColumnWrapper: true }); + } + } + } + + if (typeof parser.yy.result.colRef !== 'undefined' && !parser.yy.result.colRef.linked) { + parser.expandIdentifierChain({ wrapper: parser.yy.result.colRef }); + + var primaries = filterTablePrimariesForOwner(parser.yy.latestTablePrimaries); + if (primaries.length === 0 || (primaries.length > 1 && parser.yy.result.colRef.identifierChain.length === 1)) { + parser.yy.result.colRef.identifierChain = []; + } + } + if (typeof parser.yy.result.suggestKeyValues !== 'undefined' && !parser.yy.result.suggestKeyValues.linked) { + parser.expandIdentifierChain({ wrapper: parser.yy.result.suggestKeyValues }); + } + }; + + parser.getSubQuery = function (cols) { + var columns = []; + cols.selectList.forEach(function (col) { + var result = {}; + if (col.alias) { + result.alias = col.alias; + } + if (col.valueExpression && col.valueExpression.columnReference) { + result.identifierChain = col.valueExpression.columnReference + } else if (col.asterisk) { + result.identifierChain = [{asterisk: true}]; + } + if (col.valueExpression && col.valueExpression.types && col.valueExpression.types.length === 1) { + result.type = col.valueExpression.types[0]; + } + + columns.push(result); + }); + + return { + columns: columns + }; + }; + + parser.addTablePrimary = function (ref) { + if (typeof parser.yy.latestTablePrimaries === 'undefined') { + parser.yy.latestTablePrimaries = []; + } + parser.yy.latestTablePrimaries.push(ref); + }; + + parser.suggestFileFormats = function () { + if (parser.isHive()) { + parser.suggestKeywords(['AVRO', 'INPUTFORMAT', 'ORC', 'PARQUET', 'RCFILE', 'SEQUENCEFILE', 'TEXTFILE']); + } else { + parser.suggestKeywords(['AVRO', 'KUDU', 'ORC', 'PARQUET', 'RCFILE', 'SEQUENCEFILE', 'TEXTFILE']); + } + }; + + parser.getKeywordsForOptionalsLR = function (optionals, keywords, override) { + var result = []; + + for (var i = 0; i < optionals.length; i++) { + if (!optionals[i] && (typeof override === 'undefined' || override[i])) { + if (keywords[i] instanceof Array) { + result = result.concat(keywords[i]); + } else { + result.push(keywords[i]); + } + } else if (optionals[i]) { + break; + } + } + return result; + }; + + parser.suggestDdlAndDmlKeywords = function (extraKeywords) { + var keywords = ['ALTER', 'CREATE', 'DESCRIBE', 'DROP', 'GRANT', 'INSERT', 'REVOKE', 'SELECT', 'SET', 'SHOW', 'TRUNCATE', 'UPDATE', 'USE', 'WITH']; + + if (extraKeywords) { + keywords = keywords.concat(extraKeywords); + } + + if (parser.isHive()) { + keywords = keywords.concat(['ABORT', 'ANALYZE TABLE', 'DELETE', 'EXPORT', 'IMPORT', 'LOAD', 'MERGE', 'MSCK', 'RELOAD FUNCTION', 'RESET']); + } + + if (parser.isImpala()) { + keywords = keywords.concat(['COMMENT ON', 'COMPUTE', 'DELETE', 'INVALIDATE METADATA', 'LOAD', 'REFRESH', 'UPSERT']); + } + + parser.suggestKeywords(keywords); + }; + + parser.checkForSelectListKeywords = function (selectList) { + if (selectList.length === 0) { + return; + } + var last = selectList[selectList.length - 1]; + if (!last || !last.valueExpression) { + return; + } + var valueExpressionKeywords = parser.getValueExpressionKeywords(last.valueExpression); + var keywords = []; + if (last.suggestKeywords) { + keywords = keywords.concat(last.suggestKeywords); + } + if (valueExpressionKeywords.suggestKeywords) { + keywords = keywords.concat(valueExpressionKeywords.suggestKeywords); + } + if (valueExpressionKeywords.suggestColRefKeywords) { + parser.suggestColRefKeywords(valueExpressionKeywords.suggestColRefKeywords); + parser.addColRefIfExists(last.valueExpression); + } + if (!last.alias) { + keywords.push('AS'); + } + if (keywords.length > 0) { + parser.suggestKeywords(keywords); + } + }; + + parser.checkForKeywords = function (expression) { + if (expression) { + if (expression.suggestKeywords && expression.suggestKeywords.length > 0) { + parser.suggestKeywords(expression.suggestKeywords); + } + if (expression.suggestColRefKeywords) { + parser.suggestColRefKeywords(expression.suggestColRefKeywords); + parser.addColRefIfExists(expression); + } + } + }; + + parser.createWeightedKeywords = function (keywords, weight) { + var result = []; + keywords.forEach(function (keyword) { + if (typeof keyword.weight !== 'undefined') { + keyword.weight = weight + (keyword.weight / 10); + result.push(keyword); + } else { + result.push({value: keyword, weight: weight}); + } + }); + return result; + }; + + parser.suggestKeywords = function (keywords) { + var weightedKeywords = []; + if (keywords.length == 0) { + return; + } + keywords.forEach(function (keyword) { + if (typeof keyword.weight !== 'undefined') { + weightedKeywords.push(keyword); + } else { + weightedKeywords.push({value: keyword, weight: -1}) + } + }); + weightedKeywords.sort(function (a, b) { + if (a.weight !== b.weight) { + return b.weight - a.weight; + } + return a.value.localeCompare(b.value); + }); + parser.yy.result.suggestKeywords = weightedKeywords; + }; + + parser.suggestColRefKeywords = function (colRefKeywords) { + parser.yy.result.suggestColRefKeywords = colRefKeywords; + }; + + parser.suggestTablesOrColumns = function (identifier) { + if (typeof parser.yy.latestTablePrimaries == 'undefined') { + parser.suggestTables({identifierChain: [{name: identifier}]}); + return; + } + var tableRef = parser.yy.latestTablePrimaries.filter(function (tablePrimary) { + return equalIgnoreCase(tablePrimary.alias, identifier); + }); + if (tableRef.length > 0) { + parser.suggestColumns({identifierChain: [{name: identifier}]}); + } else { + parser.suggestTables({identifierChain: [{name: identifier}]}); + } + }; + + parser.suggestFunctions = function (details) { + parser.yy.result.suggestFunctions = details || {}; + }; + + parser.suggestAggregateFunctions = function () { + var primaries = []; + var aliases = {}; + parser.yy.latestTablePrimaries.forEach(function (primary) { + if (typeof primary.alias !== 'undefined') { + aliases[primary.alias] = true; + } + // Drop if the first one refers to a table alias (...FROM tbl t, t.map tm ...) + if (typeof primary.identifierChain !== 'undefined' && !aliases[primary.identifierChain[0].name] && typeof primary.owner === 'undefined') { + primaries.push(primary); + } + }); + parser.yy.result.suggestAggregateFunctions = {tablePrimaries: primaries}; + }; + + parser.suggestAnalyticFunctions = function () { + parser.yy.result.suggestAnalyticFunctions = true; + }; + + parser.suggestSetOptions = function () { + parser.yy.result.suggestSetOptions = true; + }; + + parser.suggestIdentifiers = function (identifiers) { + parser.yy.result.suggestIdentifiers = identifiers; + }; + + parser.suggestColumns = function (details) { + if (typeof details === 'undefined') { + details = {identifierChain: []}; + } else if (typeof details.identifierChain === 'undefined') { + details.identifierChain = []; + } + parser.yy.result.suggestColumns = details; + }; + + parser.suggestGroupBys = function (details) { + parser.yy.result.suggestGroupBys = details || {}; + }; + + parser.suggestOrderBys = function (details) { + parser.yy.result.suggestOrderBys = details || {}; + }; + + parser.suggestFilters = function (details) { + parser.yy.result.suggestFilters = details || {}; + }; + + parser.suggestKeyValues = function (details) { + parser.yy.result.suggestKeyValues = details || {}; + }; + + parser.suggestTables = function (details) { + parser.yy.result.suggestTables = details || {}; + }; + + var adjustLocationForCursor = function (location) { + // columns are 0-based and lines not, so add 1 to cols + var newLocation = { + first_line: location.first_line, + last_line: location.last_line, + first_column: location.first_column + 1, + last_column: location.last_column + 1 + }; + if (parser.yy.cursorFound) { + if (parser.yy.cursorFound.first_line === newLocation.first_line && parser.yy.cursorFound.last_column <= newLocation.first_column) { + var additionalSpace = parser.yy.partialLengths.left + parser.yy.partialLengths.right; + additionalSpace -= parser.yy.partialCursor ? 1 : 3; // For some reason the normal cursor eats 3 positions. + newLocation.first_column = newLocation.first_column + additionalSpace; + newLocation.last_column = newLocation.last_column + additionalSpace; + } + } + return newLocation; + }; + + parser.addFunctionLocation = function (location, functionName) { + // Remove trailing '(' from location + var adjustedLocation = { + first_line: location.first_line, + last_line: location.last_line, + first_column: location.first_column, + last_column: location.last_column - 1 + }; + parser.yy.locations.push({ + type: 'function', + location: adjustLocationForCursor(adjustedLocation), + function: functionName.toLowerCase() + }); + }; + + parser.addStatementLocation = function (location) { + // Don't report lonely cursor as a statement + if (location.first_line === location.last_line && Math.abs(location.last_column - location.first_column) === 1) { + return; + } + var adjustedLocation; + if (parser.yy.cursorFound && parser.yy.cursorFound.last_line === location.last_line && + parser.yy.cursorFound.first_column >= location.first_column && parser.yy.cursorFound.last_column <= location.last_column) { + var additionalSpace = parser.yy.partialLengths.left + parser.yy.partialLengths.right; + adjustedLocation = { + first_line: location.first_line, + last_line: location.last_line, + first_column: location.first_column + 1, + last_column: location.last_column + additionalSpace - (parser.yy.partialCursor ? 0 : 2) + } + } else { + adjustedLocation = { + first_line: location.first_line, + last_line: location.last_line, + first_column: location.first_column + 1, + last_column: location.last_column + 1 + } + } + + parser.yy.locations.push({ + type: 'statement', + location: adjustedLocation + }); + }; + + parser.firstDefined = function () { + for (var i = 0; i + 1 < arguments.length; i += 2) { + if (arguments[i]) { + return arguments[i + 1]; + } + } + }; + + parser.addClauseLocation = function (type, precedingLocation, locationIfPresent, isCursor) { + var location; + if (isCursor) { + if (parser.yy.partialLengths.left === 0 && parser.yy.partialLengths.right === 0) { + location = { + type: type, + missing: true, + location: adjustLocationForCursor({ + first_line: precedingLocation.last_line, + first_column: precedingLocation.last_column, + last_line: precedingLocation.last_line, + last_column: precedingLocation.last_column + }) + } + } else { + location = { + type: type, + missing: false, + location: { + first_line: locationIfPresent.last_line, + first_column: locationIfPresent.last_column - 1, + last_line: locationIfPresent.last_line, + last_column: locationIfPresent.last_column - 1 + parser.yy.partialLengths.right + parser.yy.partialLengths.left + } + } + } + } else { + location = { + type: type, + missing: !locationIfPresent, + location: adjustLocationForCursor(locationIfPresent || { + first_line: precedingLocation.last_line, + first_column: precedingLocation.last_column, + last_line: precedingLocation.last_line, + last_column: precedingLocation.last_column + }) + }; + } + if (parser.isInSubquery()) { + location.subquery = true; + } + parser.yy.locations.push(location) + }; + + parser.addStatementTypeLocation = function (identifier, location, additionalText) { + if (!parser.isImpala()) { + return; + } + var loc = { + type: 'statementType', + location: adjustLocationForCursor(location), + identifier: identifier + }; + if (typeof additionalText !== 'undefined') { + switch (identifier) { + case 'ALTER': + if (/ALTER\s+VIEW/i.test(additionalText)) { + loc.identifier = 'ALTER VIEW'; + } else { + loc.identifier = 'ALTER TABLE'; + } + break; + case 'COMPUTE': + loc.identifier = 'COMPUTE STATS'; + break; + case 'CREATE': + if (/CREATE\s+VIEW/i.test(additionalText)) { + loc.identifier = 'CREATE VIEW'; + } else if (/CREATE\s+TABLE/i.test(additionalText)) { + loc.identifier = 'CREATE TABLE'; + } else if (/CREATE\s+DATABASE/i.test(additionalText)) { + loc.identifier = 'CREATE DATABASE'; + } else if (/CREATE\s+ROLE/i.test(additionalText)) { + loc.identifier = 'CREATE ROLE'; + } else if (/CREATE\s+FUNCTION/i.test(additionalText)) { + loc.identifier = 'CREATE FUNCTION'; + } else { + loc.identifier = 'CREATE TABLE'; + } + break; + case 'DROP': + if (/DROP\s+VIEW/i.test(additionalText)) { + loc.identifier = 'DROP VIEW'; + } else if (/DROP\s+TABLE/i.test(additionalText)) { + loc.identifier = 'DROP TABLE'; + } else if (/DROP\s+DATABASE/i.test(additionalText)) { + loc.identifier = 'DROP DATABASE'; + } else if (/DROP\s+ROLE/i.test(additionalText)) { + loc.identifier = 'DROP ROLE'; + } else if (/DROP\s+STATS/i.test(additionalText)) { + loc.identifier = 'DROP STATS'; + } else if (/DROP\s+FUNCTION/i.test(additionalText)) { + loc.identifier = 'DROP FUNCTION'; + } else { + loc.identifier = 'DROP TABLE'; + } + break; + case 'INVALIDATE': + loc.identifier = 'INVALIDATE METADATA'; + break; + case 'LOAD': + loc.identifier = 'LOAD DATA'; + break; + case 'TRUNCATE': + loc.identifier = 'TRUNCATE TABLE'; + break; + default: + } + } + parser.yy.locations.push(loc); + }; + + parser.addFileLocation = function (location, path) { + parser.yy.locations.push({ + type: 'file', + location: adjustLocationForCursor(location), + path: path + }); + }; + + parser.addDatabaseLocation = function (location, identifierChain) { + parser.yy.locations.push({ + type: 'database', + location: adjustLocationForCursor(location), + identifierChain: identifierChain + }); + }; + + parser.addTableLocation = function (location, identifierChain) { + parser.yy.locations.push({ + type: 'table', + location: adjustLocationForCursor(location), + identifierChain: identifierChain + }); + }; + + parser.addColumnAliasLocation = function (location, alias, parentLocation) { + var aliasLocation = { + type: 'alias', + source: 'column', + alias: alias, + location: adjustLocationForCursor(location), + parentLocation: adjustLocationForCursor(parentLocation) + }; + if (parser.yy.locations.length && parser.yy.locations[parser.yy.locations.length - 1].type === 'column') { + var closestColumn = parser.yy.locations[parser.yy.locations.length - 1]; + if (closestColumn.location.first_line === aliasLocation.parentLocation.first_line && + closestColumn.location.last_line === aliasLocation.parentLocation.last_line && + closestColumn.location.first_column === aliasLocation.parentLocation.first_column && + closestColumn.location.last_column === aliasLocation.parentLocation.last_column) { + parser.yy.locations[parser.yy.locations.length - 1].alias = alias; + } + } + parser.yy.locations.push(aliasLocation); + }; + + parser.addTableAliasLocation = function (location, alias, identifierChain) { + parser.yy.locations.push({ + type: 'alias', + source: 'table', + alias: alias, + location: adjustLocationForCursor(location), + identifierChain: identifierChain + }); + }; + + parser.addSubqueryAliasLocation = function (location, alias) { + parser.yy.locations.push({ + type: 'alias', + source: 'subquery', + alias: alias, + location: adjustLocationForCursor(location) + }); + }; + + parser.addAsteriskLocation = function (location, identifierChain) { + parser.yy.locations.push({ + type: 'asterisk', + location: adjustLocationForCursor(location), + identifierChain: identifierChain + }); + }; + + parser.addVariableLocation = function (location, value) { + if (/\$\{[^}]*\}/.test(value)) { + parser.yy.locations.push({ + type: 'variable', + location: adjustLocationForCursor(location), + value: value + }); + } + }; + + parser.addColumnLocation = function (location, identifierChain) { + var isVariable = identifierChain.length && /\$\{[^}]*\}/.test(identifierChain[identifierChain.length - 1].name); + if (isVariable) { + parser.yy.locations.push({ + type: 'variable', + location: adjustLocationForCursor(location), + value: identifierChain[identifierChain.length - 1].name + }); + } else { + parser.yy.locations.push({ + type: 'column', + location: adjustLocationForCursor(location), + identifierChain: identifierChain, + qualified: identifierChain.length > 1 + }); + } + }; + + parser.addCteAliasLocation = function (location, alias) { + parser.yy.locations.push({ + type: 'alias', + source: 'cte', + alias: alias, + location: adjustLocationForCursor(location) + }); + }; + + parser.addUnknownLocation = function (location, identifierChain) { + var isVariable = identifierChain.length && /\$\{[^}]*\}/.test(identifierChain[identifierChain.length - 1].name); + var loc; + if (isVariable) { + loc = { + type: 'variable', + location: adjustLocationForCursor(location), + value: identifierChain[identifierChain.length - 1].name + }; + } else { + loc = { + type: 'unknown', + location: adjustLocationForCursor(location), + identifierChain: identifierChain, + qualified: identifierChain.length > 1 + }; + } + parser.yy.locations.push(loc); + return loc; + }; + + parser.addColRefToVariableIfExists = function (left, right) { + if (left && left.columnReference && left.columnReference.length && right && right.columnReference && right.columnReference.length && parser.yy.locations.length > 1) { + var addColRefToVariableLocation = function (variableValue, colRef) { + // See if colref is actually an alias + if (colRef.length === 1 && colRef[0].name) { + parser.yy.locations.some(function (location) { + if (location.type === 'column' && location.alias === colRef[0].name) { + colRef = location.identifierChain; + return true; + } + }); + } + + for (var i = parser.yy.locations.length - 1; i > 0; i--) { + var location = parser.yy.locations[i]; + if (location.type === 'variable' && location.value === variableValue) { + location.colRef = { identifierChain: colRef }; + break; + } + } + }; + + if (/\$\{[^}]*\}/.test(left.columnReference[0].name)) { + // left is variable + addColRefToVariableLocation(left.columnReference[0].name, right.columnReference); + } else if (/\$\{[^}]*\}/.test(right.columnReference[0].name)) { + // right is variable + addColRefToVariableLocation(right.columnReference[0].name, left.columnReference); + } + } + }; + + parser.suggestDatabases = function (details) { + parser.yy.result.suggestDatabases = details || {}; + }; + + parser.suggestHdfs = function (details) { + parser.yy.result.suggestHdfs = details || {}; + }; + + parser.suggestValues = function (details) { + parser.yy.result.suggestValues = details || {}; + }; + + parser.determineCase = function (text) { + if (!parser.yy.caseDetermined) { + parser.yy.lowerCase = text.toLowerCase() === text; + parser.yy.caseDetermined = true; + } + }; + + parser.handleQuotedValueWithCursor = function (lexer, yytext, yylloc, quoteChar) { + if (yytext.indexOf('\u2020') !== -1 || yytext.indexOf('\u2021') !== -1) { + parser.yy.partialCursor = yytext.indexOf('\u2021') !== -1; + var cursorIndex = parser.yy.partialCursor ? yytext.indexOf('\u2021') : yytext.indexOf('\u2020'); + parser.yy.cursorFound = { + first_line: yylloc.first_line, + last_line: yylloc.last_line, + first_column: yylloc.first_column + cursorIndex, + last_column: yylloc.first_column + cursorIndex + 1 + }; + var remainder = yytext.substring(cursorIndex + 1); + var remainingQuotes = (lexer.upcomingInput().match(new RegExp(quoteChar, 'g')) || []).length; + if (remainingQuotes > 0 && remainingQuotes & 1 != 0) { + parser.yy.missingEndQuote = false; + lexer.input(); + } else { + parser.yy.missingEndQuote = true; + lexer.unput(remainder); + } + lexer.popState(); + return true; + } + return false; + }; + + var lexerModified = false; + + /** + * Main parser function + */ + parser.parseSql = function (beforeCursor, afterCursor, dialect, debug) { + // Jison counts CRLF as two lines in the locations + beforeCursor = beforeCursor.replace(/\r\n|\n\r/gm, '\n'); + afterCursor = afterCursor.replace(/\r\n|\n\r/gm, '\n'); + parser.yy.result = {locations: []}; + parser.yy.lowerCase = false; + parser.yy.locations = []; + parser.yy.allLocations = []; + parser.yy.subQueries = []; + parser.yy.errors = []; + parser.yy.selectListAliases = []; + + parser.yy.locationsStack = []; + parser.yy.primariesStack = []; + parser.yy.lateralViewsStack = []; + parser.yy.subQueriesStack = []; + parser.yy.resultStack = []; + parser.yy.selectListAliasesStack = []; + + delete parser.yy.caseDetermined; + delete parser.yy.cursorFound; + delete parser.yy.partialCursor; + + parser.prepareNewStatement(); + + var REASONABLE_SURROUNDING_LENGTH = 150000; // About 3000 lines before and after + + if (beforeCursor.length > REASONABLE_SURROUNDING_LENGTH) { + if ((beforeCursor.length - beforeCursor.lastIndexOf(';')) > REASONABLE_SURROUNDING_LENGTH) { + // Bail out if the last complete statement is more than 150000 chars before + return {}; + } + // Cut it at the first statement found within 150000 chars before + var lastReasonableChunk = beforeCursor.substring(beforeCursor.length - REASONABLE_SURROUNDING_LENGTH); + beforeCursor = lastReasonableChunk.substring(lastReasonableChunk.indexOf(';') + 1); + } + + if (afterCursor.length > REASONABLE_SURROUNDING_LENGTH) { + if ((afterCursor.length - afterCursor.indexOf(';')) > REASONABLE_SURROUNDING_LENGTH) { + // No need to bail out for what's comes after, we can still get keyword completion + afterCursor = ''; + } else { + // Cut it at the last statement found within 150000 chars after + var firstReasonableChunk = afterCursor.substring(0, REASONABLE_SURROUNDING_LENGTH); + afterCursor = firstReasonableChunk.substring(0, firstReasonableChunk.lastIndexOf(';')); + } + } + + parser.yy.partialLengths = parser.identifyPartials(beforeCursor, afterCursor); + + if (parser.yy.partialLengths.left > 0) { + beforeCursor = beforeCursor.substring(0, beforeCursor.length - parser.yy.partialLengths.left); + } + + if (parser.yy.partialLengths.right > 0) { + afterCursor = afterCursor.substring(parser.yy.partialLengths.right); + } + + parser.yy.activeDialect = (dialect !== 'hive' && dialect !== 'impala') ? undefined : dialect; + + // Hack to set the inital state of the lexer without first having to hit a token + // has to be done as the first token found can be dependant on dialect + if (!lexerModified) { + var originalSetInput = parser.lexer.setInput; + parser.lexer.setInput = function (input, yy) { + var lexer = originalSetInput.bind(parser.lexer)(input, yy); + if (typeof parser.yy.activeDialect !== 'undefined') { + lexer.begin(parser.yy.activeDialect); + } + return lexer; + }; + lexerModified = true; + } + + var result; + try { + // Add |CURSOR| or |PARTIAL_CURSOR| to represent the different cursor states in the lexer + result = parser.parse(beforeCursor + (beforeCursor.length == 0 || /[\s\(]$$/.test(beforeCursor) ? ' \u2020 ' : '\u2021') + afterCursor); + } catch (err) { + // On any error try to at least return any existing result + if (typeof parser.yy.result === 'undefined') { + throw err; + } + if (debug) { + console.log(err); + console.error(err.stack); + } + result = parser.yy.result; + } + if (parser.yy.errors.length > 0) { + parser.yy.result.errors = parser.yy.errors; + if (debug) { + console.log(parser.yy.errors); + } + } + try { + linkTablePrimaries(); + parser.commitLocations(); + // Clean up and prioritize + prioritizeSuggestions(); + } catch (err) { + if (debug) { + console.log(err); + console.error(err.stack); + } + } + + + parser.yy.allLocations.sort(function (a, b) { + if (a.location.first_line !== b.location.first_line) { + return a.location.first_line - b.location.first_line; + } + if (a.location.first_column !== b.location.first_column) { + return a.location.first_column - b.location.first_column; + } + if (a.location.last_column !== b.location.last_column) { + return b.location.last_column - a.location.last_column; + } + return b.type.localeCompare(a.type); + }); + parser.yy.result.locations = parser.yy.allLocations; + + parser.yy.result.locations.forEach(function (location) { + delete location.linked; + }); + if (typeof parser.yy.result.suggestColumns !== 'undefined') { + delete parser.yy.result.suggestColumns.linked; + } + + SIMPLE_TABLE_REF_SUGGESTIONS.forEach(function (suggestionType) { + if (typeof parser.yy.result[suggestionType] !== 'undefined') { + delete parser.yy.result[suggestionType].linked; + } + }); + + if (typeof parser.yy.result.colRef !== 'undefined') { + delete parser.yy.result.colRef.linked; + } + if (typeof parser.yy.result.suggestKeyValues !== 'undefined') { + delete parser.yy.result.suggestKeyValues.linked; + } + + if (typeof result.error !== 'undefined' && typeof result.error.expected !== 'undefined') { + // Remove any expected tokens from other dialects, jison doesn't remove tokens from other lexer states. + var actualExpected = {}; + result.error.expected.forEach(function (expected) { + var match = expected.match(/\<([a-z]+)\>(.*)/); + if (match !== null) { + if (typeof parser.yy.activeDialect !== 'undefined' && parser.yy.activeDialect === match[1]) { + actualExpected[("'" + match[2])] = true; + } + } else if (expected.indexOf('CURSOR') == -1) { + actualExpected[expected] = true; + } + }); + result.error.expected = Object.keys(actualExpected); + } + + if (typeof result.error !== 'undefined' && result.error.recoverable) { + delete result.error; + } + + // Adjust all the statement locations to include white space surrounding them + var lastStatementLocation = null; + result.locations.forEach(function (location) { + if (location.type === 'statement') { + if (lastStatementLocation === null) { + location.location.first_line = 1; + location.location.first_column = 1; + } else { + location.location.first_line = lastStatementLocation.location.last_line; + location.location.first_column = lastStatementLocation.location.last_column + 1; + } + lastStatementLocation = location; + } + }); + + return result; + }; + }; + + var SYNTAX_PARSER_NOOP_FUNCTIONS = ['prepareNewStatement', 'addCommonTableExpressions', 'pushQueryState', 'popQueryState', 'suggestSelectListAliases', + 'suggestValueExpressionKeywords', 'getSelectListKeywords', 'getValueExpressionKeywords', 'addColRefIfExists', 'selectListNoTableSuggest', 'suggestJoinConditions', + 'suggestJoins', 'valueExpressionSuggest', 'applyTypeToSuggestions', 'applyArgumentTypesToSuggestions', 'commitLocations', 'identifyPartials', + 'getSubQuery', 'addTablePrimary', 'suggestFileFormats', 'suggestDdlAndDmlKeywords', 'checkForSelectListKeywords', 'checkForKeywords', + 'suggestKeywords', 'suggestColRefKeywords', 'suggestTablesOrColumns', 'suggestFunctions', 'suggestAggregateFunctions', 'suggestAnalyticFunctions', + 'suggestColumns', 'suggestGroupBys', 'suggestIdentifiers', 'suggestOrderBys', 'suggestFilters', 'suggestKeyValues', 'suggestTables', 'addFunctionLocation', + 'addStatementLocation', 'firstDefined', 'addClauseLocation', 'addStatementTypeLocation', 'addFileLocation', 'addDatabaseLocation', 'addColumnAliasLocation', + 'addTableAliasLocation', 'addSubqueryAliasLocation', 'addTableLocation', 'addAsteriskLocation', 'addVariableLocation', 'addColumnLocation', 'addCteAliasLocation', + 'addUnknownLocation', 'addColRefToVariableIfExists', 'suggestDatabases', 'suggestHdfs', 'suggestValues']; + + var SYNTAX_PARSER_NOOP = function () {}; + + var initSyntaxParser = function (parser) { + + // Noop functions for compatibility with the autocomplete parser as the grammar is shared + SYNTAX_PARSER_NOOP_FUNCTIONS.forEach(function (noopFn) { + parser[noopFn] = SYNTAX_PARSER_NOOP + }); + + parser.yy.locations = [{}]; + + parser.determineCase = function (text) { + if (!parser.yy.caseDetermined) { + parser.yy.lowerCase = text.toLowerCase() === text; + parser.yy.caseDetermined = true; + } + }; + + parser.getKeywordsForOptionalsLR = function () { + return []; + }; + + parser.mergeSuggestKeywords = function () { + return {}; + }; + + parser.getTypeKeywords = function () { + return []; + }; + + parser.getColumnDataTypeKeywords = function () { + return []; + }; + + parser.findCaseType = function () { + return {types: ['T']}; + }; + + parser.findReturnTypes = function (functionName) { + return ['T']; + }; + + parser.isHive = function () { + return parser.yy.activeDialect === 'hive'; + }; + + parser.isImpala = function () { + return parser.yy.activeDialect === 'impala'; + }; + + parser.expandImpalaIdentifierChain = function () { + return []; + }; + + parser.expandIdentifierChain = function () { + return []; + }; + + parser.expandLateralViews = function () { + return []; + }; + + parser.createWeightedKeywords = function () { + return []; + }; + + parser.handleQuotedValueWithCursor = function (lexer, yytext, yylloc, quoteChar) { + if (yytext.indexOf('\u2020') !== -1 || yytext.indexOf('\u2021') !== -1) { + parser.yy.partialCursor = yytext.indexOf('\u2021') !== -1; + var cursorIndex = parser.yy.partialCursor ? yytext.indexOf('\u2021') : yytext.indexOf('\u2020'); + parser.yy.cursorFound = { + first_line: yylloc.first_line, + last_line: yylloc.last_line, + first_column: yylloc.first_column + cursorIndex, + last_column: yylloc.first_column + cursorIndex + 1 + }; + var remainder = yytext.substring(cursorIndex + 1); + var remainingQuotes = (lexer.upcomingInput().match(new RegExp(quoteChar, 'g')) || []).length; + if (remainingQuotes > 0 && remainingQuotes & 1 != 0) { + parser.yy.missingEndQuote = false; + lexer.input(); + } else { + parser.yy.missingEndQuote = true; + lexer.unput(remainder); + } + lexer.popState(); + return true; + } + return false; + }; + + var lexerModified = false; + + parser.yy.parseError = function (str, hash) { + parser.yy.error = hash; + }; + + var IGNORED_EXPECTED = { + ';': true, + '.': true, + 'EOF': true, + 'UNSIGNED_INTEGER': true, + 'UNSIGNED_INTEGER_E': true, + 'REGULAR_IDENTIFIER': true, // TODO: Indicate that an identifier was expected + 'CURSOR': true, + 'PARTIAL_CURSOR': true, + 'HDFS_START_QUOTE': true, + 'HDFS_PATH': true, + 'HDFS_END_QUOTE' : true, + 'COMPARISON_OPERATOR': true, // TODO: Expand in results when found + 'ARITHMETIC_OPERATOR' : true, // TODO: Expand in results when found + 'VARIABLE_REFERENCE': true, + 'BACKTICK': true, + 'VALUE': true, + 'PARTIAL_VALUE': true, + 'SINGLE_QUOTE': true, + 'DOUBLE_QUOTE': true + }; + + var CLEAN_EXPECTED = { + 'BETWEEN_AND': 'AND', + 'OVERWRITE_DIRECTORY' : 'OVERWRITE', + 'STORED_AS_DIRECTORIES' : 'STORED', + 'LIKE_PARQUET' : 'LIKE', + 'PARTITION_VALUE' : 'PARTITION' + }; + + parser.parseSyntax = function (beforeCursor, afterCursor, dialect, debug) { + parser.yy.caseDetermined = false; + parser.yy.error = undefined; + + parser.yy.latestTablePrimaries = []; + parser.yy.subQueries = []; + parser.yy.selectListAliases = []; + parser.yy.latestTablePrimaries = []; + + parser.yy.activeDialect = (dialect !== 'hive' && dialect !== 'impala') ? undefined : dialect; + + // Hack to set the inital state of the lexer without first having to hit a token + // has to be done as the first token found can be dependant on dialect + if (!lexerModified) { + var originalSetInput = parser.lexer.setInput; + parser.lexer.setInput = function (input, yy) { + var lexer = originalSetInput.bind(parser.lexer)(input, yy); + if (typeof parser.yy.activeDialect !== 'undefined') { + lexer.begin(parser.yy.activeDialect); + } + return lexer; + }; + lexerModified = true; + } + + // TODO: Find a way around throwing an exception when the parser finds a syntax error + try { + parser.yy.error = false; + parser.parse(beforeCursor + afterCursor); + } catch (err) { + if (debug) { + console.log(err); + console.error(err.stack); + console.log(parser.yy.error); + } + } + + if (parser.yy.error && (parser.yy.error.loc.last_column < beforeCursor.length || !beforeCursor.endsWith(parser.yy.error.text))) { + var weightedExpected = []; + + var addedExpected = {}; + + var isLowerCase = parser.yy.caseDetermined && parser.yy.lowerCase || parser.yy.error.text.toLowerCase() === parser.yy.error.text; + + if (parser.yy.error.expected.length == 2 && parser.yy.error.expected.indexOf('\';\'') !== -1 && parser.yy.error.expected.indexOf('\'EOF\'') !== -1) { + parser.yy.error.expected = []; + parser.yy.error.expectedStatementEnd = true; + return parser.yy.error; + } + for (var i = 0; i < parser.yy.error.expected.length; i++) { + var expected = parser.yy.error.expected[i]; + // Strip away the surrounding ' chars + expected = expected.substring(1, expected.length - 1); + // TODO: Only suggest alphanumeric? + if (!IGNORED_EXPECTED[expected] && /[a-z_]+/i.test(expected)) { + if (dialect && expected.indexOf('<' + dialect + '>') == 0) { + expected = expected.substring(dialect.length + 2); + } else if (/^<[a-z]+>/.test(expected)) { + continue; + } + expected = CLEAN_EXPECTED[expected] || expected; + if (expected === parser.yy.error.text.toUpperCase()) { + // Can happen when the lexer entry for a rule contains multiple words like 'stored' in 'stored as parquet' + return false; + } + var text = isLowerCase ? expected.toLowerCase() : expected; + if (text && !addedExpected[text]) { + addedExpected[text] = true; + weightedExpected.push({ + text: text, + distance: stringDistance(parser.yy.error.text, text, true) + }); + } + } + } + if (weightedExpected.length === 0) { + parser.yy.error.expected = []; + parser.yy.error.incompleteStatement = true; + return parser.yy.error; + } + weightedExpected.sort(function (a, b) { + if (a.distance === b.distance) { + return a.text.localeCompare(b.text); + } + return a.distance - b.distance + }); + parser.yy.error.expected = weightedExpected; + parser.yy.error.incompleteStatement = true; + return parser.yy.error; + } else if (parser.yy.error) { + parser.yy.error.expected = []; + parser.yy.error.incompleteStatement = true; + return parser.yy.error; + } + return false; + } + }; + + var initGlobalSearchParser = function (parser) { + + parser.identifyPartials = function (beforeCursor, afterCursor) { + var beforeMatch = beforeCursor.match(/[0-9a-zA-Z_]*$/); + var afterMatch = afterCursor.match(/^[0-9a-zA-Z_]*(?:\((?:[^)]*\))?)?/); + return {left: beforeMatch ? beforeMatch[0].length : 0, right: afterMatch ? afterMatch[0].length : 0}; + }; + + parser.mergeFacets = function (a, b) { + if (!a.facets) { + a.facets = {}; + } + if (!b.facets) { + return; + } + Object.keys(b.facets).forEach(function (key) { + if (a.facets[key]) { + Object.keys(b.facets[key]).forEach(function (val) { + a.facets[key][val.toLowerCase()] = true; + }); + } else { + a.facets[key] = b.facets[key]; + } + }); + }; + + parser.mergeText = function (a, b) { + if (!a.text) { + a.text = []; + } + if (!b.text) { + return; + } + a.text = a.text.concat(b.text); + }; + + parser.handleQuotedValueWithCursor = function (lexer, yytext, yylloc, quoteChar) { + if (yytext.indexOf('\u2020') !== -1 || yytext.indexOf('\u2021') !== -1) { + var cursorIndex = yytext.indexOf('\u2020'); + parser.yy.cursorFound = { + first_line: yylloc.first_line, + last_line: yylloc.last_line, + first_column: yylloc.first_column + cursorIndex, + last_column: yylloc.first_column + cursorIndex + 1 + }; + var remainder = yytext.substring(cursorIndex + 1); + var remainingQuotes = (lexer.upcomingInput().match(new RegExp(quoteChar, 'g')) || []).length; + if (remainingQuotes > 0 && remainingQuotes & 1 != 0) { + parser.yy.missingEndQuote = false; + lexer.input(); + } else { + parser.yy.missingEndQuote = true; + lexer.unput(remainder); + } + lexer.popState(); + return true; + } + return false; + }; + + parser.parseGlobalSearch = function (beforeCursor, afterCursor, debug) { + delete parser.yy.cursorFound; + + var result; + try { + result = parser.parse(beforeCursor + '\u2020' + afterCursor); + } catch (err) { + if (debug) { + console.log(err); + console.error(err.stack); + console.log(parser.yy.error); + } + return { + facets: {}, + text: [] + } + } + return result; + }; + }; + + return { + initSqlParser: initSqlParser, + initSyntaxParser: initSyntaxParser, + stringDistance: stringDistance, + initGlobalSearchParser: initGlobalSearchParser + }; +})(); +/* 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 sqlSyntaxParser = (function(){ +var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[6,10,25,29,57,58,73,78,79,96,112,130,144,162,182,219,308,340,353,439,440,441,453,569,570,576,759,814,857,919,920,922,1158,1182,1183,1184,1185,1187,1205,1220,1245,1246,1272,1308],$V1=[2,4],$V2=[6,10],$V3=[2,5],$V4=[1,64],$V5=[1,44],$V6=[1,33],$V7=[1,99],$V8=[1,129],$V9=[1,138],$Va=[1,108],$Vb=[1,109],$Vc=[1,135],$Vd=[1,122],$Ve=[1,66],$Vf=[1,34],$Vg=[1,65],$Vh=[1,92],$Vi=[1,136],$Vj=[1,69],$Vk=[1,102],$Vl=[1,131],$Vm=[1,132],$Vn=[1,133],$Vo=[1,110],$Vp=[1,103],$Vq=[1,104],$Vr=[1,101],$Vs=[1,119],$Vt=[1,105],$Vu=[1,116],$Vv=[1,45],$Vw=[1,46],$Vx=[1,47],$Vy=[1,91],$Vz=[1,125],$VA=[1,100],$VB=[1,142],$VC=[1,67],$VD=[1,68],$VE=[1,126],$VF=[1,141],$VG=[1,130],$VH=[1,98],$VI=[1,134],$VJ=[1,121],$VK=[6,10,400,949],$VL=[2,865],$VM=[1,151],$VN=[1,153],$VO=[1,156],$VP=[25,29,58,73,78,79,96,112,130,144,182,219,308,340,353,439,440,441,453,569,570,576,759,814,857,919,920,922,1158,1182,1183,1184,1185,1187,1205,1220,1245,1246,1272,1308],$VQ=[1,170],$VR=[1,171],$VS=[1,172],$VT=[1,173],$VU=[1,174],$VV=[1,175],$VW=[1,176],$VX=[1,177],$VY=[1,178],$VZ=[1,179],$V_=[1,180],$V$=[1,181],$V01=[1,182],$V11=[1,183],$V21=[1,184],$V31=[1,185],$V41=[1,186],$V51=[1,187],$V61=[1,188],$V71=[1,189],$V81=[1,190],$V91=[1,191],$Va1=[1,192],$Vb1=[1,193],$Vc1=[1,194],$Vd1=[1,195],$Ve1=[1,196],$Vf1=[1,197],$Vg1=[1,198],$Vh1=[1,199],$Vi1=[1,200],$Vj1=[1,201],$Vk1=[1,202],$Vl1=[1,203],$Vm1=[1,204],$Vn1=[1,205],$Vo1=[1,206],$Vp1=[1,207],$Vq1=[1,208],$Vr1=[1,209],$Vs1=[1,210],$Vt1=[1,211],$Vu1=[1,212],$Vv1=[1,213],$Vw1=[1,214],$Vx1=[1,215],$Vy1=[1,216],$Vz1=[1,217],$VA1=[1,218],$VB1=[1,219],$VC1=[1,220],$VD1=[1,221],$VE1=[1,222],$VF1=[1,223],$VG1=[1,224],$VH1=[1,225],$VI1=[1,226],$VJ1=[1,227],$VK1=[1,228],$VL1=[1,229],$VM1=[1,230],$VN1=[1,231],$VO1=[1,232],$VP1=[1,233],$VQ1=[1,234],$VR1=[1,235],$VS1=[1,236],$VT1=[1,237],$VU1=[1,238],$VV1=[1,239],$VW1=[1,240],$VX1=[1,241],$VY1=[1,242],$VZ1=[1,243],$V_1=[1,244],$V$1=[1,245],$V02=[1,246],$V12=[1,247],$V22=[1,248],$V32=[1,249],$V42=[1,250],$V52=[1,251],$V62=[1,252],$V72=[1,253],$V82=[1,254],$V92=[1,255],$Va2=[1,256],$Vb2=[1,257],$Vc2=[1,258],$Vd2=[1,259],$Ve2=[1,260],$Vf2=[1,261],$Vg2=[1,262],$Vh2=[1,263],$Vi2=[1,264],$Vj2=[1,265],$Vk2=[1,266],$Vl2=[1,267],$Vm2=[1,268],$Vn2=[1,269],$Vo2=[1,270],$Vp2=[1,271],$Vq2=[1,272],$Vr2=[1,273],$Vs2=[1,274],$Vt2=[1,275],$Vu2=[1,276],$Vv2=[1,277],$Vw2=[1,278],$Vx2=[1,279],$Vy2=[1,280],$Vz2=[1,281],$VA2=[1,282],$VB2=[1,283],$VC2=[1,284],$VD2=[1,285],$VE2=[1,286],$VF2=[1,287],$VG2=[1,288],$VH2=[1,289],$VI2=[1,290],$VJ2=[1,291],$VK2=[1,292],$VL2=[1,293],$VM2=[1,294],$VN2=[1,295],$VO2=[1,296],$VP2=[1,297],$VQ2=[1,298],$VR2=[1,299],$VS2=[1,300],$VT2=[1,301],$VU2=[1,302],$VV2=[1,167],$VW2=[1,168],$VX2=[1,166],$VY2=[1,323],$VZ2=[1,321],$V_2=[1,322],$V$2=[1,320],$V03=[1,318],$V13=[1,314],$V23=[1,317],$V33=[1,319],$V43=[1,316],$V53=[1,313],$V63=[1,315],$V73=[1,326],$V83=[1,328],$V93=[1,332],$Va3=[1,327],$Vb3=[1,329],$Vc3=[1,331],$Vd3=[1,330],$Ve3=[1,356],$Vf3=[25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,168,208,237,261,282,286,293,304,305,312,322,323,324,347,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,371,372,373,374,375,376,377,378,379,380,381,382,383,384,392,393,396,397,398,399,403,404,405,758,759,789],$Vg3=[2,900],$Vh3=[1,371],$Vi3=[1,372],$Vj3=[1,373],$Vk3=[25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,403],$Vl3=[1,384],$Vm3=[1,382],$Vn3=[1,383],$Vo3=[2,631],$Vp3=[1,387],$Vq3=[1,388],$Vr3=[1,396],$Vs3=[1,394],$Vt3=[1,395],$Vu3=[1,393],$Vv3=[1,397],$Vw3=[1,406],$Vx3=[1,433],$Vy3=[1,426],$Vz3=[1,422],$VA3=[1,421],$VB3=[1,432],$VC3=[1,431],$VD3=[1,438],$VE3=[1,436],$VF3=[1,435],$VG3=[1,439],$VH3=[1,434],$VI3=[1,407],$VJ3=[1,444],$VK3=[1,443],$VL3=[178,193,223,263,343],$VM3=[1,457],$VN3=[1,458],$VO3=[1,459],$VP3=[1,512],$VQ3=[1,513],$VR3=[25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160],$VS3=[1,519],$VT3=[1,522],$VU3=[1,523],$VV3=[44,217],$VW3=[105,121,132,146,156,178,181,193,197,202,211,223,230,263,297,338,343,1093],$VX3=[38,41,45,64,75,90,105,106,107,119,120,127,142,143,144,146,147,171,174,182,193,196,197,198,206,211,216,218,225,231,248,251,257,264,440,441],$VY3=[268,274,349,576],$VZ3=[6,10,348,400,949],$V_3=[2,663],$V$3=[6,10,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,167,170,176,184,188,204,207,213,232,243,245,259,265,266,267,268,270,274,275,276,287,295,308,309,310,311,312,314,318,319,321,323,325,326,327,329,331,334,336,339,340,348,349,352,353,395,399,400,403,446,453,544,576,652,659,758,814,825,857,895,897,899,949,1182],$V04=[1,551],$V14=[1,550],$V24=[1,549],$V34=[6,10,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,164,167,168,170,175,176,180,183,184,188,189,194,195,204,207,208,209,210,213,214,232,234,240,243,245,247,250,251,252,255,259,265,266,267,268,270,274,275,276,282,283,284,286,287,288,289,290,291,294,295,298,300,301,302,303,306,308,309,310,311,312,313,314,315,317,318,319,320,321,322,323,324,325,326,327,329,331,332,333,334,335,336,337,339,340,341,342,344,345,346,348,349,350,351,352,353,386,387,388,389,390,391,392,393,394,395,396,399,400,403,404,446,453,544,576,652,659,664,758,814,825,857,895,897,899,949,967,998,1182],$V44=[1,553],$V54=[1,552],$V64=[6,10,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,164,167,168,170,175,176,180,183,184,188,189,194,195,204,205,207,208,209,210,213,214,232,234,240,243,245,247,250,251,252,255,259,265,266,267,268,270,274,275,276,282,283,284,286,287,288,289,290,291,294,295,298,300,301,302,303,306,308,309,310,311,312,313,314,315,317,318,319,320,321,322,323,324,325,326,327,329,331,332,333,334,335,336,337,339,340,341,342,344,345,346,348,349,350,351,352,353,386,387,388,389,390,391,392,393,394,395,396,399,400,403,404,446,453,544,576,652,659,664,758,814,825,857,895,897,899,944,949,967,998,1182],$V74=[2,33],$V84=[2,111],$V94=[2,152],$Va4=[1,561],$Vb4=[1,563],$Vc4=[1,566],$Vd4=[1,565],$Ve4=[2,2766],$Vf4=[1,568],$Vg4=[308,325,395,825],$Vh4=[6,10,308,395,825],$Vi4=[2,692],$Vj4=[1,572],$Vk4=[308,325,395,399,825],$Vl4=[2,2805],$Vm4=[308,395],$Vn4=[208,282,388,396],$Vo4=[6,10,170,176,184,207,232,243,308,310,311,321,326,348,352,395,400,446,576,652,659,949,1182],$Vp4=[1,596],$Vq4=[1,597],$Vr4=[1,601],$Vs4=[1,598],$Vt4=[1,595],$Vu4=[1,602],$Vv4=[1,599],$Vw4=[1,603],$Vx4=[1,600],$Vy4=[6,10,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,167,170,176,184,207,232,243,265,266,267,287,295,308,309,310,311,314,318,319,321,325,326,327,334,339,348,352,395,400,403,446,576,652,659,949,1182],$Vz4=[6,10,170,176,184,207,232,243,265,266,267,295,308,309,310,311,314,318,319,321,325,326,327,334,339,348,352,395,400,446,576,652,659,949,1182],$VA4=[2,1371],$VB4=[353,576],$VC4=[2,1349],$VD4=[65,239],$VE4=[65,185,239],$VF4=[2,1453],$VG4=[6,10,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,164,188,329,340,399,403],$VH4=[25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,168,208,237,282,286,293,304,305,312,322,323,324,347,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,371,372,373,374,375,376,377,378,379,380,381,382,383,384,392,393,396,397,398,399,403,404,405,758,759,789],$VI4=[2,886],$VJ4=[1,622],$VK4=[25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,168,208,237,261,282,286,293,304,305,312,322,323,324,347,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,371,372,373,374,375,376,377,378,379,380,381,382,383,384,392,393,396,397,398,399,400,403,404,405,576,758,759,789],$VL4=[308,395,399,576,1182,1184,1220],$VM4=[2,623],$VN4=[1,627],$VO4=[6,10,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,164,312,403],$VP4=[25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,312,403],$VQ4=[188,251,329],$VR4=[2,656],$VS4=[2,1883],$VT4=[1,637],$VU4=[38,172,188,251,312,329,887],$VV4=[1,662],$VW4=[1,670],$VX4=[1,657],$VY4=[1,667],$VZ4=[1,665],$V_4=[1,669],$V$4=[1,671],$V05=[1,668],$V15=[1,666],$V25=[1,660],$V35=[1,661],$V45=[1,663],$V55=[2,653],$V65=[1,677],$V75=[1,681],$V85=[1,682],$V95=[2,1891],$Va5=[188,329],$Vb5=[82,83],$Vc5=[25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,403,848],$Vd5=[292,399],$Ve5=[38,887],$Vf5=[25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,168,175,212,241,252,269,271,272,278,290,291,294,298,300,306,315,341,342,345,346,350,353,399,403,576,1032],$Vg5=[193,263,343],$Vh5=[1,728],$Vi5=[1,729],$Vj5=[6,10,325],$Vk5=[6,10,320,404],$Vl5=[2,660],$Vm5=[1,756],$Vn5=[6,10,320],$Vo5=[193,263,343,1093],$Vp5=[6,10,313,320,404],$Vq5=[2,931],$Vr5=[1,766],$Vs5=[6,10,1182],$Vt5=[2,2962],$Vu5=[1,770],$Vv5=[1,774],$Vw5=[1,796],$Vx5=[1,805],$Vy5=[1,795],$Vz5=[1,785],$VA5=[1,783],$VB5=[1,824],$VC5=[1,794],$VD5=[1,797],$VE5=[1,779],$VF5=[1,790],$VG5=[1,823],$VH5=[1,826],$VI5=[1,813],$VJ5=[1,820],$VK5=[1,837],$VL5=[1,838],$VM5=[1,835],$VN5=[1,836],$VO5=[1,821],$VP5=[1,843],$VQ5=[1,846],$VR5=[1,847],$VS5=[1,827],$VT5=[1,828],$VU5=[1,829],$VV5=[1,830],$VW5=[1,831],$VX5=[1,833],$VY5=[1,840],$VZ5=[1,841],$V_5=[1,842],$V$5=[1,825],$V06=[1,815],$V16=[1,832],$V26=[1,839],$V36=[1,834],$V46=[1,844],$V56=[1,845],$V66=[1,812],$V76=[1,782],$V86=[1,781],$V96=[1,780],$Va6=[1,784],$Vb6=[1,798],$Vc6=[1,799],$Vd6=[1,814],$Ve6=[6,10,170,176,184,207,232,243,310,311,321,326,348,352,400,446,576,652,659,949,1182],$Vf6=[6,10,170,176,184,207,232,243,310,311,321,326,348,352,395,400,446,576,652,659,949,1182],$Vg6=[1,853],$Vh6=[2,2994],$Vi6=[1,856],$Vj6=[25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,263,403],$Vk6=[6,10,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,167,170,176,183,184,194,195,207,210,213,232,234,240,243,245,247,250,251,259,267,275,276,284,287,288,289,295,301,302,303,308,309,310,311,313,314,317,318,319,320,321,323,324,326,327,332,333,334,335,336,337,339,344,348,351,352,353,383,384,386,387,388,389,390,391,392,393,394,395,400,403,446,453,544,576,652,659,664,949,1182],$Vl6=[6,10,395],$Vm6=[6,10,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,167,170,176,183,184,194,195,207,210,213,232,234,240,243,245,247,250,251,259,267,275,276,284,287,288,289,295,301,302,303,308,309,310,311,313,314,317,318,319,320,321,323,324,326,327,332,333,334,335,336,337,339,344,348,351,352,353,386,387,388,389,390,391,392,393,394,395,400,403,446,453,544,576,652,659,664,949,1182],$Vn6=[2,1209],$Vo6=[1,869],$Vp6=[1,882],$Vq6=[1,880],$Vr6=[1,881],$Vs6=[1,892],$Vt6=[1,891],$Vu6=[1,890],$Vv6=[1,889],$Vw6=[1,907],$Vx6=[1,908],$Vy6=[1,906],$Vz6=[1,910],$VA6=[1,911],$VB6=[25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,399,403],$VC6=[2,1265],$VD6=[1,918],$VE6=[1,917],$VF6=[25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,274,280,399,403],$VG6=[6,10,170,176,184,207,232,243,266,267,295,308,309,310,311,314,318,319,321,325,326,327,334,339,348,352,395,400,446,576,652,659,949,1182],$VH6=[2,1341],$VI6=[1,939],$VJ6=[1,967],$VK6=[1,991],$VL6=[1,992],$VM6=[1,993],$VN6=[1,994],$VO6=[1,995],$VP6=[1,996],$VQ6=[1,997],$VR6=[1,998],$VS6=[1,999],$VT6=[1,1001],$VU6=[1,1002],$VV6=[1,1003],$VW6=[1,1004],$VX6=[1,1000],$VY6=[1,1006],$VZ6=[2,754],$V_6=[1,1011],$V$6=[31,66,84,88,94,108,123,212,241,269,271,272,278,1032],$V07=[6,10,353],$V17=[6,10,28,34,36,39,62,68,74,85,89,104,113,116,120,151,152,153,154,167,213,245,250,259,270,275,276,287,313,323,324,329,336,353,386,388,390,395,400,453,544,576,944,949],$V27=[2,1892],$V37=[1,1038],$V47=[6,10,36,39,74,89,113,116,120,167,213,245,259,270,275,276,287,320,329,336,353,399,453,544,949,967],$V57=[6,10,208],$V67=[6,10,170,176,207,243,311,321,326,348,400,652,659,949,1182],$V77=[6,10,170,176,207,232,243,310,311,321,326,348,400,446,652,659,949,1182],$V87=[116,275,353,576],$V97=[2,2953],$Va7=[1,1114],$Vb7=[1,1134],$Vc7=[1,1135],$Vd7=[1,1125],$Ve7=[1,1124],$Vf7=[1,1118],$Vg7=[1,1133],$Vh7=[1,1123],$Vi7=[1,1137],$Vj7=[1,1136],$Vk7=[1,1138],$Vl7=[1,1127],$Vm7=[1,1126],$Vn7=[1,1119],$Vo7=[1,1120],$Vp7=[1,1121],$Vq7=[1,1122],$Vr7=[1,1128],$Vs7=[1,1129],$Vt7=[1,1130],$Vu7=[6,10,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,167,170,176,183,184,194,195,207,210,232,234,240,243,247,251,267,284,287,288,289,295,301,302,303,308,309,310,311,313,314,317,318,319,320,321,323,326,327,332,333,334,335,337,339,344,348,351,352,353,386,387,388,389,390,391,392,393,394,395,400,403,446,576,652,659,664,949,1182],$Vv7=[1,1149],$Vw7=[6,10,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,167,170,176,183,184,194,195,207,210,232,234,240,243,247,250,251,267,284,287,288,289,295,301,302,303,308,309,310,311,313,314,317,318,319,320,321,323,324,326,327,332,333,334,335,337,339,344,348,351,352,353,386,387,388,389,390,391,392,393,394,395,400,403,446,453,576,652,659,664,949,1182],$Vx7=[1,1151],$Vy7=[6,10,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,167,170,176,183,184,194,195,207,210,232,234,240,243,247,250,251,267,284,287,288,289,295,301,302,303,308,309,310,311,313,314,317,318,319,320,321,323,324,326,327,332,333,334,335,337,339,344,348,351,352,353,386,387,388,389,390,391,392,393,394,395,399,400,403,446,453,576,652,659,664,949,1182],$Vz7=[1,1156],$VA7=[6,10,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,167,170,176,183,184,194,195,207,208,210,232,234,240,243,247,250,251,267,282,284,287,288,289,295,301,302,303,308,309,310,311,313,314,317,318,319,320,321,323,324,326,327,332,333,334,335,337,339,344,348,351,352,353,386,387,388,389,390,391,392,393,394,395,396,399,400,403,446,453,576,652,659,664,949,1182],$VB7=[6,10,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,167,170,176,183,184,194,195,207,210,232,234,240,243,247,250,251,267,284,287,288,289,295,301,302,303,308,309,310,311,313,314,317,318,319,320,321,323,324,326,327,328,332,333,334,335,337,339,344,348,351,352,353,386,387,388,389,390,391,392,393,394,395,400,403,446,453,576,652,659,664,949,1182],$VC7=[6,10,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,167,168,170,175,176,183,184,188,194,195,207,208,210,232,234,240,243,247,250,251,252,267,282,284,286,287,288,289,290,291,294,295,298,300,301,302,303,306,308,309,310,311,313,314,315,317,318,319,320,321,322,323,324,326,327,329,332,333,334,335,337,339,340,341,342,344,345,346,348,350,351,352,353,386,387,388,389,390,391,392,393,394,395,396,399,400,403,446,453,576,652,659,664,857,949,1182],$VD7=[1,1185],$VE7=[2,1210],$VF7=[1,1189],$VG7=[308,825],$VH7=[2,2833],$VI7=[1,1197],$VJ7=[1,1196],$VK7=[6,10,353,395],$VL7=[1,1203],$VM7=[6,10,243,321,348,395,400,652,659,949,1182],$VN7=[6,10,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,167,287,949],$VO7=[6,10,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,167,170,176,183,184,194,195,207,210,232,234,240,243,247,251,265,266,267,284,287,288,289,295,301,302,303,308,309,310,311,313,314,317,318,319,320,321,323,325,326,327,332,333,334,335,337,339,344,348,351,352,353,386,387,388,389,390,391,392,393,394,395,400,403,446,576,652,659,664,949,1182],$VP7=[6,10,352],$VQ7=[1,1246],$VR7=[6,10,308,351,352,395],$VS7=[39,388,395,400,453],$VT7=[1,1251],$VU7=[6,10,170,176,207,232,243,308,310,311,321,326,348,352,395,400,446,652,659,949,1182],$VV7=[6,10,188,208,282,329,396],$VW7=[6,10,188,213,329,544],$VX7=[2,743],$VY7=[1,1268],$VZ7=[1,1269],$V_7=[6,10,39,74,120,167,213,245,276,287,353,453,544,576,949],$V$7=[2,2387],$V08=[1,1284],$V18=[6,10,167,287,949],$V28=[1,1287],$V38=[6,10,93,395],$V48=[6,10,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,167,170,176,183,184,188,194,195,205,207,210,213,215,221,226,232,234,236,240,243,244,245,246,247,249,250,251,258,259,267,270,275,276,279,284,287,288,289,295,301,302,303,308,309,310,311,313,314,317,318,319,320,321,322,323,324,326,327,329,332,333,334,335,336,337,339,344,348,351,352,353,386,387,388,389,390,391,392,393,394,395,400,403,446,453,544,576,652,659,664,944,949,1182],$V58=[6,10,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,167,170,176,183,184,194,195,207,210,213,232,234,240,243,245,247,250,251,259,267,270,275,276,284,287,288,289,295,301,302,303,308,309,310,311,313,314,317,318,319,320,321,323,324,326,327,329,332,333,334,335,336,337,339,344,348,351,352,353,386,387,388,389,390,391,392,393,394,395,400,403,446,453,544,576,652,659,664,944,949,1182],$V68=[1,1304],$V78=[395,400],$V88=[2,648],$V98=[1,1313],$Va8=[1,1314],$Vb8=[2,2052],$Vc8=[1,1323],$Vd8=[1,1324],$Ve8=[39,120,167,287,453],$Vf8=[1,1334],$Vg8=[6,10,170,176,207,243,321,326,348,400,652,659,949,1182],$Vh8=[2,2329],$Vi8=[1,1382],$Vj8=[1,1383],$Vk8=[2,1223],$Vl8=[1,1388],$Vm8=[6,10,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,167,170,176,183,184,194,195,207,210,232,243,247,251,267,284,287,288,289,295,301,302,303,308,309,310,311,314,318,319,321,323,326,327,332,334,337,339,344,348,351,352,353,386,387,395,400,403,446,576,652,659,664,949,1182],$Vn8=[6,10,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,167,170,176,183,184,194,195,207,210,232,243,247,251,267,284,287,288,289,295,301,302,303,308,309,310,311,314,318,319,321,323,326,327,332,334,337,339,344,348,351,352,353,386,387,388,389,390,391,392,393,394,395,400,403,446,576,652,659,664,949,1182],$Vo8=[302,303,351],$Vp8=[1,1422],$Vq8=[1,1442],$Vr8=[1,1443],$Vs8=[25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,168,208,210,237,282,284,286,293,304,305,312,322,323,324,347,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,371,372,373,374,375,376,377,378,379,380,381,382,383,384,392,396,397,398,399,403,404,405,758,759,789],$Vt8=[25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,168,208,237,282,286,293,304,305,312,322,323,324,347,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,371,372,373,374,375,376,377,378,379,380,381,382,383,384,392,396,397,398,399,403,404,405,758,759,789],$Vu8=[1,1453],$Vv8=[326,395,400],$Vw8=[6,10,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,167,170,176,184,188,204,207,213,232,243,245,259,265,266,267,268,270,274,275,276,282,287,295,308,309,310,311,312,314,318,319,321,323,325,326,327,329,331,334,336,339,340,348,349,352,353,395,399,400,403,446,453,544,576,652,659,758,814,825,857,895,897,899,949,1182],$Vx8=[2,2827],$Vy8=[1,1463],$Vz8=[6,10,170,176,184,207,232,243,267,295,308,309,310,311,314,318,319,321,326,327,334,339,348,352,395,400,446,576,652,659,949,1182],$VA8=[2,1312],$VB8=[1,1480],$VC8=[1,1479],$VD8=[91,337],$VE8=[6,10,213,544],$VF8=[1,1517],$VG8=[6,10,74,120,167,213,245,276,287,544,949],$VH8=[2,2363],$VI8=[1,1532],$VJ8=[1,1533],$VK8=[6,10,34,104],$VL8=[1,1567],$VM8=[1,1570],$VN8=[1,1580],$VO8=[1,1575],$VP8=[1,1560],$VQ8=[1,1581],$VR8=[1,1576],$VS8=[1,1577],$VT8=[1,1568],$VU8=[1,1578],$VV8=[1,1563],$VW8=[1,1564],$VX8=[1,1572],$VY8=[1,1571],$VZ8=[1,1566],$V_8=[1,1565],$V$8=[1,1562],$V09=[1,1579],$V19=[1,1561],$V29=[1,1569],$V39=[1,1574],$V49=[1,1559],$V59=[1,1573],$V69=[404,405],$V79=[1,1614],$V89=[6,10,170,176,243,321,326,348,400,652,659,949,1182],$V99=[167,287],$Va9=[2,601],$Vb9=[1,1641],$Vc9=[1,1645],$Vd9=[1,1644],$Ve9=[6,10,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,167,170,176,183,184,194,195,207,210,232,243,247,251,267,284,287,288,289,295,301,302,303,308,309,310,311,314,318,319,321,323,326,327,332,334,337,339,344,348,351,352,353,386,387,388,389,390,391,395,400,403,446,576,652,659,664,949,1182],$Vf9=[6,10,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,167,170,176,183,184,194,195,207,210,232,243,247,251,267,284,287,288,295,301,302,303,308,309,310,311,314,318,319,321,326,327,332,334,337,339,344,348,351,352,353,386,387,395,400,403,446,576,652,659,664,949,1182],$Vg9=[326,400],$Vh9=[25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,168,286,312,322,758,759],$Vi9=[6,10,80,169],$Vj9=[2,747],$Vk9=[1,1705],$Vl9=[1,1710],$Vm9=[1,1711],$Vn9=[1,1712],$Vo9=[1,1709],$Vp9=[1,1720],$Vq9=[6,10,39,74,116,120,167,213,245,275,276,287,353,453,544,949],$Vr9=[2,2379],$Vs9=[1,1734],$Vt9=[1,1735],$Vu9=[1,1737],$Vv9=[1,1738],$Vw9=[122,277],$Vx9=[25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,208,282,305,324,347,383,384,392,396,404,405,685],$Vy9=[6,10,28,34,62,104,395,400],$Vz9=[1,1751],$VA9=[1,1749],$VB9=[1,1750],$VC9=[1,1748],$VD9=[1,1755],$VE9=[1,1752],$VF9=[1,1753],$VG9=[6,10,28,34,39,62,104,151,152,153,154,250,323,324,390,395,400,453],$VH9=[6,10,28,34,39,62,74,104,151,152,153,154,245,250,281,323,324,390,395,400,453],$VI9=[2,819],$VJ9=[1,1759],$VK9=[6,10,34,36,39,74,89,104,113,116,120,167,213,245,259,270,275,276,287,329,336,353,453,544,949],$VL9=[6,10,36,39,74,89,113,116,120,167,213,245,259,270,275,276,287,329,336,353,453,544,949],$VM9=[6,10,256],$VN9=[281,395,400],$VO9=[1,1805],$VP9=[1,1806],$VQ9=[1,1807],$VR9=[6,10,170,176,243,321,348,400,652,659,949,1182],$VS9=[1,1811],$VT9=[6,10,170,176,183,207,243,311,321,326,348,353,395,400,652,659,949,1182],$VU9=[6,10,37,39,72,74,116,120,167,213,244,245,275,276,287,322,324,353,453,544,576,949],$VV9=[6,10,351],$VW9=[6,10,80],$VX9=[208,282,305,347,349,383,384,396,404,405],$VY9=[6,10,28,34,39,62,104,151,152,153,154,250,323,324,395,400,453],$VZ9=[6,10,36,74,113,116,120,167,213,245,259,275,276,287,336,353,544,949],$V_9=[6,10,243,321,348,400,659,949,1182],$V$9=[1,1941],$V0a=[6,10,39,72,74,116,120,167,213,244,245,275,276,287,322,324,353,453,544,576,949],$V1a=[1,1966],$V2a=[1,1965],$V3a=[1,1973],$V4a=[390,395],$V5a=[6,10,74,113,116,120,167,213,245,275,276,287,336,353,544,949],$V6a=[2,991],$V7a=[1,2010],$V8a=[1,2012],$V9a=[1,2009],$Vaa=[1,2011],$Vba=[6,10,36,74,113,116,120,167,213,245,275,276,287,336,353,544,949],$Vca=[6,10,348,400,659,949,1182],$Vda=[6,10,39,72,74,116,120,167,213,244,245,275,276,287,324,353,453,544,576,949],$Vea=[289,780],$Vfa=[289,399,780],$Vga=[25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,167,403],$Vha=[6,10,170,176,243,247,251,321,332,337,348,395,400,652,659,949,1182],$Via=[6,10,39,68,74,116,120,245,275,276,313,336,453],$Vja=[6,10,348,400,949,1182],$Vka=[6,10,170,176,243,251,321,332,337,348,395,400,652,659,949,1182],$Vla=[2,952],$Vma=[1,2107],$Vna=[6,10,39,74,116,120,167,213,245,275,276,287,324,353,453,544,576,949],$Voa=[143,174,296,383,386,400,780],$Vpa=[2,1452],$Vqa=[6,10,74,116,120,167,213,245,275,276,287,336,353,544,949],$Vra=[6,10,39,74,116,120,245,275,276,313,336,453],$Vsa=[6,10,243,321,348,395,400,659,949,1182],$Vta=[1,2149],$Vua=[6,10,39,74,116,120,167,213,245,275,276,287,353,453,544,576,949],$Vva=[386,400],$Vwa=[2,1462],$Vxa=[1,2164],$Vya=[1,2163],$Vza=[1,2162],$VAa=[1,2160],$VBa=[1,2161],$VCa=[2,2317],$VDa=[1,2175],$VEa=[1,2174],$VFa=[6,10,39,74,116,120,245,275,276,336,453],$VGa=[6,10,215,226,236,258],$VHa=[1,2199],$VIa=[2,1472],$VJa=[307,330],$VKa=[6,10,400],$VLa=[6,10,39,74,120,167,213,245,276,287,353,453,544,949],$VMa=[1,2214],$VNa=[1,2215],$VOa=[6,10,226,236,258],$VPa=[49,109,220],$VQa=[6,10,226,236],$VRa=[2,2393],$VSa=[1,2260],$VTa=[1,2261],$VUa=[6,10,236],$VVa=[6,10,39,167,213,287,453,544,949],$VWa=[2,2280],$VXa=[2,2281],$VYa=[6,10,949]; +var parser = {trace: function trace() { }, +yy: {}, +symbols_: {"error":2,"SqlSyntax":3,"NewStatement":4,"SqlStatements":5,"EOF":6,"SqlAutocomplete":7,"SqlStatements_EDIT":8,"SqlStatement":9,";":10,"SqlStatement_EDIT":11,"DataDefinition":12,"DataManipulation":13,"QuerySpecification":14,"ExplainClause":15,"AnyCursor":16,"CommonTableExpression":17,"CURSOR":18,"ExplainClause_EDIT":19,"DataDefinition_EDIT":20,"DataManipulation_EDIT":21,"QuerySpecification_EDIT":22,"SetSpecification_EDIT":23,"NonReservedKeyword":24,"