Search in sources :

Example 6 with FunctionHandle

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())));
}
Also used : FunctionAndTypeManager.createTestFunctionAndTypeManager(io.prestosql.metadata.FunctionAndTypeManager.createTestFunctionAndTypeManager) TypeSignature.parseTypeSignature(io.prestosql.spi.type.TypeSignature.parseTypeSignature) TypeSignature(io.prestosql.spi.type.TypeSignature) Signature(io.prestosql.spi.function.Signature) LiteralEncoder.getMagicLiteralFunctionSignature(io.prestosql.sql.planner.LiteralEncoder.getMagicLiteralFunctionSignature) BuiltInFunctionHandle(io.prestosql.spi.function.BuiltInFunctionHandle) BuiltInFunctionHandle(io.prestosql.spi.function.BuiltInFunctionHandle) FunctionHandle(io.prestosql.spi.function.FunctionHandle) Test(org.testng.annotations.Test)

Example 7 with FunctionHandle

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);
}
Also used : RowExpressionDeterminismEvaluator(io.prestosql.sql.relational.RowExpressionDeterminismEvaluator) VariableReferenceExpression(io.prestosql.spi.relation.VariableReferenceExpression) LogicalRowExpressions(io.prestosql.expressions.LogicalRowExpressions) ConstantExpression(io.prestosql.spi.relation.ConstantExpression) RowExpression(io.prestosql.spi.relation.RowExpression) FunctionResolution(io.prestosql.sql.relational.FunctionResolution) FunctionHandle(io.prestosql.spi.function.FunctionHandle) Test(org.testng.annotations.Test)

Example 8 with FunctionHandle

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);
}
Also used : RowExpressionDeterminismEvaluator(io.prestosql.sql.relational.RowExpressionDeterminismEvaluator) VariableReferenceExpression(io.prestosql.spi.relation.VariableReferenceExpression) LogicalRowExpressions(io.prestosql.expressions.LogicalRowExpressions) ConstantExpression(io.prestosql.spi.relation.ConstantExpression) RowExpression(io.prestosql.spi.relation.RowExpression) FunctionResolution(io.prestosql.sql.relational.FunctionResolution) FunctionHandle(io.prestosql.spi.function.FunctionHandle) Test(org.testng.annotations.Test)

Example 9 with FunctionHandle

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;
}
Also used : LabelNode(io.airlift.bytecode.instruction.LabelNode) FunctionMetadata(io.prestosql.spi.function.FunctionMetadata) IfStatement(io.airlift.bytecode.control.IfStatement) CastType(io.prestosql.metadata.CastType) Type(io.prestosql.spi.type.Type) Variable(io.airlift.bytecode.Variable) Scope(io.airlift.bytecode.Scope) FunctionAndTypeManager(io.prestosql.metadata.FunctionAndTypeManager) BuiltInScalarFunctionImplementation(io.prestosql.spi.function.BuiltInScalarFunctionImplementation) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) RowExpression(io.prestosql.spi.relation.RowExpression) BytecodeNode(io.airlift.bytecode.BytecodeNode) FunctionHandle(io.prestosql.spi.function.FunctionHandle)

Example 10 with FunctionHandle

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;
}
Also used : LabelNode(io.airlift.bytecode.instruction.LabelNode) Variable(io.airlift.bytecode.Variable) ImmutableList(com.google.common.collect.ImmutableList) ConstantExpression(io.prestosql.spi.relation.ConstantExpression) IfStatement(io.airlift.bytecode.control.IfStatement) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableListMultimap(com.google.common.collect.ImmutableListMultimap) BytecodeNode(io.airlift.bytecode.BytecodeNode) FunctionHandle(io.prestosql.spi.function.FunctionHandle) BuiltInScalarFunctionImplementation(io.prestosql.spi.function.BuiltInScalarFunctionImplementation) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) RowExpression(io.prestosql.spi.relation.RowExpression) BigintType(io.prestosql.spi.type.BigintType) Type(io.prestosql.spi.type.Type) IntegerType(io.prestosql.spi.type.IntegerType) DateType(io.prestosql.spi.type.DateType) Scope(io.airlift.bytecode.Scope) SwitchBuilder(io.airlift.bytecode.control.SwitchStatement.SwitchBuilder) Collection(java.util.Collection) Map(java.util.Map) MethodHandle(java.lang.invoke.MethodHandle)

Aggregations

FunctionHandle (io.prestosql.spi.function.FunctionHandle)49 RowExpression (io.prestosql.spi.relation.RowExpression)24 CallExpression (io.prestosql.spi.relation.CallExpression)21 Type (io.prestosql.spi.type.Type)21 BuiltInFunctionHandle (io.prestosql.spi.function.BuiltInFunctionHandle)13 Symbol (io.prestosql.spi.plan.Symbol)13 ConstantExpression (io.prestosql.spi.relation.ConstantExpression)13 ImmutableList (com.google.common.collect.ImmutableList)11 Test (org.testng.annotations.Test)11 PrestoException (io.prestosql.spi.PrestoException)10 BuiltInScalarFunctionImplementation (io.prestosql.spi.function.BuiltInScalarFunctionImplementation)10 Signature (io.prestosql.spi.function.Signature)10 VariableReferenceExpression (io.prestosql.spi.relation.VariableReferenceExpression)10 PlanNode (io.prestosql.spi.plan.PlanNode)9 Map (java.util.Map)9 List (java.util.List)8 ArrayList (java.util.ArrayList)7 Optional (java.util.Optional)7 BytecodeBlock (io.airlift.bytecode.BytecodeBlock)6 Variable (io.airlift.bytecode.Variable)6