use of org.apache.drill.common.exceptions.DrillRuntimeException in project drill by axbaretto.
the class JoinUtils method addLeastRestrictiveCasts.
/**
* Utility method used by joins to add implicit casts on one of the sides of the join condition in case the two
* expressions have different types.
* @param leftExpressions array of expressions from left input into the join
* @param leftBatch left input record batch
* @param rightExpressions array of expressions from right input into the join
* @param rightBatch right input record batch
* @param context fragment context
*/
public static void addLeastRestrictiveCasts(LogicalExpression[] leftExpressions, VectorAccessible leftBatch, LogicalExpression[] rightExpressions, VectorAccessible rightBatch, FragmentContext context) {
assert rightExpressions.length == leftExpressions.length;
for (int i = 0; i < rightExpressions.length; i++) {
LogicalExpression rightExpression = rightExpressions[i];
LogicalExpression leftExpression = leftExpressions[i];
TypeProtos.MinorType rightType = rightExpression.getMajorType().getMinorType();
TypeProtos.MinorType leftType = leftExpression.getMajorType().getMinorType();
if (rightType == TypeProtos.MinorType.UNION || leftType == TypeProtos.MinorType.UNION) {
continue;
}
if (rightType != leftType) {
// currently we only support implicit casts if the input types are numeric or varchar/varbinary
if (!allowImplicitCast(rightType, leftType)) {
throw new DrillRuntimeException(String.format("Join only supports implicit casts between " + "1. Numeric data\n 2. Varchar, Varbinary data 3. Date, Timestamp data " + "Left type: %s, Right type: %s. Add explicit casts to avoid this error", leftType, rightType));
}
// We need to add a cast to one of the expressions
List<TypeProtos.MinorType> types = new LinkedList<>();
types.add(rightType);
types.add(leftType);
TypeProtos.MinorType result = TypeCastRules.getLeastRestrictiveType(types);
ErrorCollector errorCollector = new ErrorCollectorImpl();
if (result == null) {
throw new DrillRuntimeException(String.format("Join conditions cannot be compared failing left " + "expression:" + " %s failing right expression: %s", leftExpression.getMajorType().toString(), rightExpression.getMajorType().toString()));
} else if (result != rightType) {
// Add a cast expression on top of the right expression
LogicalExpression castExpr = ExpressionTreeMaterializer.addCastExpression(rightExpression, leftExpression.getMajorType(), context.getFunctionRegistry(), errorCollector);
// Store the newly casted expression
rightExpressions[i] = ExpressionTreeMaterializer.materialize(castExpr, rightBatch, errorCollector, context.getFunctionRegistry());
} else if (result != leftType) {
// Add a cast expression on top of the left expression
LogicalExpression castExpr = ExpressionTreeMaterializer.addCastExpression(leftExpression, rightExpression.getMajorType(), context.getFunctionRegistry(), errorCollector);
// store the newly casted expression
leftExpressions[i] = ExpressionTreeMaterializer.materialize(castExpr, leftBatch, errorCollector, context.getFunctionRegistry());
}
}
}
}
use of org.apache.drill.common.exceptions.DrillRuntimeException in project drill by axbaretto.
the class UnionAllRecordBatch method inferOutputFieldsBothSide.
// The output table's column names always follow the left table,
// where the output type is chosen based on DRILL's implicit casting rules
private void inferOutputFieldsBothSide(final BatchSchema leftSchema, final BatchSchema rightSchema) {
// outputFields = Lists.newArrayList();
final Iterator<MaterializedField> leftIter = leftSchema.iterator();
final Iterator<MaterializedField> rightIter = rightSchema.iterator();
int index = 1;
while (leftIter.hasNext() && rightIter.hasNext()) {
MaterializedField leftField = leftIter.next();
MaterializedField rightField = rightIter.next();
if (leftField.hasSameTypeAndMode(rightField)) {
TypeProtos.MajorType.Builder builder = TypeProtos.MajorType.newBuilder().setMinorType(leftField.getType().getMinorType()).setMode(leftField.getDataMode());
builder = Types.calculateTypePrecisionAndScale(leftField.getType(), rightField.getType(), builder);
container.addOrGet(MaterializedField.create(leftField.getName(), builder.build()), callBack);
} else if (Types.isUntypedNull(rightField.getType())) {
container.addOrGet(leftField, callBack);
} else if (Types.isUntypedNull(leftField.getType())) {
container.addOrGet(MaterializedField.create(leftField.getName(), rightField.getType()), callBack);
} else {
// If the output type is not the same,
// cast the column of one of the table to a data type which is the Least Restrictive
TypeProtos.MajorType.Builder builder = TypeProtos.MajorType.newBuilder();
if (leftField.getType().getMinorType() == rightField.getType().getMinorType()) {
builder.setMinorType(leftField.getType().getMinorType());
builder = Types.calculateTypePrecisionAndScale(leftField.getType(), rightField.getType(), builder);
} else {
List<TypeProtos.MinorType> types = Lists.newLinkedList();
types.add(leftField.getType().getMinorType());
types.add(rightField.getType().getMinorType());
TypeProtos.MinorType outputMinorType = TypeCastRules.getLeastRestrictiveType(types);
if (outputMinorType == null) {
throw new DrillRuntimeException("Type mismatch between " + leftField.getType().getMinorType().toString() + " on the left side and " + rightField.getType().getMinorType().toString() + " on the right side in column " + index + " of UNION ALL");
}
builder.setMinorType(outputMinorType);
}
// The output data mode should be as flexible as the more flexible one from the two input tables
List<TypeProtos.DataMode> dataModes = Lists.newLinkedList();
dataModes.add(leftField.getType().getMode());
dataModes.add(rightField.getType().getMode());
builder.setMode(TypeCastRules.getLeastRestrictiveDataMode(dataModes));
container.addOrGet(MaterializedField.create(leftField.getName(), builder.build()), callBack);
}
++index;
}
assert !leftIter.hasNext() && !rightIter.hasNext() : "Mis-match of column count should have been detected when validating sqlNode at planning";
}
use of org.apache.drill.common.exceptions.DrillRuntimeException in project drill by axbaretto.
the class SortRecordBatchBuilder method add.
@SuppressWarnings("resource")
public void add(RecordBatchData rbd) {
long batchBytes = getSize(rbd.getContainer());
if (batchBytes == 0 && batches.size() > 0) {
return;
}
if (runningBatches >= Character.MAX_VALUE) {
final String errMsg = String.format("Tried to add more than %d number of batches.", (int) Character.MAX_VALUE);
logger.error(errMsg);
throw new DrillRuntimeException(errMsg);
}
if (!reservation.add(rbd.getRecordCount() * 4)) {
final String errMsg = String.format("Failed to pre-allocate memory for SV. " + "Existing recordCount*4 = %d, " + "incoming batch recordCount*4 = %d", recordCount * 4, rbd.getRecordCount() * 4);
logger.error(errMsg);
throw new DrillRuntimeException(errMsg);
}
if (rbd.getRecordCount() == 0 && batches.size() > 0) {
rbd.getContainer().zeroVectors();
SelectionVector2 sv2 = rbd.getSv2();
if (sv2 != null) {
sv2.clear();
}
return;
}
runningBatches++;
batches.put(rbd.getContainer().getSchema(), rbd);
recordCount += rbd.getRecordCount();
}
use of org.apache.drill.common.exceptions.DrillRuntimeException in project drill by axbaretto.
the class DrillPushProjectIntoScanRule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
final Project project = call.rel(0);
final TableScan scan = call.rel(1);
try {
if (scan.getRowType().getFieldList().isEmpty()) {
return;
}
ProjectPushInfo projectPushInfo = getFieldsInformation(scan.getRowType(), project.getProjects());
if (!canPushProjectIntoScan(scan.getTable(), projectPushInfo)) {
return;
}
final DrillScanRel newScan = new DrillScanRel(scan.getCluster(), scan.getTraitSet().plus(DrillRel.DRILL_LOGICAL), scan.getTable(), projectPushInfo.createNewRowType(project.getInput().getCluster().getTypeFactory()), projectPushInfo.getFields());
List<RexNode> newProjects = new ArrayList<>();
for (RexNode n : project.getChildExps()) {
newProjects.add(n.accept(projectPushInfo.getInputReWriter()));
}
final DrillProjectRel newProject = new DrillProjectRel(project.getCluster(), project.getTraitSet().plus(DrillRel.DRILL_LOGICAL), newScan, newProjects, project.getRowType());
if (ProjectRemoveRule.isTrivial(newProject)) {
call.transformTo(newScan);
} else {
call.transformTo(newProject);
}
} catch (IOException e) {
throw new DrillRuntimeException(e);
}
}
use of org.apache.drill.common.exceptions.DrillRuntimeException in project drill by axbaretto.
the class CreateFunctionHandler method initRemoteRegistration.
/**
* Instantiates remote registration. First gets remote function registry with version.
* Version is used to ensure that we update the same registry we validated against.
* Then validates against list of remote jars.
* If validation is successful, first copies jars to registry area and starts updating remote function registry.
* If during update {@link VersionMismatchException} was detected,
* attempts to repeat remote registration process till retry attempts exceeds the limit.
* If retry attempts number hits 0, throws exception that failed to update remote function registry.
* In case of any error, if jars have been already copied to registry area, they will be deleted.
*
* @param functions list of functions present in jar
* @param jarManager helper class for copying jars to registry area
* @param remoteRegistry remote function registry
* @throws IOException in case of problems with copying jars to registry area
*/
private void initRemoteRegistration(List<String> functions, JarManager jarManager, RemoteFunctionRegistry remoteRegistry) throws IOException {
int retryAttempts = remoteRegistry.getRetryAttempts();
boolean copyJars = true;
try {
while (retryAttempts >= 0) {
DataChangeVersion version = new DataChangeVersion();
List<Jar> remoteJars = remoteRegistry.getRegistry(version).getJarList();
validateAgainstRemoteRegistry(remoteJars, jarManager.getBinaryName(), functions);
if (copyJars) {
jarManager.copyToRegistryArea();
copyJars = false;
}
List<Jar> jars = Lists.newArrayList(remoteJars);
jars.add(Jar.newBuilder().setName(jarManager.getBinaryName()).addAllFunctionSignature(functions).build());
Registry updatedRegistry = Registry.newBuilder().addAllJar(jars).build();
try {
remoteRegistry.updateRegistry(updatedRegistry, version);
return;
} catch (VersionMismatchException ex) {
logger.debug("Failed to update function registry during registration, version mismatch was detected.", ex);
retryAttempts--;
}
}
throw new DrillRuntimeException("Failed to update remote function registry. Exceeded retry attempts limit.");
} catch (Exception e) {
if (!copyJars) {
jarManager.deleteQuietlyFromRegistryArea();
}
throw e;
}
}
Aggregations