Search in sources :

Example 71 with RexCall

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexCall in project beam by apache.

the class CEPCall method of.

public static CEPCall of(RexCall operation) {
    SqlOperator call = operation.getOperator();
    CEPOperator myOp = CEPOperator.of(call);
    ArrayList<CEPOperation> operandsList = new ArrayList<>();
    for (RexNode i : operation.getOperands()) {
        if (i.getClass() == RexCall.class) {
            CEPCall callToAdd = CEPCall.of((RexCall) i);
            operandsList.add(callToAdd);
        } else if (i.getClass() == RexLiteral.class) {
            RexLiteral lit = (RexLiteral) i;
            CEPLiteral litToAdd = CEPLiteral.of(lit);
            operandsList.add(litToAdd);
        } else if (i.getClass() == RexPatternFieldRef.class) {
            RexPatternFieldRef fieldRef = (RexPatternFieldRef) i;
            CEPFieldRef fieldRefToAdd = CEPFieldRef.of(fieldRef);
            operandsList.add(fieldRefToAdd);
        } else {
            throw new UnsupportedOperationException("RexNode not supported: " + i.getClass().getName());
        }
    }
    return new CEPCall(myOp, operandsList);
}
Also used : RexLiteral(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexLiteral) SqlOperator(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlOperator) ArrayList(java.util.ArrayList) RexPatternFieldRef(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexPatternFieldRef) RexNode(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode)

Example 72 with RexCall

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexCall in project beam by apache.

the class BeamCalcRelType method canImplement.

@Override
protected boolean canImplement(RexCall call) {
    final SqlOperator operator = call.getOperator();
    RexImpTable.RexCallImplementor implementor = RexImpTable.INSTANCE.get(operator);
    if (implementor == null) {
        // Reject methods with no implementation
        return false;
    }
    if (operator instanceof SqlUserDefinedFunction) {
        SqlUserDefinedFunction udf = (SqlUserDefinedFunction) call.op;
        if (udf.function instanceof ZetaSqlScalarFunctionImpl) {
            ZetaSqlScalarFunctionImpl scalarFunction = (ZetaSqlScalarFunctionImpl) udf.function;
            if (!scalarFunction.functionGroup.equals(BeamZetaSqlCatalog.USER_DEFINED_JAVA_SCALAR_FUNCTIONS)) {
                // Reject ZetaSQL Builtin Scalar Functions
                return false;
            }
            for (RexNode operand : call.getOperands()) {
                if (operand instanceof RexLocalRef) {
                    if (!supportsType(operand.getType())) {
                        LOG.error("User-defined function {} received unsupported operand type {}.", call.op.getName(), ((RexLocalRef) operand).getType());
                        return false;
                    }
                } else {
                    LOG.error("User-defined function {} received unrecognized operand kind {}.", call.op.getName(), operand.getKind());
                    return false;
                }
            }
        } else {
            // Reject other UDFs
            return false;
        }
    } else {
        // Reject Calcite implementations
        return false;
    }
    return true;
}
Also used : SqlUserDefinedFunction(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.validate.SqlUserDefinedFunction) ZetaSqlScalarFunctionImpl(org.apache.beam.sdk.extensions.sql.zetasql.translation.ZetaSqlScalarFunctionImpl) SqlOperator(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlOperator) RexLocalRef(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexLocalRef) RexImpTable(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.adapter.enumerable.RexImpTable) RexNode(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode)

Example 73 with RexCall

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexCall in project beam by apache.

the class CEPUtils method getCEPPatternFromPattern.

/**
 * Construct a list of {@code CEPPattern}s from a {@code RexNode}.
 */
