use of org.apache.calcite.sql.SqlNumericLiteral in project drill by apache.
the class DrillConvertletTable method expandVariance.
/**
* This code is adapted from calcite's AvgVarianceConvertlet. The difference being
* we add a cast to double before we perform the division. The reason we have a separate implementation
* from calcite's code is because while injecting a similar cast, calcite will look
* at the output type of the aggregate function which will be 'ANY' at that point and will
* inject a cast to 'ANY' which does not solve the problem.
*/
private static SqlNode expandVariance(SqlNode arg, boolean biased, boolean sqrt) {
/* stddev_pop(x) ==>
* power(
* (sum(x * x) - sum(x) * sum(x) / count(x))
* / count(x),
* .5)
* stddev_samp(x) ==>
* power(
* (sum(x * x) - sum(x) * sum(x) / count(x))
* / (count(x) - 1),
* .5)
* var_pop(x) ==>
* (sum(x * x) - sum(x) * sum(x) / count(x))
* / count(x)
* var_samp(x) ==>
* (sum(x * x) - sum(x) * sum(x) / count(x))
* / (count(x) - 1)
*/
final SqlParserPos pos = SqlParserPos.ZERO;
// cast the argument to double
final SqlNode castHighArg = CastHighOp.createCall(pos, arg);
final SqlNode argSquared = SqlStdOperatorTable.MULTIPLY.createCall(pos, castHighArg, castHighArg);
final SqlNode sumArgSquared = DrillCalciteSqlAggFunctionWrapper.SUM.createCall(pos, argSquared);
final SqlNode sum = DrillCalciteSqlAggFunctionWrapper.SUM.createCall(pos, castHighArg);
final SqlNode sumSquared = SqlStdOperatorTable.MULTIPLY.createCall(pos, sum, sum);
final SqlNode count = SqlStdOperatorTable.COUNT.createCall(pos, castHighArg);
final SqlNode avgSumSquared = SqlStdOperatorTable.DIVIDE.createCall(pos, sumSquared, count);
final SqlNode diff = SqlStdOperatorTable.MINUS.createCall(pos, sumArgSquared, avgSumSquared);
final SqlNode denominator;
if (biased) {
denominator = count;
} else {
final SqlNumericLiteral one = SqlLiteral.createExactNumeric("1", pos);
denominator = SqlStdOperatorTable.MINUS.createCall(pos, count, one);
}
final SqlNode diffAsDouble = CastHighOp.createCall(pos, diff);
final SqlNode div = SqlStdOperatorTable.DIVIDE.createCall(pos, diffAsDouble, denominator);
SqlNode result = div;
if (sqrt) {
final SqlNumericLiteral half = SqlLiteral.createExactNumeric("0.5", pos);
result = SqlStdOperatorTable.POWER.createCall(pos, div, half);
}
return result;
}
use of org.apache.calcite.sql.SqlNumericLiteral in project drill by apache.
the class MetastoreAnalyzeTableHandler method convertToDrel.
/**
* Converts to Drill logical plan
*/
private DrillRel convertToDrel(RelNode relNode, SqlMetastoreAnalyzeTable sqlAnalyzeTable, DrillTableInfo drillTableInfo) throws ForemanSetupException, IOException {
RelBuilder relBuilder = LOGICAL_BUILDER.create(relNode.getCluster(), null);
DrillTable table = drillTableInfo.drillTable();
AnalyzeInfoProvider analyzeInfoProvider = table.getGroupScan().getAnalyzeInfoProvider();
List<String> schemaPath = drillTableInfo.schemaPath();
String pluginName = schemaPath.get(0);
String workspaceName = Strings.join(schemaPath.subList(1, schemaPath.size()), AbstractSchema.SCHEMA_SEPARATOR);
String tableName = drillTableInfo.tableName();
TableInfo tableInfo = TableInfo.builder().name(tableName).owner(table.getUserName()).type(analyzeInfoProvider.getTableTypeName()).storagePlugin(pluginName).workspace(workspaceName).build();
ColumnNamesOptions columnNamesOptions = new ColumnNamesOptions(context.getOptions());
List<String> segmentColumns = analyzeInfoProvider.getSegmentColumns(table, columnNamesOptions).stream().map(SchemaPath::getRootSegmentPath).collect(Collectors.toList());
List<NamedExpression> segmentExpressions = segmentColumns.stream().map(partitionName -> new NamedExpression(SchemaPath.getSimplePath(partitionName), FieldReference.getWithQuotedRef(partitionName))).collect(Collectors.toList());
List<MetadataInfo> rowGroupsInfo = Collections.emptyList();
List<MetadataInfo> filesInfo = Collections.emptyList();
Multimap<Integer, MetadataInfo> segments = ArrayListMultimap.create();
BasicTablesRequests basicRequests;
try {
basicRequests = context.getMetastoreRegistry().get().tables().basicRequests();
} catch (MetastoreException e) {
logger.error("Error when obtaining Metastore instance for table {}", tableName, e);
DrillRel convertedRelNode = convertToRawDrel(relBuilder.values(new String[] { MetastoreAnalyzeConstants.OK_FIELD_NAME, MetastoreAnalyzeConstants.SUMMARY_FIELD_NAME }, false, e.getMessage()).build());
return new DrillScreenRel(convertedRelNode.getCluster(), convertedRelNode.getTraitSet(), convertedRelNode);
}
MetadataType metadataLevel = getMetadataType(sqlAnalyzeTable);
List<SchemaPath> interestingColumns = sqlAnalyzeTable.getFieldNames();
MetastoreTableInfo metastoreTableInfo = basicRequests.metastoreTableInfo(tableInfo);
List<MetadataInfo> allMetaToHandle = null;
List<MetadataInfo> metadataToRemove = new ArrayList<>();
// whether incremental analyze may be produced
if (metastoreTableInfo.isExists()) {
RelNode finalRelNode = relNode;
CheckedSupplier<TableScan, SqlUnsupportedException> tableScanSupplier = () -> DrillRelOptUtil.findScan(convertToDrel(finalRelNode.getInput(0)));
MetadataInfoCollector metadataInfoCollector = analyzeInfoProvider.getMetadataInfoCollector(basicRequests, tableInfo, (FormatSelection) table.getSelection(), context.getPlannerSettings(), tableScanSupplier, interestingColumns, metadataLevel, segmentColumns.size());
if (!metadataInfoCollector.isOutdated()) {
DrillRel convertedRelNode = convertToRawDrel(relBuilder.values(new String[] { MetastoreAnalyzeConstants.OK_FIELD_NAME, MetastoreAnalyzeConstants.SUMMARY_FIELD_NAME }, false, "Table metadata is up to date, analyze wasn't performed.").build());
return new DrillScreenRel(convertedRelNode.getCluster(), convertedRelNode.getTraitSet(), convertedRelNode);
}
// updates scan to read updated / new files, pass removed files into metadata handler
relNode = relNode.copy(relNode.getTraitSet(), Collections.singletonList(metadataInfoCollector.getPrunedScan()));
filesInfo = metadataInfoCollector.getFilesInfo();
segments = metadataInfoCollector.getSegmentsInfo();
rowGroupsInfo = metadataInfoCollector.getRowGroupsInfo();
allMetaToHandle = metadataInfoCollector.getAllMetaToHandle();
metadataToRemove = metadataInfoCollector.getMetadataToRemove();
}
// Step 2: constructs plan for producing analyze
DrillRel convertedRelNode = convertToRawDrel(relNode);
boolean createNewAggregations = true;
// List of columns for which statistics should be collected: interesting columns + segment columns
List<SchemaPath> statisticsColumns = interestingColumns == null ? null : new ArrayList<>(interestingColumns);
if (statisticsColumns != null) {
segmentColumns.stream().map(SchemaPath::getSimplePath).forEach(statisticsColumns::add);
}
SchemaPath locationField = analyzeInfoProvider.getLocationField(columnNamesOptions);
if (analyzeInfoProvider.supportsMetadataType(MetadataType.ROW_GROUP) && metadataLevel.includes(MetadataType.ROW_GROUP)) {
MetadataHandlerContext handlerContext = MetadataHandlerContext.builder().tableInfo(tableInfo).metadataToHandle(rowGroupsInfo).metadataType(MetadataType.ROW_GROUP).depthLevel(segmentExpressions.size()).segmentColumns(segmentColumns).build();
convertedRelNode = getRowGroupAggRelNode(segmentExpressions, convertedRelNode, createNewAggregations, statisticsColumns, handlerContext);
createNewAggregations = false;
locationField = SchemaPath.getSimplePath(MetastoreAnalyzeConstants.LOCATION_FIELD);
}
if (analyzeInfoProvider.supportsMetadataType(MetadataType.FILE) && metadataLevel.includes(MetadataType.FILE)) {
MetadataHandlerContext handlerContext = MetadataHandlerContext.builder().tableInfo(tableInfo).metadataToHandle(filesInfo).metadataType(MetadataType.FILE).depthLevel(segmentExpressions.size()).segmentColumns(segmentColumns).build();
convertedRelNode = getFileAggRelNode(segmentExpressions, convertedRelNode, createNewAggregations, statisticsColumns, locationField, handlerContext);
locationField = SchemaPath.getSimplePath(MetastoreAnalyzeConstants.LOCATION_FIELD);
createNewAggregations = false;
}
if (analyzeInfoProvider.supportsMetadataType(MetadataType.SEGMENT) && metadataLevel.includes(MetadataType.SEGMENT)) {
for (int i = segmentExpressions.size(); i > 0; i--) {
MetadataHandlerContext handlerContext = MetadataHandlerContext.builder().tableInfo(tableInfo).metadataToHandle(new ArrayList<>(segments.get(i - 1))).metadataType(MetadataType.SEGMENT).depthLevel(i).segmentColumns(segmentColumns.subList(0, i)).build();
convertedRelNode = getSegmentAggRelNode(segmentExpressions, convertedRelNode, createNewAggregations, statisticsColumns, locationField, i, handlerContext);
locationField = SchemaPath.getSimplePath(MetastoreAnalyzeConstants.LOCATION_FIELD);
createNewAggregations = false;
}
}
if (analyzeInfoProvider.supportsMetadataType(MetadataType.TABLE) && metadataLevel.includes(MetadataType.TABLE)) {
MetadataHandlerContext handlerContext = MetadataHandlerContext.builder().tableInfo(tableInfo).metadataToHandle(Collections.emptyList()).metadataType(MetadataType.TABLE).depthLevel(segmentExpressions.size()).segmentColumns(segmentColumns).build();
convertedRelNode = getTableAggRelNode(convertedRelNode, createNewAggregations, statisticsColumns, locationField, handlerContext);
} else {
throw new IllegalStateException("Analyze table with NONE level");
}
boolean useStatistics = context.getOptions().getOption(PlannerSettings.STATISTICS_USE);
SqlNumericLiteral samplePercentLiteral = sqlAnalyzeTable.getSamplePercent();
double samplePercent = samplePercentLiteral == null ? 100.0 : samplePercentLiteral.intValue(true);
// Step 3: adds rel nodes for producing statistics analyze if required
RelNode analyzeRel = useStatistics ? new DrillAnalyzeRel(convertedRelNode.getCluster(), convertedRelNode.getTraitSet(), convertToRawDrel(relNode), samplePercent) : convertToRawDrel(relBuilder.values(new String[] { "" }, "").build());
MetadataControllerContext metadataControllerContext = MetadataControllerContext.builder().tableInfo(tableInfo).metastoreTableInfo(metastoreTableInfo).location(((FormatSelection) table.getSelection()).getSelection().getSelectionRoot()).interestingColumns(interestingColumns).segmentColumns(segmentColumns).metadataToHandle(allMetaToHandle).metadataToRemove(metadataToRemove).analyzeMetadataLevel(metadataLevel).build();
convertedRelNode = new MetadataControllerRel(convertedRelNode.getCluster(), convertedRelNode.getTraitSet(), convertedRelNode, analyzeRel, metadataControllerContext);
return new DrillScreenRel(convertedRelNode.getCluster(), convertedRelNode.getTraitSet(), convertedRelNode);
}
use of org.apache.calcite.sql.SqlNumericLiteral in project drill by axbaretto.
the class UnsupportedOperatorsVisitor method visit.
@Override
public SqlNode visit(SqlCall sqlCall) {
// Inspect the window functions
if (sqlCall instanceof SqlSelect) {
SqlSelect sqlSelect = (SqlSelect) sqlCall;
checkGrouping((sqlSelect));
checkRollupCubeGrpSets(sqlSelect);
for (SqlNode nodeInSelectList : sqlSelect.getSelectList()) {
// enter the first operand of AS operator
if (nodeInSelectList.getKind() == SqlKind.AS && (((SqlCall) nodeInSelectList).getOperandList().get(0).getKind() == SqlKind.OVER)) {
nodeInSelectList = ((SqlCall) nodeInSelectList).getOperandList().get(0);
}
if (nodeInSelectList.getKind() == SqlKind.OVER) {
// Throw exceptions if window functions are disabled
if (!context.getOptions().getOption(ExecConstants.ENABLE_WINDOW_FUNCTIONS).bool_val) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Window functions are disabled\n" + "See Apache Drill JIRA: DRILL-2559");
throw new UnsupportedOperationException();
}
// DRILL-3182, DRILL-3195
SqlCall over = (SqlCall) nodeInSelectList;
if (over.getOperandList().get(0) instanceof SqlCall) {
SqlCall function = (SqlCall) over.getOperandList().get(0);
// Window function with DISTINCT qualifier is temporarily disabled
if (function.getFunctionQuantifier() != null && function.getFunctionQuantifier().getValue() == SqlSelectKeyword.DISTINCT) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "DISTINCT for window aggregate functions is not currently supported\n" + "See Apache Drill JIRA: DRILL-3182");
throw new UnsupportedOperationException();
}
// DRILL-3596: we only allow (<column-name>) or (<column-name>, 1)
final String functionName = function.getOperator().getName().toUpperCase();
if ("LEAD".equals(functionName) || "LAG".equals(functionName)) {
boolean supported = true;
if (function.operandCount() > 2) {
// we don't support more than 2 arguments
supported = false;
} else if (function.operandCount() == 2) {
SqlNode operand = function.operand(1);
if (operand instanceof SqlNumericLiteral) {
SqlNumericLiteral offsetLiteral = (SqlNumericLiteral) operand;
try {
if (offsetLiteral.intValue(true) != 1) {
// we don't support offset != 1
supported = false;
}
} catch (AssertionError e) {
// we only support offset as an integer
supported = false;
}
} else {
// we only support offset as a numeric literal
supported = false;
}
}
if (!supported) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Function " + functionName + " only supports (<value expression>) or (<value expression>, 1)\n" + "See Apache DRILL JIRA: DRILL-3596");
throw new UnsupportedOperationException();
}
}
}
}
}
}
// (i.e., BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
if (sqlCall instanceof SqlWindow) {
SqlWindow window = (SqlWindow) sqlCall;
SqlNode lowerBound = window.getLowerBound();
SqlNode upperBound = window.getUpperBound();
// If no frame is specified
// it is a default frame
boolean isSupported = (lowerBound == null && upperBound == null);
// RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
if (window.getOrderList().size() != 0 && !window.isRows() && SqlWindow.isUnboundedPreceding(lowerBound) && (upperBound == null || SqlWindow.isCurrentRow(upperBound) || SqlWindow.isUnboundedFollowing(upperBound))) {
isSupported = true;
}
// is supported with and without the ORDER BY clause
if (window.isRows() && SqlWindow.isUnboundedPreceding(lowerBound) && (upperBound == null || SqlWindow.isCurrentRow(upperBound))) {
isSupported = true;
}
// is supported with and without an ORDER BY clause
if (!window.isRows() && SqlWindow.isCurrentRow(lowerBound) && SqlWindow.isCurrentRow(upperBound)) {
isSupported = true;
}
// ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
if (window.getOrderList().size() == 0 && SqlWindow.isUnboundedPreceding(lowerBound) && SqlWindow.isUnboundedFollowing(upperBound)) {
isSupported = true;
}
if (!isSupported) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "This type of window frame is currently not supported \n" + "See Apache Drill JIRA: DRILL-3188");
throw new UnsupportedOperationException();
}
// DRILL-3189: Disable DISALLOW PARTIAL
if (!window.isAllowPartial()) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Disallowing partial windows is currently not supported \n" + "See Apache Drill JIRA: DRILL-3189");
throw new UnsupportedOperationException();
}
}
// Disable unsupported Intersect, Except
if (sqlCall.getKind() == SqlKind.INTERSECT || sqlCall.getKind() == SqlKind.EXCEPT) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.RELATIONAL, sqlCall.getOperator().getName() + " is not supported\n" + "See Apache Drill JIRA: DRILL-1921");
throw new UnsupportedOperationException();
}
// Disable unsupported JOINs
if (sqlCall.getKind() == SqlKind.JOIN) {
SqlJoin join = (SqlJoin) sqlCall;
// Block Natural Join
if (join.isNatural()) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.RELATIONAL, "NATURAL JOIN is not supported\n" + "See Apache Drill JIRA: DRILL-1986");
throw new UnsupportedOperationException();
}
// Block Cross Join
if (join.getJoinType() == JoinType.CROSS) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.RELATIONAL, "CROSS JOIN is not supported\n" + "See Apache Drill JIRA: DRILL-1921");
throw new UnsupportedOperationException();
}
}
// Disable Function
for (String strOperator : disabledOperators) {
if (sqlCall.getOperator().isName(strOperator)) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, sqlCall.getOperator().getName() + " is not supported\n" + "See Apache Drill JIRA: DRILL-2115");
throw new UnsupportedOperationException();
}
}
// Disable complex functions incorrect placement
if (sqlCall instanceof SqlSelect) {
SqlSelect sqlSelect = (SqlSelect) sqlCall;
for (SqlNode nodeInSelectList : sqlSelect.getSelectList()) {
if (checkDirExplorers(nodeInSelectList)) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Directory explorers " + dirExplorers + " functions are not supported in Select List\n" + "See Apache Drill JIRA: DRILL-3944");
throw new UnsupportedOperationException();
}
}
if (sqlSelect.hasWhere()) {
if (checkDirExplorers(sqlSelect.getWhere()) && !context.getPlannerSettings().isConstantFoldingEnabled()) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Directory explorers " + dirExplorers + " functions can not be used " + "when " + PlannerSettings.CONSTANT_FOLDING.getOptionName() + " option is set to false\n" + "See Apache Drill JIRA: DRILL-3944");
throw new UnsupportedOperationException();
}
}
if (sqlSelect.hasOrderBy()) {
for (SqlNode sqlNode : sqlSelect.getOrderList()) {
if (containsFlatten(sqlNode)) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Flatten function is not supported in Order By\n" + "See Apache Drill JIRA: DRILL-2181");
throw new UnsupportedOperationException();
} else if (checkDirExplorers(sqlNode)) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Directory explorers " + dirExplorers + " functions are not supported in Order By\n" + "See Apache Drill JIRA: DRILL-3944");
throw new UnsupportedOperationException();
}
}
}
if (sqlSelect.getGroup() != null) {
for (SqlNode sqlNode : sqlSelect.getGroup()) {
if (containsFlatten(sqlNode)) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Flatten function is not supported in Group By\n" + "See Apache Drill JIRA: DRILL-2181");
throw new UnsupportedOperationException();
} else if (checkDirExplorers(sqlNode)) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Directory explorers " + dirExplorers + " functions are not supported in Group By\n" + "See Apache Drill JIRA: DRILL-3944");
throw new UnsupportedOperationException();
}
}
}
if (sqlSelect.isDistinct()) {
for (SqlNode column : sqlSelect.getSelectList()) {
if (column.getKind() == SqlKind.AS) {
if (containsFlatten(((SqlCall) column).getOperandList().get(0))) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Flatten function is not supported in Distinct\n" + "See Apache Drill JIRA: DRILL-2181");
throw new UnsupportedOperationException();
}
} else {
if (containsFlatten(column)) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Flatten function is not supported in Distinct\n" + "See Apache Drill JIRA: DRILL-2181");
throw new UnsupportedOperationException();
}
}
}
}
}
if (DrillCalciteWrapperUtility.extractSqlOperatorFromWrapper(sqlCall.getOperator()) instanceof SqlCountAggFunction) {
for (SqlNode sqlNode : sqlCall.getOperandList()) {
if (containsFlatten(sqlNode)) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Flatten function in aggregate functions is not supported\n" + "See Apache Drill JIRA: DRILL-2181");
throw new UnsupportedOperationException();
}
}
}
return sqlCall.getOperator().acceptCall(this, sqlCall);
}
use of org.apache.calcite.sql.SqlNumericLiteral in project streamline by hortonworks.
the class ExpressionGenerator method visitSqlSpecialOperator.
private Expression visitSqlSpecialOperator(SqlSpecialOperator specialOperator, List<SqlNode> operands) {
if (specialOperator.getName().equalsIgnoreCase("ITEM")) {
Expression left = operands.get(0).accept(this);
SqlNode right = operands.get(1);
if (right instanceof SqlNumericLiteral) {
SqlNumericLiteral index = (SqlNumericLiteral) right;
if (!index.isInteger()) {
throw new IllegalArgumentException("Invalid array index " + index);
}
return new ArrayFieldExpression(left, Integer.parseInt(index.toValue()));
} else if (right instanceof SqlCharStringLiteral) {
String key = ((SqlCharStringLiteral) right).toValue();
return new MapFieldExpression(left, key);
} else {
throw new IllegalArgumentException("Item right operand '" + right + "' must be numeric or character type");
}
} else if (specialOperator.getName().equalsIgnoreCase("AS")) {
Expression left = operands.get(0).accept(this);
String alias = operands.get(1).toString();
return new AsExpression(left, alias);
} else {
throw new UnsupportedOperationException("Operator " + specialOperator + " not implemented");
}
}
use of org.apache.calcite.sql.SqlNumericLiteral in project drill by apache.
the class UnsupportedOperatorsVisitor method visit.
@Override
public SqlNode visit(SqlCall sqlCall) {
// Inspect the window functions
if (sqlCall instanceof SqlSelect) {
SqlSelect sqlSelect = (SqlSelect) sqlCall;
checkGrouping((sqlSelect));
checkRollupCubeGrpSets(sqlSelect);
for (SqlNode nodeInSelectList : sqlSelect.getSelectList()) {
// enter the first operand of AS operator
if (nodeInSelectList.getKind() == SqlKind.AS && (((SqlCall) nodeInSelectList).getOperandList().get(0).getKind() == SqlKind.OVER)) {
nodeInSelectList = ((SqlCall) nodeInSelectList).getOperandList().get(0);
}
if (nodeInSelectList.getKind() == SqlKind.OVER) {
// Throw exceptions if window functions are disabled
if (!context.getOptions().getOption(ExecConstants.ENABLE_WINDOW_FUNCTIONS).bool_val) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Window functions are disabled\n" + "See Apache Drill JIRA: DRILL-2559");
throw new UnsupportedOperationException();
}
// DRILL-3182, DRILL-3195
SqlCall over = (SqlCall) nodeInSelectList;
if (over.getOperandList().get(0) instanceof SqlCall) {
SqlCall function = (SqlCall) over.getOperandList().get(0);
// Window function with DISTINCT qualifier is temporarily disabled
if (function.getFunctionQuantifier() != null && function.getFunctionQuantifier().getValue() == SqlSelectKeyword.DISTINCT) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "DISTINCT for window aggregate functions is not currently supported\n" + "See Apache Drill JIRA: DRILL-3182");
throw new UnsupportedOperationException();
}
// DRILL-3596: we only allow (<column-name>) or (<column-name>, 1)
final String functionName = function.getOperator().getName().toUpperCase();
if ("LEAD".equals(functionName) || "LAG".equals(functionName)) {
boolean supported = true;
if (function.operandCount() > 2) {
// we don't support more than 2 arguments
supported = false;
} else if (function.operandCount() == 2) {
SqlNode operand = function.operand(1);
if (operand instanceof SqlNumericLiteral) {
SqlNumericLiteral offsetLiteral = (SqlNumericLiteral) operand;
try {
if (offsetLiteral.intValue(true) != 1) {
// we don't support offset != 1
supported = false;
}
} catch (AssertionError e) {
// we only support offset as an integer
supported = false;
}
} else {
// we only support offset as a numeric literal
supported = false;
}
}
if (!supported) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Function " + functionName + " only supports (<value expression>) or (<value expression>, 1)\n" + "See Apache DRILL JIRA: DRILL-3596");
throw new UnsupportedOperationException();
}
}
}
}
}
}
// (i.e., BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
if (sqlCall instanceof SqlWindow) {
SqlWindow window = (SqlWindow) sqlCall;
SqlNode lowerBound = window.getLowerBound();
SqlNode upperBound = window.getUpperBound();
// If no frame is specified
// it is a default frame
boolean isSupported = (lowerBound == null && upperBound == null);
// RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
if (window.getOrderList().size() != 0 && !window.isRows() && SqlWindow.isUnboundedPreceding(lowerBound) && (upperBound == null || SqlWindow.isCurrentRow(upperBound) || SqlWindow.isUnboundedFollowing(upperBound))) {
isSupported = true;
}
// is supported with and without the ORDER BY clause
if (window.isRows() && SqlWindow.isUnboundedPreceding(lowerBound) && (upperBound == null || SqlWindow.isCurrentRow(upperBound))) {
isSupported = true;
}
// is supported with and without an ORDER BY clause
if (!window.isRows() && SqlWindow.isCurrentRow(lowerBound) && SqlWindow.isCurrentRow(upperBound)) {
isSupported = true;
}
// ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
if (window.getOrderList().size() == 0 && SqlWindow.isUnboundedPreceding(lowerBound) && SqlWindow.isUnboundedFollowing(upperBound)) {
isSupported = true;
}
if (!isSupported) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "This type of window frame is currently not supported \n" + "See Apache Drill JIRA: DRILL-3188");
throw new UnsupportedOperationException();
}
// DRILL-3189: Disable DISALLOW PARTIAL
if (!window.isAllowPartial()) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Disallowing partial windows is currently not supported \n" + "See Apache Drill JIRA: DRILL-3189");
throw new UnsupportedOperationException();
}
}
// Disable unsupported Intersect, Except
if (sqlCall.getKind() == SqlKind.INTERSECT || sqlCall.getKind() == SqlKind.EXCEPT) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.RELATIONAL, sqlCall.getOperator().getName() + " is not supported\n" + "See Apache Drill JIRA: DRILL-1921");
throw new UnsupportedOperationException();
}
// Disable unsupported JOINs
if (sqlCall.getKind() == SqlKind.JOIN) {
SqlJoin join = (SqlJoin) sqlCall;
// Block Natural Join
if (join.isNatural()) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.RELATIONAL, "NATURAL JOIN is not supported\n" + "See Apache Drill JIRA: DRILL-1986");
throw new UnsupportedOperationException();
}
}
// Disable UNNEST if the configuration disable it
if (sqlCall.getKind() == SqlKind.UNNEST) {
if (!context.getPlannerSettings().isUnnestLateralEnabled()) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.RELATIONAL, "Unnest is not enabled per configuration");
throw new UnsupportedOperationException();
}
}
// Disable Function
for (String strOperator : disabledOperators) {
if (sqlCall.getOperator().isName(strOperator, true)) {
// true is passed to preserve previous behavior
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, sqlCall.getOperator().getName() + " is not supported\n" + "See Apache Drill JIRA: DRILL-2115");
throw new UnsupportedOperationException();
}
}
// Disable complex functions incorrect placement
if (sqlCall instanceof SqlSelect) {
SqlSelect sqlSelect = (SqlSelect) sqlCall;
for (SqlNode nodeInSelectList : sqlSelect.getSelectList()) {
if (checkDirExplorers(nodeInSelectList)) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Directory explorers " + dirExplorers + " functions are not supported in Select List\n" + "See Apache Drill JIRA: DRILL-3944");
throw new UnsupportedOperationException();
}
}
if (sqlSelect.hasWhere()) {
if (checkDirExplorers(sqlSelect.getWhere()) && !context.getPlannerSettings().isConstantFoldingEnabled()) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Directory explorers " + dirExplorers + " functions can not be used " + "when " + PlannerSettings.CONSTANT_FOLDING.getOptionName() + " option is set to false\n" + "See Apache Drill JIRA: DRILL-3944");
throw new UnsupportedOperationException();
}
}
if (sqlSelect.hasOrderBy()) {
for (SqlNode sqlNode : sqlSelect.getOrderList()) {
if (containsFlatten(sqlNode)) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Flatten function is not supported in Order By\n" + "See Apache Drill JIRA: DRILL-2181");
throw new UnsupportedOperationException();
} else if (checkDirExplorers(sqlNode)) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Directory explorers " + dirExplorers + " functions are not supported in Order By\n" + "See Apache Drill JIRA: DRILL-3944");
throw new UnsupportedOperationException();
}
}
}
if (sqlSelect.getGroup() != null) {
for (SqlNode sqlNode : sqlSelect.getGroup()) {
if (containsFlatten(sqlNode)) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Flatten function is not supported in Group By\n" + "See Apache Drill JIRA: DRILL-2181");
throw new UnsupportedOperationException();
} else if (checkDirExplorers(sqlNode)) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Directory explorers " + dirExplorers + " functions are not supported in Group By\n" + "See Apache Drill JIRA: DRILL-3944");
throw new UnsupportedOperationException();
}
}
}
if (sqlSelect.isDistinct()) {
for (SqlNode column : sqlSelect.getSelectList()) {
if (column.getKind() == SqlKind.AS) {
if (containsFlatten(((SqlCall) column).getOperandList().get(0))) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Flatten function is not supported in Distinct\n" + "See Apache Drill JIRA: DRILL-2181");
throw new UnsupportedOperationException();
}
} else {
if (containsFlatten(column)) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Flatten function is not supported in Distinct\n" + "See Apache Drill JIRA: DRILL-2181");
throw new UnsupportedOperationException();
}
}
}
}
}
if (DrillCalciteWrapperUtility.extractSqlOperatorFromWrapper(sqlCall.getOperator()) instanceof SqlCountAggFunction) {
for (SqlNode sqlNode : sqlCall.getOperandList()) {
if (containsFlatten(sqlNode)) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION, "Flatten function in aggregate functions is not supported\n" + "See Apache Drill JIRA: DRILL-2181");
throw new UnsupportedOperationException();
}
}
}
return sqlCall.getOperator().acceptCall(this, sqlCall);
}
Aggregations