use of io.prestosql.spi.function.FunctionHandle in project hetu-core by openlookeng.
the class TestFunctionAndTypeManager method testIdentityCast.
@Test
public void testIdentityCast() {
FunctionAndTypeManager functionAndTypeManager = createTestFunctionAndTypeManager();
FunctionHandle exactOperator = functionAndTypeManager.lookupCast(CastType.CAST, HYPER_LOG_LOG.getTypeSignature(), HYPER_LOG_LOG.getTypeSignature());
assertEquals(exactOperator, new BuiltInFunctionHandle(new Signature(CAST.getFunctionName(), SCALAR, HYPER_LOG_LOG.getTypeSignature(), HYPER_LOG_LOG.getTypeSignature())));
}
use of io.prestosql.spi.function.FunctionHandle in project hetu-core by openlookeng.
the class TestDynamicFilters method testExtractStaticFilters.
@Test
public void testExtractStaticFilters() {
LogicalRowExpressions logicalRowExpressions = new LogicalRowExpressions(new RowExpressionDeterminismEvaluator(metadata), new FunctionResolution(metadata.getFunctionAndTypeManager()), metadata.getFunctionAndTypeManager());
ConstantExpression staticExpression = new ConstantExpression(utf8Slice("age"), VarcharType.VARCHAR);
VariableReferenceExpression variableExpression = new VariableReferenceExpression("col", VarcharType.VARCHAR);
FunctionHandle functionHandle = metadata.getFunctionAndTypeManager().lookupFunction("rank", ImmutableList.of());
RowExpression dynamicFilterExpression = call(DynamicFilters.Function.NAME, functionHandle, staticExpression.getType(), asList(staticExpression, variableExpression), Optional.empty());
RowExpression combinedExpression = logicalRowExpressions.combineConjuncts(staticExpression, dynamicFilterExpression);
Optional<RowExpression> extractedExpression = DynamicFilters.extractStaticFilters(Optional.of(combinedExpression), metadata);
assertEquals(extractedExpression.get(), staticExpression);
RowExpression combinedStaticExpression = logicalRowExpressions.combineConjuncts(staticExpression, variableExpression);
combinedExpression = logicalRowExpressions.combineConjuncts(staticExpression, variableExpression, dynamicFilterExpression);
extractedExpression = DynamicFilters.extractStaticFilters(Optional.of(combinedExpression), metadata);
assertEquals(extractedExpression.get(), combinedStaticExpression);
}
use of io.prestosql.spi.function.FunctionHandle in project hetu-core by openlookeng.
the class TestDynamicFilters method testExtractDynamicFilterExpression.
@Test
public void testExtractDynamicFilterExpression() {
LogicalRowExpressions logicalRowExpressions = new LogicalRowExpressions(new RowExpressionDeterminismEvaluator(metadata), new FunctionResolution(metadata.getFunctionAndTypeManager()), metadata.getFunctionAndTypeManager());
ConstantExpression staticExpression1 = new ConstantExpression(utf8Slice("age"), VarcharType.VARCHAR);
VariableReferenceExpression variableExpression1 = new VariableReferenceExpression("col", VarcharType.VARCHAR);
ConstantExpression staticExpression2 = new ConstantExpression(utf8Slice("age"), VarcharType.VARCHAR);
VariableReferenceExpression variableExpression2 = new VariableReferenceExpression("col", VarcharType.VARCHAR);
FunctionHandle functionHandle = metadata.getFunctionAndTypeManager().lookupFunction("rank", ImmutableList.of());
RowExpression dynamicFilterExpression1 = call(DynamicFilters.Function.NAME, functionHandle, staticExpression1.getType(), asList(staticExpression1, variableExpression1), Optional.empty());
RowExpression dynamicFilterExpression2 = call(DynamicFilters.Function.NAME, functionHandle, staticExpression2.getType(), asList(staticExpression2, variableExpression2), Optional.empty());
RowExpression combineDynamicFilterExpression = logicalRowExpressions.combineDisjuncts(asList(dynamicFilterExpression1, dynamicFilterExpression2));
RowExpression combinedExpression = logicalRowExpressions.combineConjuncts(staticExpression1, combineDynamicFilterExpression);
RowExpression extractedExpression = DynamicFilters.extractDynamicFilterExpression(combinedExpression, metadata);
assertEquals(extractedExpression, combineDynamicFilterExpression);
}
use of io.prestosql.spi.function.FunctionHandle in project hetu-core by openlookeng.
the class NullIfCodeGenerator method generateExpression.
@Override
public BytecodeNode generateExpression(FunctionHandle functionHandle, BytecodeGeneratorContext generatorContext, Type returnType, List<RowExpression> arguments) {
Scope scope = generatorContext.getScope();
RowExpression first = arguments.get(0);
RowExpression second = arguments.get(1);
LabelNode notMatch = new LabelNode("notMatch");
// push first arg on the stack
Variable firstValue = scope.createTempVariable(first.getType().getJavaType());
BytecodeBlock block = new BytecodeBlock().comment("check if first arg is null").append(generatorContext.generate(first)).append(ifWasNullPopAndGoto(scope, notMatch, void.class)).dup(first.getType().getJavaType()).putVariable(firstValue);
Type firstType = first.getType();
Type secondType = second.getType();
// if (equal(cast(first as <common type>), cast(second as <common type>))
FunctionAndTypeManager functionAndTypeManager = generatorContext.getFunctionManager();
FunctionHandle equalFunction = functionAndTypeManager.resolveOperatorFunctionHandle(EQUAL, TypeSignatureProvider.fromTypes(firstType, secondType));
FunctionMetadata equalFunctionMetadata = functionAndTypeManager.getFunctionMetadata(equalFunction);
BuiltInScalarFunctionImplementation equalsFunction = generatorContext.getFunctionManager().getBuiltInScalarFunctionImplementation(equalFunction);
BytecodeNode equalsCall = generatorContext.generateCall(EQUAL.name(), equalsFunction, ImmutableList.of(cast(generatorContext, firstValue, firstType, equalFunctionMetadata.getArgumentTypes().get(0)), cast(generatorContext, generatorContext.generate(second, Optional.empty()), secondType, equalFunctionMetadata.getArgumentTypes().get(1))));
BytecodeBlock conditionBlock = new BytecodeBlock().append(equalsCall).append(BytecodeUtils.ifWasNullClearPopAndGoto(scope, notMatch, void.class, boolean.class));
// if first and second are equal, return null
BytecodeBlock trueBlock = new BytecodeBlock().append(generatorContext.wasNull().set(constantTrue())).pop(first.getType().getJavaType()).pushJavaDefault(first.getType().getJavaType());
// else return first (which is still on the stack
block.append(new IfStatement().condition(conditionBlock).ifTrue(trueBlock).ifFalse(notMatch));
return block;
}
use of io.prestosql.spi.function.FunctionHandle in project hetu-core by openlookeng.
the class InCodeGenerator method generateExpression.
@Override
public BytecodeNode generateExpression(FunctionHandle functionHandle, BytecodeGeneratorContext generatorContext, Type returnType, List<RowExpression> arguments) {
List<RowExpression> values = arguments.subList(1, arguments.size());
// empty IN statements are not allowed by the standard, and not possible here
// the implementation assumes this condition is always met
checkArgument(values.size() > 0, "values must not be empty");
Type type = arguments.get(0).getType();
Class<?> javaType = type.getJavaType();
SwitchGenerationCase switchGenerationCase = checkSwitchGenerationCase(type, values);
FunctionHandle hashCodeHandle = generatorContext.getFunctionManager().resolveOperatorFunctionHandle(HASH_CODE, fromTypes(type));
MethodHandle hashCodeFunction = generatorContext.getFunctionManager().getBuiltInScalarFunctionImplementation(hashCodeHandle).getMethodHandle();
FunctionHandle isIndeterminateHandle = generatorContext.getFunctionManager().resolveOperatorFunctionHandle(INDETERMINATE, fromTypes(type));
BuiltInScalarFunctionImplementation isIndeterminateFunction = generatorContext.getFunctionManager().getBuiltInScalarFunctionImplementation(isIndeterminateHandle);
ImmutableListMultimap.Builder<Integer, BytecodeNode> hashBucketsBuilder = ImmutableListMultimap.builder();
ImmutableList.Builder<BytecodeNode> defaultBucket = ImmutableList.builder();
ImmutableSet.Builder<Object> constantValuesBuilder = ImmutableSet.builder();
for (RowExpression testValue : values) {
BytecodeNode testBytecode = generatorContext.generate(testValue);
if (isDeterminateConstant(testValue, isIndeterminateFunction.getMethodHandle())) {
ConstantExpression constant = (ConstantExpression) testValue;
Object object = constant.getValue();
switch(switchGenerationCase) {
case DIRECT_SWITCH:
case SET_CONTAINS:
constantValuesBuilder.add(object);
break;
case HASH_SWITCH:
try {
int hashCode = toIntExact(Long.hashCode((Long) hashCodeFunction.invoke(object)));
hashBucketsBuilder.put(hashCode, testBytecode);
} catch (Throwable throwable) {
throw new IllegalArgumentException("Error processing IN statement: error calculating hash code for " + object, throwable);
}
break;
default:
throw new IllegalArgumentException("Not supported switch generation case: " + switchGenerationCase);
}
} else {
defaultBucket.add(testBytecode);
}
}
ImmutableListMultimap<Integer, BytecodeNode> hashBuckets = hashBucketsBuilder.build();
ImmutableSet<Object> constantValues = constantValuesBuilder.build();
LabelNode end = new LabelNode("end");
LabelNode match = new LabelNode("match");
LabelNode noMatch = new LabelNode("noMatch");
LabelNode defaultLabel = new LabelNode("default");
Scope scope = generatorContext.getScope();
Variable value = scope.createTempVariable(javaType);
BytecodeNode switchBlock;
Variable expression = scope.createTempVariable(int.class);
SwitchBuilder switchBuilder = new SwitchBuilder().expression(expression);
switch(switchGenerationCase) {
case DIRECT_SWITCH:
// For these types, it's safe to not use presto HASH_CODE and EQUAL operator.
for (Object constantValue : constantValues) {
switchBuilder.addCase(toIntExact((Long) constantValue), jump(match));
}
switchBuilder.defaultCase(jump(defaultLabel));
switchBlock = new BytecodeBlock().comment("lookupSwitch(<stackValue>))").append(new IfStatement().condition(invokeStatic(InCodeGenerator.class, "isInteger", boolean.class, value)).ifFalse(new BytecodeBlock().gotoLabel(defaultLabel))).append(expression.set(value.cast(int.class))).append(switchBuilder.build());
break;
case HASH_SWITCH:
for (Map.Entry<Integer, Collection<BytecodeNode>> bucket : hashBuckets.asMap().entrySet()) {
Collection<BytecodeNode> testValues = bucket.getValue();
BytecodeBlock caseBlock = buildInCase(generatorContext, scope, type, match, defaultLabel, value, testValues, false, isIndeterminateFunction);
switchBuilder.addCase(bucket.getKey(), caseBlock);
}
switchBuilder.defaultCase(jump(defaultLabel));
Binding hashCodeBinding = generatorContext.getCallSiteBinder().bind(hashCodeFunction);
switchBlock = new BytecodeBlock().comment("lookupSwitch(hashCode(<stackValue>))").getVariable(value).append(invoke(hashCodeBinding, HASH_CODE.name())).invokeStatic(Long.class, "hashCode", int.class, long.class).putVariable(expression).append(switchBuilder.build());
break;
case SET_CONTAINS:
Set<?> constantValuesSet = toFastutilHashSet(constantValues, type, metadata);
Binding constant = generatorContext.getCallSiteBinder().bind(constantValuesSet, constantValuesSet.getClass());
switchBlock = new BytecodeBlock().comment("inListSet.contains(<stackValue>)").append(new IfStatement().condition(new BytecodeBlock().comment("value").getVariable(value).comment("set").append(loadConstant(constant)).invokeStatic(FastutilSetHelper.class, "in", boolean.class, javaType.isPrimitive() ? javaType : Object.class, constantValuesSet.getClass())).ifTrue(jump(match)));
break;
default:
throw new IllegalArgumentException("Not supported switch generation case: " + switchGenerationCase);
}
BytecodeBlock defaultCaseBlock = buildInCase(generatorContext, scope, type, match, noMatch, value, defaultBucket.build(), true, isIndeterminateFunction).setDescription("default");
BytecodeBlock block = new BytecodeBlock().comment("IN").append(generatorContext.generate(arguments.get(0))).append(ifWasNullPopAndGoto(scope, end, boolean.class, javaType)).putVariable(value).append(switchBlock).visitLabel(defaultLabel).append(defaultCaseBlock);
BytecodeBlock matchBlock = new BytecodeBlock().setDescription("match").visitLabel(match).append(generatorContext.wasNull().set(constantFalse())).push(true).gotoLabel(end);
block.append(matchBlock);
BytecodeBlock noMatchBlock = new BytecodeBlock().setDescription("noMatch").visitLabel(noMatch).push(false).gotoLabel(end);
block.append(noMatchBlock);
block.visitLabel(end);
return block;
}
Aggregations