public static ArrayList<CEPPattern> getCEPPatternFromPattern(Schema upStreamSchema, RexNode call, Map<String, RexNode> patternDefs) {
    ArrayList<CEPPattern> patternList = new ArrayList<>();
    if (call.getClass() == RexLiteral.class) {
        String p = ((RexLiteral) call).getValueAs(String.class);
        RexNode pd = patternDefs.get(p);
        patternList.add(CEPPattern.of(upStreamSchema, p, (RexCall) pd, Quantifier.NONE));
    } else {
        RexCall patCall = (RexCall) call;
        SqlOperator operator = patCall.getOperator();
        List<RexNode> operands = patCall.getOperands();
        // check if the node has quantifier
        if (operator.getKind() == SqlKind.PATTERN_QUANTIFIER) {
            String p = ((RexLiteral) operands.get(0)).getValueAs(String.class);
            RexNode pd = patternDefs.get(p);
            int start = ((RexLiteral) operands.get(1)).getValueAs(Integer.class);
            int end = ((RexLiteral) operands.get(2)).getValueAs(Integer.class);
            boolean isReluctant = ((RexLiteral) operands.get(3)).getValueAs(Boolean.class);
            patternList.add(CEPPattern.of(upStreamSchema, p, (RexCall) pd, getQuantifier(start, end, isReluctant)));
        } else {
            for (RexNode i : operands) {
                patternList.addAll(getCEPPatternFromPattern(upStreamSchema, i, patternDefs));
            }
        }
    }
    return patternList;
}
Also used : RexCall(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexCall) RexLiteral(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexLiteral) SqlOperator(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlOperator) ArrayList(java.util.ArrayList) RexNode(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode)

Example 74 with RexCall

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexCall in project beam by apache.

the class MongoDbTable method translateRexNodeToBson.

/**
 * Recursively translates a single RexNode to MongoDB Bson filter. Supports simple comparison
 * operations, negation, and nested conjunction/disjunction. Boolean fields are translated as an
 * `$eq` operation with a boolean `true`.
 *
 * @param node {@code RexNode} to translate.
 * @return {@code Bson} filter.
 */
