blob: 1bbf550fecc814bdb31fc1da020bab1b3b9c0a63 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF 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.
*/
package org.apache.pinot.core.operator.transform.function;
import com.google.common.base.Preconditions;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;
import org.apache.pinot.core.operator.blocks.ProjectionBlock;
import org.apache.pinot.core.operator.transform.TransformResultMetadata;
import org.apache.pinot.segment.spi.datasource.DataSource;
import org.apache.pinot.spi.data.FieldSpec;
public class TruncateDecimalTransformFunction extends BaseTransformFunction {
public static final String FUNCTION_NAME = "truncate";
private TransformFunction _leftTransformFunction;
private TransformFunction _rightTransformFunction;
private int _scale;
private boolean _fixedScale;
@Override
public String getName() {
return FUNCTION_NAME;
}
@Override
public void init(List<TransformFunction> arguments, Map<String, DataSource> dataSourceMap) {
int numArguments = arguments.size();
// Check that there are more than 2 arguments or no arguments
if (numArguments < 1 || numArguments > 2) {
throw new IllegalArgumentException(
"truncate transform function supports either 1 or 2 arguments. Num arguments provided: " + numArguments);
}
_fixedScale = false;
_leftTransformFunction = arguments.get(0);
if (numArguments > 1) {
_rightTransformFunction = arguments.get(1);
if (_rightTransformFunction instanceof LiteralTransformFunction) {
_scale = Integer.parseInt(((LiteralTransformFunction) _rightTransformFunction).getLiteral());
_fixedScale = true;
}
Preconditions.checkArgument(
_rightTransformFunction.getResultMetadata().isSingleValue() && isIntegralResultDatatype(
_rightTransformFunction), "Argument must be single-valued with type INT for transform function: %s",
getName());
} else {
_rightTransformFunction = null;
}
Preconditions.checkArgument(_leftTransformFunction.getResultMetadata().isSingleValue(),
"Argument must be single-valued for transform function: %s", getName());
}
private boolean isIntegralResultDatatype(TransformFunction transformFunction) {
return transformFunction.getResultMetadata().getDataType().getStoredType() == FieldSpec.DataType.INT
|| transformFunction.getResultMetadata().getDataType().getStoredType() == FieldSpec.DataType.LONG;
}
@Override
public TransformResultMetadata getResultMetadata() {
return DOUBLE_SV_NO_DICTIONARY_METADATA;
}
@Override
public double[] transformToDoubleValuesSV(ProjectionBlock projectionBlock) {
int length = projectionBlock.getNumDocs();
if (_doubleValuesSV == null || _doubleValuesSV.length < length) {
_doubleValuesSV = new double[length];
}
double[] leftValues = _leftTransformFunction.transformToDoubleValuesSV(projectionBlock);
if (_fixedScale) {
for (int i = 0; i < length; i++) {
_doubleValuesSV[i] = BigDecimal.valueOf(leftValues[i])
.setScale(_scale, RoundingMode.DOWN).doubleValue();
}
} else if (_rightTransformFunction != null) {
int[] rightValues = _rightTransformFunction.transformToIntValuesSV(projectionBlock);
for (int i = 0; i < length; i++) {
_doubleValuesSV[i] = BigDecimal.valueOf(leftValues[i])
.setScale(rightValues[i], RoundingMode.DOWN).doubleValue();
}
} else {
for (int i = 0; i < length; i++) {
_doubleValuesSV[i] = Math.signum(leftValues[i]) * Math.floor(Math.abs(leftValues[i]));
}
}
return _doubleValuesSV;
}
}