org.apache.drill.exec.store.mapr.db.json.JsonConditionBuilder.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.drill.exec.store.mapr.db.json.JsonConditionBuilder.java

Source

/**
 * 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.drill.exec.store.mapr.db.json;

import org.apache.drill.common.expression.BooleanOperator;
import org.apache.drill.common.expression.FunctionCall;
import org.apache.drill.common.expression.LogicalExpression;
import org.apache.drill.common.expression.SchemaPath;
import org.apache.drill.common.expression.visitors.AbstractExprVisitor;
import org.apache.drill.exec.store.hbase.DrillHBaseConstants;
import org.ojai.Value;
import org.ojai.store.QueryCondition;
import org.ojai.store.QueryCondition.Op;

import com.google.common.collect.ImmutableList;
import com.mapr.db.MapRDB;

public class JsonConditionBuilder extends AbstractExprVisitor<JsonScanSpec, Void, RuntimeException>
        implements DrillHBaseConstants {

    final private JsonTableGroupScan groupScan;

    final private LogicalExpression le;

    private boolean allExpressionsConverted = true;

    public JsonConditionBuilder(JsonTableGroupScan groupScan, LogicalExpression conditionExp) {
        this.groupScan = groupScan;
        this.le = conditionExp;
    }

    public JsonScanSpec parseTree() {
        JsonScanSpec parsedSpec = le.accept(this, null);
        if (parsedSpec != null) {
            parsedSpec.mergeScanSpec("booleanAnd", this.groupScan.getScanSpec());
        }
        return parsedSpec;
    }

    public boolean isAllExpressionsConverted() {
        // TODO Auto-generated method stub
        return allExpressionsConverted;
    }

    @Override
    public JsonScanSpec visitUnknown(LogicalExpression e, Void value) throws RuntimeException {
        allExpressionsConverted = false;
        return null;
    }

    @Override
    public JsonScanSpec visitBooleanOperator(BooleanOperator op, Void value) throws RuntimeException {
        return visitFunctionCall(op, value);
    }

    @Override
    public JsonScanSpec visitFunctionCall(FunctionCall call, Void value) throws RuntimeException {
        JsonScanSpec nodeScanSpec = null;
        String functionName = call.getName();
        ImmutableList<LogicalExpression> args = call.args;

        if (CompareFunctionsProcessor.isCompareFunction(functionName)) {
            CompareFunctionsProcessor processor = CompareFunctionsProcessor.process(call);
            if (processor.isSuccess()) {
                nodeScanSpec = createJsonScanSpec(call, processor);
            }
        } else {
            switch (functionName) {
            case "booleanAnd":
            case "booleanOr":
                nodeScanSpec = args.get(0).accept(this, null);
                for (int i = 1; i < args.size(); ++i) {
                    JsonScanSpec nextScanSpec = args.get(i).accept(this, null);
                    if (nodeScanSpec != null && nextScanSpec != null) {
                        nodeScanSpec.mergeScanSpec(functionName, nextScanSpec);
                    } else {
                        allExpressionsConverted = false;
                        if ("booleanAnd".equals(functionName)) {
                            nodeScanSpec = nodeScanSpec == null ? nextScanSpec : nodeScanSpec;
                        }
                    }
                }
                break;
            }
        }

        if (nodeScanSpec == null) {
            allExpressionsConverted = false;
        }

        return nodeScanSpec;
    }

    private void setIsCondition(QueryCondition c, String str, QueryCondition.Op op, Value v) {
        switch (v.getType()) {
        case BOOLEAN:
            c.is(str, op, v.getBoolean());
            break;
        case STRING:
            c.is(str, op, v.getString());
            break;
        case BYTE:
            c.is(str, op, v.getByte());
            break;
        case SHORT:
            c.is(str, op, v.getShort());
            break;
        case INT:
            c.is(str, op, v.getInt());
            break;
        case LONG:
            c.is(str, op, v.getLong());
            break;
        case FLOAT:
            c.is(str, op, v.getFloat());
            break;
        case DOUBLE:
            c.is(str, op, v.getDouble());
            break;
        case DECIMAL:
            c.is(str, op, v.getDecimal());
            break;
        case DATE:
            c.is(str, op, v.getDate());
            break;
        case TIME:
            c.is(str, op, v.getTime());
            break;
        case TIMESTAMP:
            c.is(str, op, v.getTimestamp());
            break;
        case BINARY:
            c.is(str, op, v.getBinary());
            break;
        // XXX/TODO: Map, Array?
        default:
            break;
        }
    }

    private JsonScanSpec createJsonScanSpec(FunctionCall call, CompareFunctionsProcessor processor) {
        String functionName = processor.getFunctionName();
        SchemaPath field = processor.getPath();
        Value fieldValue = processor.getValue();

        QueryCondition cond = null;
        switch (functionName) {
        case "equal":
            cond = MapRDB.newCondition();
            setIsCondition(cond, field.getAsUnescapedPath(), Op.EQUAL, fieldValue);
            cond.build();
            break;

        case "not_equal":
            cond = MapRDB.newCondition();
            setIsCondition(cond, field.getAsUnescapedPath(), Op.NOT_EQUAL, fieldValue);
            cond.build();
            break;

        case "less_than":
            cond = MapRDB.newCondition();
            setIsCondition(cond, field.getAsUnescapedPath(), Op.LESS, fieldValue);
            cond.build();
            break;

        case "less_than_or_equal_to":
            cond = MapRDB.newCondition();
            setIsCondition(cond, field.getAsUnescapedPath(), Op.LESS_OR_EQUAL, fieldValue);
            cond.build();
            break;

        case "greater_than":
            cond = MapRDB.newCondition();
            setIsCondition(cond, field.getAsUnescapedPath(), Op.GREATER, fieldValue);
            cond.build();
            break;

        case "greater_than_or_equal_to":
            cond = MapRDB.newCondition();
            setIsCondition(cond, field.getAsUnescapedPath(), Op.GREATER_OR_EQUAL, fieldValue);
            cond.build();
            break;

        case "isnull":
            cond = MapRDB.newCondition().notExists(field.getAsUnescapedPath()).build();
            break;

        case "isnotnull":
            cond = MapRDB.newCondition().exists(field.getAsUnescapedPath()).build();
            break;

        case "istrue":
            cond = MapRDB.newCondition().is(field.getAsUnescapedPath(), Op.EQUAL, true).build();
            break;

        case "isnotfalse":
            cond = MapRDB.newCondition().is(field.getAsUnescapedPath(), Op.NOT_EQUAL, false).build();
            break;

        case "isfalse":
            cond = MapRDB.newCondition().is(field.getAsUnescapedPath(), Op.EQUAL, false).build();
            break;

        case "isnottrue":
            cond = MapRDB.newCondition().is(field.getAsUnescapedPath(), Op.NOT_EQUAL, true).build();
            break;

        case "like":
            cond = MapRDB.newCondition().like(field.getAsUnescapedPath(), fieldValue.getString()).build();
            break;

        default:
        }

        if (cond != null) {
            return new JsonScanSpec(groupScan.getTableName(), cond);
        }

        return null;
    }
}