private Bson translateRexNodeToBson(RexNode node) {
    final IntFunction<String> fieldIdToName = i -> getSchema().getField(i).getName();
    // Supported operations are described in MongoDbFilter#isSupported
    if (node instanceof RexCall) {
        RexCall compositeNode = (RexCall) node;
        List<RexLiteral> literals = new ArrayList<>();
        List<RexInputRef> inputRefs = new ArrayList<>();
        for (RexNode operand : compositeNode.getOperands()) {
            if (operand instanceof RexLiteral) {
                literals.add((RexLiteral) operand);
            } else if (operand instanceof RexInputRef) {
                inputRefs.add((RexInputRef) operand);
            }
        }
        // Operation is a comparison, since one of the operands in a field reference.
        if (inputRefs.size() == 1) {
            RexInputRef inputRef = inputRefs.get(0);
            String inputFieldName = fieldIdToName.apply(inputRef.getIndex());
            if (literals.size() > 0) {
                // Convert literal value to the same Java type as the field we are comparing to.
                Object literal = convertToExpectedType(inputRef, literals.get(0));
                switch(node.getKind()) {
                    case IN:
                        return Filters.in(inputFieldName, convertToExpectedType(inputRef, literals));
                    case EQUALS:
                        return Filters.eq(inputFieldName, literal);
                    case NOT_EQUALS:
                        return Filters.not(Filters.eq(inputFieldName, literal));
                    case LESS_THAN:
                        return Filters.lt(inputFieldName, literal);
                    case GREATER_THAN:
                        return Filters.gt(inputFieldName, literal);
                    case GREATER_THAN_OR_EQUAL:
                        return Filters.gte(inputFieldName, literal);
                    case LESS_THAN_OR_EQUAL:
                        return Filters.lte(inputFieldName, literal);
                    default:
                        // Encountered an unexpected node kind, RuntimeException below.
                        break;
                }
            } else if (node.getKind().equals(SqlKind.NOT)) {
                // Ex: `where not boolean_field`
                return Filters.not(translateRexNodeToBson(inputRef));
            } else {
                throw new RuntimeException("Cannot create a filter for an unsupported node: " + node.toString());
            }
        } else {
            // Operation is a conjunction/disjunction.
            switch(node.getKind()) {
                case AND:
                    // Recursively construct filter for each operand of conjunction.
                    return Filters.and(compositeNode.getOperands().stream().map(this::translateRexNodeToBson).collect(Collectors.toList()));
                case OR:
                    // Recursively construct filter for each operand of disjunction.
                    return Filters.or(compositeNode.getOperands().stream().map(this::translateRexNodeToBson).collect(Collectors.toList()));
                default:
                    // Encountered an unexpected node kind, RuntimeException below.
                    break;
            }
        }
        throw new RuntimeException("Encountered an unexpected node kind: " + node.getKind().toString());
    } else if (node instanceof RexInputRef && node.getType().getSqlTypeName().equals(SqlTypeName.BOOLEAN)) {
        // Boolean field, must be true. Ex: `select * from table where bool_field`
        return Filters.eq(fieldIdToName.apply(((RexInputRef) node).getIndex()), true);
    }
    throw new RuntimeException("Was expecting a RexCall or a boolean RexInputRef, but received: " + node.getClass().getSimpleName());
}
Also used : Document(org.bson.Document) PBegin(org.apache.beam.sdk.values.PBegin) LoggerFactory(org.slf4j.LoggerFactory) MongoDbIO(org.apache.beam.sdk.io.mongodb.MongoDbIO) IsBounded(org.apache.beam.sdk.values.PCollection.IsBounded) JsonToRow(org.apache.beam.sdk.transforms.JsonToRow) SimpleFunction(org.apache.beam.sdk.transforms.SimpleFunction) ProjectSupport(org.apache.beam.sdk.extensions.sql.meta.ProjectSupport) Table(org.apache.beam.sdk.extensions.sql.meta.Table) Matcher(java.util.regex.Matcher) AND(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlKind.AND) RexLiteral(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexLiteral) MapElements(org.apache.beam.sdk.transforms.MapElements) SchemaBaseBeamTable(org.apache.beam.sdk.extensions.sql.meta.SchemaBaseBeamTable) FieldType(org.apache.beam.sdk.schemas.Schema.FieldType) Collectors(java.util.stream.Collectors) FindQuery(org.apache.beam.sdk.io.mongodb.FindQuery) Serializable(java.io.Serializable) InvalidTableException(org.apache.beam.sdk.extensions.sql.meta.provider.InvalidTableException) VisibleForTesting(org.apache.beam.vendor.calcite.v1_28_0.com.google.common.annotations.VisibleForTesting) COMPARISON(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlKind.COMPARISON) POutput(org.apache.beam.sdk.values.POutput) List(java.util.List) ParDo(org.apache.beam.sdk.transforms.ParDo) BeamTableStatistics(org.apache.beam.sdk.extensions.sql.impl.BeamTableStatistics) ImmutableList(org.apache.beam.vendor.guava.v26_0_jre.com.google.common.collect.ImmutableList) Pattern(java.util.regex.Pattern) Experimental(org.apache.beam.sdk.annotations.Experimental) RexNode(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode) JsonWriterSettings(org.bson.json.JsonWriterSettings) SqlKind(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlKind) SelectHelpers(org.apache.beam.sdk.schemas.utils.SelectHelpers) ArrayList(java.util.ArrayList) PTransform(org.apache.beam.sdk.transforms.PTransform) Filters(com.mongodb.client.model.Filters) DefaultTableFilter(org.apache.beam.sdk.extensions.sql.meta.DefaultTableFilter) Bson(org.bson.conversions.Bson) ToJson(org.apache.beam.sdk.transforms.ToJson) JsonMode(org.bson.json.JsonMode) FieldAccessDescriptor(org.apache.beam.sdk.schemas.FieldAccessDescriptor) Row(org.apache.beam.sdk.values.Row) PipelineOptions(org.apache.beam.sdk.options.PipelineOptions) IntFunction(java.util.function.IntFunction) FieldTypeDescriptors(org.apache.beam.sdk.schemas.FieldTypeDescriptors) DoFn(org.apache.beam.sdk.transforms.DoFn) Logger(org.slf4j.Logger) BeamSqlTableFilter(org.apache.beam.sdk.extensions.sql.meta.BeamSqlTableFilter) PCollection(org.apache.beam.sdk.values.PCollection) Schema(org.apache.beam.sdk.schemas.Schema) RexCall(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexCall) SqlTypeName(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.type.SqlTypeName) RexInputRef(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexInputRef) OR(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlKind.OR) RexCall(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexCall) RexLiteral(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexLiteral) ArrayList(java.util.ArrayList) RexInputRef(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexInputRef) RexNode(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode)

