All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.org.apache.calcite.sql.fun.SqlLikeOperator Maven / Gradle / Ivy

/*
 * 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 com.hazelcast.org.apache.calcite.sql.fun;

import com.hazelcast.org.apache.calcite.sql.SqlCall;
import com.hazelcast.org.apache.calcite.sql.SqlCallBinding;
import com.hazelcast.org.apache.calcite.sql.SqlKind;
import com.hazelcast.org.apache.calcite.sql.SqlNode;
import com.hazelcast.org.apache.calcite.sql.SqlOperandCountRange;
import com.hazelcast.org.apache.calcite.sql.SqlOperator;
import com.hazelcast.org.apache.calcite.sql.SqlSpecialOperator;
import com.hazelcast.org.apache.calcite.sql.SqlWriter;
import com.hazelcast.org.apache.calcite.sql.parser.SqlParserPos;
import com.hazelcast.org.apache.calcite.sql.parser.SqlParserUtil;
import com.hazelcast.org.apache.calcite.sql.type.InferTypes;
import com.hazelcast.org.apache.calcite.sql.type.OperandTypes;
import com.hazelcast.org.apache.calcite.sql.type.ReturnTypes;
import com.hazelcast.org.apache.calcite.sql.type.SqlOperandCountRanges;
import com.hazelcast.org.apache.calcite.sql.type.SqlTypeUtil;

/**
 * An operator describing the LIKE and SIMILAR
 * operators.
 *
 * 

Syntax of the two operators: * *

    *
  • src-value [NOT] LIKE pattern-value [ESCAPE * escape-value]
  • *
  • src-value [NOT] SIMILAR pattern-value [ESCAPE * escape-value]
  • *
* *

NOTE If the NOT clause is present the * {@link com.hazelcast.org.apache.calcite.sql.parser.SqlParser parser} will generate a * equivalent to NOT (src LIKE pattern ...) */ public class SqlLikeOperator extends SqlSpecialOperator { //~ Instance fields -------------------------------------------------------- private final boolean negated; //~ Constructors ----------------------------------------------------------- /** * Creates a SqlLikeOperator. * * @param name Operator name * @param kind Kind * @param negated Whether this is 'NOT LIKE' */ SqlLikeOperator( String name, SqlKind kind, boolean negated) { // LIKE is right-associative, because that makes it easier to capture // dangling ESCAPE clauses: "a like b like c escape d" becomes // "a like (b like c escape d)". super( name, kind, 32, false, ReturnTypes.BOOLEAN_NULLABLE, InferTypes.FIRST_KNOWN, OperandTypes.STRING_SAME_SAME_SAME); this.negated = negated; } //~ Methods ---------------------------------------------------------------- /** * Returns whether this is the 'NOT LIKE' operator. * * @return whether this is 'NOT LIKE' */ public boolean isNegated() { return negated; } public SqlOperandCountRange getOperandCountRange() { return SqlOperandCountRanges.between(2, 3); } public boolean checkOperandTypes( SqlCallBinding callBinding, boolean throwOnFailure) { switch (callBinding.getOperandCount()) { case 2: if (!OperandTypes.STRING_SAME_SAME.checkOperandTypes( callBinding, throwOnFailure)) { return false; } break; case 3: if (!OperandTypes.STRING_SAME_SAME_SAME.checkOperandTypes( callBinding, throwOnFailure)) { return false; } // calc implementation should // enforce the escape character length to be 1 break; default: throw new AssertionError("unexpected number of args to " + callBinding.getCall() + ": " + callBinding.getOperandCount()); } return SqlTypeUtil.isCharTypeComparable( callBinding, callBinding.operands(), throwOnFailure); } public void unparse( SqlWriter writer, SqlCall call, int leftPrec, int rightPrec) { final SqlWriter.Frame frame = writer.startList("", ""); call.operand(0).unparse(writer, getLeftPrec(), getRightPrec()); writer.sep(getName()); call.operand(1).unparse(writer, getLeftPrec(), getRightPrec()); if (call.operandCount() == 3) { writer.sep("ESCAPE"); call.operand(2).unparse(writer, getLeftPrec(), getRightPrec()); } writer.endList(frame); } public ReduceResult reduceExpr( final int opOrdinal, TokenSequence list) { // Example: // a LIKE b || c ESCAPE d || e AND f // | | | | | | // exp0 exp1 exp2 SqlNode exp0 = list.node(opOrdinal - 1); SqlOperator op = list.op(opOrdinal); assert op instanceof SqlLikeOperator; SqlNode exp1 = SqlParserUtil.toTreeEx( list, opOrdinal + 1, getRightPrec(), SqlKind.ESCAPE); SqlNode exp2 = null; if ((opOrdinal + 2) < list.size()) { if (list.isOp(opOrdinal + 2)) { final SqlOperator op2 = list.op(opOrdinal + 2); if (op2.getKind() == SqlKind.ESCAPE) { exp2 = SqlParserUtil.toTreeEx( list, opOrdinal + 3, getRightPrec(), SqlKind.ESCAPE); } } } final SqlNode[] operands; int end; if (exp2 != null) { operands = new SqlNode[]{exp0, exp1, exp2}; end = opOrdinal + 4; } else { operands = new SqlNode[]{exp0, exp1}; end = opOrdinal + 2; } SqlCall call = createCall(SqlParserPos.ZERO, operands); return new ReduceResult(opOrdinal - 1, end, call); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy