plywood
Version:
A query planner and executor
201 lines (200 loc) • 10.6 kB
JavaScript
import { __extends } from "tslib";
import { NamedArray } from 'immutable-class';
import { SQLDialect } from './baseDialect';
var DruidDialect = (function (_super) {
__extends(DruidDialect, _super);
function DruidDialect(options) {
if (options === void 0) { options = {}; }
var _this = _super.call(this) || this;
_this.attributes = options.attributes;
return _this;
}
DruidDialect.prototype.dateToSQLDateString = function (date) {
return date
.toISOString()
.replace('T', ' ')
.replace('Z', '')
.replace(/\.000$/, '');
};
DruidDialect.prototype.floatDivision = function (numerator, denominator) {
return "(".concat(numerator, "*1.0/").concat(denominator, ")");
};
DruidDialect.prototype.emptyGroupBy = function () {
return 'GROUP BY ()';
};
DruidDialect.prototype.timeToSQL = function (date) {
if (!date)
return this.nullConstant();
return "TIMESTAMP '".concat(this.dateToSQLDateString(date), "'");
};
DruidDialect.prototype.stringArrayToSQL = function (value) {
var _this = this;
var arr = value.map(function (v) { return _this.escapeLiteral(v); });
return "ARRAY[".concat(arr.join(','), "]");
};
DruidDialect.prototype.ipParse = function (value) {
return "IP_PARSE(".concat(value, ")");
};
DruidDialect.prototype.ipPrefixParse = function (value) {
return "IP_PREFIX_PARSE(".concat(value, ")");
};
DruidDialect.prototype.concatExpression = function (a, b) {
return "(".concat(a, "||").concat(b, ")");
};
DruidDialect.prototype.containsExpression = function (a, b, insensitive) {
return "".concat(insensitive ? 'ICONTAINS_STRING' : 'CONTAINS_STRING', "(CAST(").concat(a, " AS VARCHAR),").concat(b, ")");
};
DruidDialect.prototype.mvContainsExpression = function (a, b) {
return "MV_CONTAINS(".concat(a, ", ").concat(this.stringArrayToSQL(b), ")");
};
DruidDialect.prototype.mvFilterOnlyExpression = function (a, b) {
return "MV_FILTER_ONLY(".concat(a, ", ").concat(this.stringArrayToSQL(b), ")");
};
DruidDialect.prototype.mvOverlapExpression = function (a, b) {
return "MV_OVERLAP(".concat(a, ", ").concat(this.stringArrayToSQL(b), ")");
};
DruidDialect.prototype.substrExpression = function (a, position, length) {
return "SUBSTRING(".concat(a, ",").concat(position + 1, ",").concat(length, ")");
};
DruidDialect.prototype.countDistinctExpression = function (a, parameterAttributeName) {
var attribute = NamedArray.findByName(this.attributes || [], parameterAttributeName);
var nativeType = attribute ? attribute.nativeType : undefined;
switch (nativeType) {
case 'HLLSketch':
return "APPROX_COUNT_DISTINCT_DS_HLL(".concat(a, ")");
case 'thetaSketch':
return "APPROX_COUNT_DISTINCT_DS_THETA(".concat(a, ")");
case 'hyperUnique':
return "APPROX_COUNT_DISTINCT(".concat(a, ")");
default:
return "COUNT(DISTINCT ".concat(a, ")");
}
};
DruidDialect.prototype.isNotDistinctFromExpression = function (a, b) {
var nullConst = this.nullConstant();
if (a === nullConst)
return "".concat(b, " IS ").concat(nullConst);
if (b === nullConst)
return "".concat(a, " IS ").concat(nullConst);
return "(".concat(a, "=").concat(b, ")");
};
DruidDialect.prototype.castExpression = function (inputType, operand, targetType) {
if (targetType === 'SET/STRING')
targetType = 'STRING';
if (inputType === targetType)
return operand;
var castForInput = DruidDialect.CAST_TO_FUNCTION[targetType];
var castFunction = castForInput[inputType || '_'] || castForInput['_'];
if (!castFunction) {
throw new Error("unsupported cast from ".concat(inputType || 'unknown', " to ").concat(targetType, " in Druid dialect"));
}
return castFunction.replace(/\$\$/g, operand);
};
DruidDialect.prototype.operandAsTimestamp = function (operand) {
return operand.includes('__time') ? operand : "CAST(".concat(operand, " AS TIMESTAMP)");
};
DruidDialect.prototype.timeFloorExpression = function (operand, duration, timezone) {
return "TIME_FLOOR(".concat(this.operandAsTimestamp(operand), ", ").concat(this.escapeLiteral(duration.toString()), ", NULL, ").concat(this.escapeLiteral(timezone.toString()), ")");
};
DruidDialect.prototype.timeBucketExpression = function (operand, duration, timezone) {
return this.timeFloorExpression(operand, duration, timezone);
};
DruidDialect.prototype.timePartExpression = function (operand, part, timezone) {
var timePartFunction = DruidDialect.TIME_PART_TO_FUNCTION[part];
if (!timePartFunction)
throw new Error("unsupported part ".concat(part, " in Druid dialect"));
return timePartFunction
.replace(/\$\$/g, this.operandAsTimestamp(operand))
.replace(/##/g, this.escapeLiteral(timezone.toString()));
};
DruidDialect.prototype.timeShiftExpression = function (operand, duration, step, timezone) {
return "TIME_SHIFT(".concat(this.operandAsTimestamp(operand), ", ").concat(this.escapeLiteral(duration.toString()), ", ").concat(step, ", ").concat(this.escapeLiteral(timezone.toString()), ")");
};
DruidDialect.prototype.extractExpression = function (operand, regexp) {
return "REGEXP_EXTRACT(CAST(".concat(operand, " AS VARCHAR), ").concat(this.escapeLiteral(regexp), ", 1)");
};
DruidDialect.prototype.regexpExpression = function (expression, regexp) {
return "REGEXP_LIKE(CAST(".concat(expression, " AS VARCHAR), ").concat(this.escapeLiteral(regexp), ")");
};
DruidDialect.prototype.indexOfExpression = function (str, substr) {
return "POSITION(".concat(substr, " IN ").concat(str, ") - 1");
};
DruidDialect.prototype.quantileExpression = function (str, quantile, parameterAttributeName) {
var attribute = NamedArray.findByName(this.attributes || [], parameterAttributeName);
var nativeType = attribute ? attribute.nativeType : undefined;
switch (nativeType) {
case 'approximateHistogram':
return "APPROX_QUANTILE(".concat(str, ", ").concat(quantile, ")");
default:
return "APPROX_QUANTILE_DS(".concat(str, ", ").concat(quantile, ")");
}
};
DruidDialect.prototype.logExpression = function (base, operand) {
if (base === String(Math.E))
return "LN(".concat(operand, ")");
if (base === '10')
return "LOG10(".concat(operand, ")");
return "LN(".concat(operand, ")/LN(").concat(base, ")");
};
DruidDialect.prototype.lookupExpression = function (base, lookup) {
return "LOOKUP(".concat(base, ", ").concat(this.escapeLiteral(lookup), ")");
};
DruidDialect.prototype.ipMatchExpression = function (columnName, searchString, ipSearchType) {
return ipSearchType === 'ipPrefix'
? "IP_MATCH(".concat(this.escapeLiteral(searchString.toString()), ", ").concat(columnName, ")")
: "IP_MATCH(".concat(columnName, ", ").concat(this.escapeLiteral(searchString.toString()), ")");
};
DruidDialect.prototype.ipSearchExpression = function (columnName, searchString, ipSearchType) {
return ipSearchType === 'ipPrefix'
? "IP_SEARCH(".concat(this.escapeLiteral(searchString.toString()), ", ").concat(columnName, ")")
: "IP_SEARCH(".concat(columnName, ", ").concat(this.escapeLiteral(searchString.toString()), ")");
};
DruidDialect.prototype.ipStringifyExpression = function (operand) {
return "IP_STRINGIFY(".concat(operand, ")");
};
DruidDialect.TIME_PART_TO_FUNCTION = {
SECOND_OF_MINUTE: "TIME_EXTRACT($$,'SECOND',##)",
SECOND_OF_HOUR: "(TIME_EXTRACT($$,'MINUTE',##)*60+TIME_EXTRACT($$,'SECOND',##))",
SECOND_OF_DAY: "((TIME_EXTRACT($$,'HOUR',##)*60+TIME_EXTRACT($$,'MINUTE',##))*60+TIME_EXTRACT($$,'SECOND',##))",
SECOND_OF_WEEK: "(((MOD(CAST((TIME_EXTRACT($$,'DOW',##)+6) AS int),7)*24)+TIME_EXTRACT($$,'HOUR',##)*60+TIME_EXTRACT($$,'MINUTE',##))*60+TIME_EXTRACT($$,'SECOND',##))",
SECOND_OF_MONTH: "((((TIME_EXTRACT($$,'DAY',##)-1)*24)+TIME_EXTRACT($$,'HOUR',##)*60+TIME_EXTRACT($$,'MINUTE',##))*60+TIME_EXTRACT($$,'SECOND',##))",
SECOND_OF_YEAR: "((((TIME_EXTRACT($$,'DOY',##)-1)*24)+TIME_EXTRACT($$,'HOUR',##)*60+TIME_EXTRACT($$,'MINUTE',##))*60+TIME_EXTRACT($$,'SECOND',##))",
MINUTE_OF_HOUR: "TIME_EXTRACT($$,'MINUTE',##)",
MINUTE_OF_DAY: "TIME_EXTRACT($$,'HOUR',##)*60+TIME_EXTRACT($$,'MINUTE',##)",
MINUTE_OF_WEEK: "(MOD(CAST((TIME_EXTRACT($$,'DOW',##)+6) AS int),7)*24)+TIME_EXTRACT($$,'HOUR',##)*60+TIME_EXTRACT($$,'MINUTE',##)",
MINUTE_OF_MONTH: "((TIME_EXTRACT($$,'DAY',##)-1)*24)+TIME_EXTRACT($$,'HOUR',##)*60+TIME_EXTRACT($$,'MINUTE',##)",
MINUTE_OF_YEAR: "((TIME_EXTRACT($$,'DOY',##)-1)*24)+TIME_EXTRACT($$,'HOUR',##)*60+TIME_EXTRACT($$,'MINUTE',##)",
HOUR_OF_DAY: "TIME_EXTRACT($$,'HOUR',##)",
HOUR_OF_WEEK: "(MOD(CAST((TIME_EXTRACT($$,'DOW',##)+6) AS int),7)*24+TIME_EXTRACT($$,'HOUR',##))",
HOUR_OF_MONTH: "((TIME_EXTRACT($$,'DAY',##)-1)*24+TIME_EXTRACT($$,'HOUR',##))",
HOUR_OF_YEAR: "((TIME_EXTRACT($$,'DOY',##)-1)*24+TIME_EXTRACT($$,'HOUR',##))",
DAY_OF_WEEK: "MOD(CAST((TIME_EXTRACT($$,'DOW',##)+6) AS int),7)+1",
DAY_OF_MONTH: "TIME_EXTRACT($$,'DAY',##)",
DAY_OF_YEAR: "TIME_EXTRACT($$,'DOY',##)",
WEEK_OF_YEAR: "TIME_EXTRACT($$,'WEEK',##)",
MONTH_OF_YEAR: "TIME_EXTRACT($$,'MONTH',##)",
YEAR: "TIME_EXTRACT($$,'YEAR',##)",
};
DruidDialect.CAST_TO_FUNCTION = {
TIME: {
NUMBER: 'MILLIS_TO_TIMESTAMP(CAST($$ AS BIGINT))',
_: 'CAST($$ AS TIMESTAMP)',
},
NUMBER: {
TIME: 'CAST($$ AS BIGINT)',
STRING: 'CAST($$ AS DOUBLE)',
_: 'CAST($$ AS DOUBLE)',
},
STRING: {
NUMBER: 'CAST($$ AS VARCHAR)',
_: 'CAST($$ AS VARCHAR)',
},
BOOLEAN: {
NUMBER: '($$ = 1)',
STRING: "($$ = 'true')",
_: "(CAST($$ AS VARCHAR) IN ('1','true'))",
},
};
return DruidDialect;
}(SQLDialect));
export { DruidDialect };