Example 75 with RexCall

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexCall in project beam by apache.

the class BigQueryFilter method isSupported.

/**
 * Check whether a {@code RexNode} is supported. As of right now BigQuery supports: 1. Complex
 * predicates (both conjunction and disjunction). 2. Comparison between a column and a literal.
 *
 * <p>TODO: Check if comparison between two columns is supported. Also over a boolean field.
 *
 * @param node A node to check for predicate push-down support.
 * @return A pair containing a boolean whether an expression is supported and the number of input
 *     references used by the expression.
 */
private Pair<Boolean, Integer> isSupported(RexNode node) {
    int numberOfInputRefs = 0;
    boolean isSupported = true;
    if (node instanceof RexCall) {
        RexCall compositeNode = (RexCall) node;
        // CAST, TRIM? and REVERSE? should be supported as well.
        if (!node.getKind().belongsTo(SUPPORTED_OPS)) {
            isSupported = false;
        } else {
            for (RexNode operand : compositeNode.getOperands()) {
                // All operands must be supported for a parent node to be supported.
                Pair<Boolean, Integer> childSupported = isSupported(operand);
                // (OR).
                if (!node.getKind().belongsTo(ImmutableSet.of(AND, OR))) {
                    numberOfInputRefs += childSupported.getRight();
                }
                // Predicate functions, where more than one field is involved are unsupported.
                isSupported = numberOfInputRefs < 2 && childSupported.getLeft();
            }
        }
    } else if (node instanceof RexInputRef) {
        numberOfInputRefs = 1;
    } else if (node instanceof RexLiteral) {
    // RexLiterals are expected, but no action is needed.
    } else {
        throw new UnsupportedOperationException("Encountered an unexpected node type: " + node.getClass().getSimpleName());
    }
    return Pair.of(isSupported, numberOfInputRefs);
}
Also used : RexCall(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexCall) RexLiteral(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexLiteral) RexInputRef(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexInputRef) RexNode(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode)

Aggregations

RexCall (org.apache.calcite.rex.RexCall)213 RexNode (org.apache.calcite.rex.RexNode)172 RexInputRef (org.apache.calcite.rex.RexInputRef)61 ArrayList (java.util.ArrayList)60 RexLiteral (org.apache.calcite.rex.RexLiteral)44 Nullable (javax.annotation.Nullable)35 RelNode (org.apache.calcite.rel.RelNode)26 RelDataType (org.apache.calcite.rel.type.RelDataType)24 SqlOperator (org.apache.calcite.sql.SqlOperator)23 List (java.util.List)22 RexBuilder (org.apache.calcite.rex.RexBuilder)22 DruidExpression (org.apache.druid.sql.calcite.expression.DruidExpression)19 SqlKind (org.apache.calcite.sql.SqlKind)14 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)14 RelOptUtil (org.apache.calcite.plan.RelOptUtil)11 PostAggregator (org.apache.druid.query.aggregation.PostAggregator)11 RexCall (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexCall)10 RexNode (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode)10 RexTableInputRef (org.apache.calcite.rex.RexTableInputRef)10 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)9