Search in sources :

Example 1 with Sarg

use of org.apache.calcite.util.Sarg in project flink by apache.

the class RexSimplify method simplifySearch.

private RexNode simplifySearch(RexCall call, RexUnknownAs unknownAs) {
    assert call.getKind() == SqlKind.SEARCH;
    final RexNode a = call.getOperands().get(0);
    if (call.getOperands().get(1) instanceof RexLiteral) {
        RexLiteral literal = (RexLiteral) call.getOperands().get(1);
        final Sarg sarg = literal.getValueAs(Sarg.class);
        if (sarg.containsNull) {
            final RexNode simplified = simplifyIs1(SqlKind.IS_NULL, a, unknownAs);
            if (simplified != null && simplified.isAlwaysFalse()) {
                final Sarg sarg2 = Sarg.of(false, sarg.rangeSet);
                final RexLiteral literal2 = rexBuilder.makeLiteral(sarg2, literal.getType(), literal.getTypeName());
                return call.clone(call.type, ImmutableList.of(a, literal2));
            }
        }
    }
    return call;
}
Also used : Sarg(org.apache.calcite.util.Sarg)

Example 2 with Sarg

use of org.apache.calcite.util.Sarg in project flink by apache.

the class FlinkRexBuilder method makeIn.

/**
 * Convert the conditions into the {@code IN} and fix [CALCITE-4888]: Unexpected {@link RexNode}
 * when call {@link RelBuilder#in} to create an {@code IN} predicate with a list of varchar
 * literals which have different length in {@link RexBuilder#makeIn}.
 *
 * <p>The bug is because the origin implementation doesn't take {@link
 * FlinkTypeSystem#shouldConvertRaggedUnionTypesToVarying} into consideration. When this is
 * true, the behaviour should not padding char. Please see
 * https://issues.apache.org/jira/browse/CALCITE-4590 and
 * https://issues.apache.org/jira/browse/CALCITE-2321. Please refer to {@code
 * org.apache.calcite.rex.RexSimplify.RexSargBuilder#getType} for the correct behaviour.
 *
 * <p>Once CALCITE-4888 is fixed, this method (and related methods) should be removed.
 */
@Override
@SuppressWarnings("unchecked")
public RexNode makeIn(RexNode arg, List<? extends RexNode> ranges) {
    if (areAssignable(arg, ranges)) {
        // Fix calcite doesn't check literal whether is NULL here
        List<RexNode> rangeWithoutNull = new ArrayList<>();
        boolean containsNull = false;
        for (RexNode node : ranges) {
            if (isNull(node)) {
                containsNull = true;
            } else {
                rangeWithoutNull.add(node);
            }
        }
        final Sarg sarg = toSarg(Comparable.class, rangeWithoutNull, containsNull);
        if (sarg != null) {
            List<RelDataType> distinctTypes = Util.distinctList(ranges.stream().map(RexNode::getType).collect(Collectors.toList()));
            RelDataType commonType = getTypeFactory().leastRestrictive(distinctTypes);
            return makeCall(SqlStdOperatorTable.SEARCH, arg, makeSearchArgumentLiteral(sarg, commonType));
        }
    }
    return RexUtil.composeDisjunction(this, ranges.stream().map(r -> makeCall(SqlStdOperatorTable.EQUALS, arg, r)).collect(Util.toImmutableList()));
}
Also used : Sarg(org.apache.calcite.util.Sarg) ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) RexNode(org.apache.calcite.rex.RexNode)

Example 3 with Sarg

use of org.apache.calcite.util.Sarg in project flink by apache.

the class RexLiteral method appendAsJava.

/**
 * Appends the specified value in the provided destination as a Java string. The value must be
 * consistent with the type, as per {@link #valueMatchesType}.
 *
 * <p>Typical return values:
 *
 * <ul>
 *   <li>true
 *   <li>null
 *   <li>"Hello, world!"
 *   <li>1.25
 *   <li>1234ABCD
 * </ul>
 *
 * @param value Value to be appended to the provided destination as a Java string
 * @param sb Destination to which to append the specified value
 * @param typeName Type name to be used for the transformation of the value to a Java string
 * @param type Type to be used for the transformation of the value to a Java string
 * @param includeType Whether to include the data type in the Java representation
 */
private static void appendAsJava(Comparable value, StringBuilder sb, SqlTypeName typeName, RelDataType type, boolean java, RexDigestIncludeType includeType) {
    switch(typeName) {
        case CHAR:
            NlsString nlsString = (NlsString) value;
            if (java) {
                Util.printJavaString(sb, nlsString.getValue(), true);
            } else {
                boolean includeCharset = (nlsString.getCharsetName() != null) && !nlsString.getCharsetName().equals(CalciteSystemProperty.DEFAULT_CHARSET.value());
                sb.append(nlsString.asSql(includeCharset, false));
            }
            break;
        case BOOLEAN:
            assert value instanceof Boolean;
            sb.append(value.toString());
            break;
        case DECIMAL:
            assert value instanceof BigDecimal;
            sb.append(value.toString());
            break;
        case DOUBLE:
            assert value instanceof BigDecimal;
            sb.append(Util.toScientificNotation((BigDecimal) value));
            break;
        case BIGINT:
            assert value instanceof BigDecimal;
            long narrowLong = ((BigDecimal) value).longValue();
            sb.append(String.valueOf(narrowLong));
            sb.append('L');
            break;
        case BINARY:
            assert value instanceof ByteString;
            sb.append("X'");
            sb.append(((ByteString) value).toString(16));
            sb.append("'");
            break;
        case NULL:
            assert value == null;
            sb.append("null");
            break;
        case SARG:
            assert value instanceof Sarg;
            // noinspection unchecked,rawtypes
            Util.asStringBuilder(sb, sb2 -> printSarg(sb2, (Sarg) value, type));
            break;
        case SYMBOL:
            assert value instanceof Enum;
            sb.append("FLAG(");
            sb.append(value.toString());
            sb.append(")");
            break;
        case DATE:
            assert value instanceof DateString;
            sb.append(value.toString());
            break;
        case TIME:
        case TIME_WITH_LOCAL_TIME_ZONE:
            assert value instanceof TimeString;
            sb.append(value.toString());
            break;
        case TIMESTAMP:
        case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
            assert value instanceof TimestampString;
            sb.append(value.toString());
            break;
        case INTERVAL_YEAR:
        case INTERVAL_YEAR_MONTH:
        case INTERVAL_MONTH:
        case INTERVAL_DAY:
        case INTERVAL_DAY_HOUR:
        case INTERVAL_DAY_MINUTE:
        case INTERVAL_DAY_SECOND:
        case INTERVAL_HOUR:
        case INTERVAL_HOUR_MINUTE:
        case INTERVAL_HOUR_SECOND:
        case INTERVAL_MINUTE:
        case INTERVAL_MINUTE_SECOND:
        case INTERVAL_SECOND:
            assert value instanceof BigDecimal;
            sb.append(value.toString());
            break;
        case MULTISET:
        case ROW:
            final List<RexLiteral> list = (List) value;
            Util.asStringBuilder(sb, sb2 -> Util.printList(sb, list.size(), (sb3, i) -> sb3.append(list.get(i).computeDigest(includeType))));
            break;
        case GEOMETRY:
            final String wkt = GeoFunctions.ST_AsWKT((Geometries.Geom) value);
            sb.append(wkt);
            break;
        default:
            assert valueMatchesType(value, typeName, true);
            throw Util.needToImplement(typeName);
    }
}
Also used : SimpleDateFormat(java.text.SimpleDateFormat) TimeUnit(org.apache.calcite.avatica.util.TimeUnit) ByteBuffer(java.nio.ByteBuffer) TimeString(org.apache.calcite.util.TimeString) BigDecimal(java.math.BigDecimal) Calendar(java.util.Calendar) ImmutableList(com.google.common.collect.ImmutableList) Charset(java.nio.charset.Charset) DateTimeUtils(org.apache.calcite.avatica.util.DateTimeUtils) Geometries(org.apache.calcite.runtime.Geometries) Locale(java.util.Locale) Map(java.util.Map) SqlOperator(org.apache.calcite.sql.SqlOperator) CalciteSystemProperty(org.apache.calcite.config.CalciteSystemProperty) GeoFunctions(org.apache.calcite.runtime.GeoFunctions) Functions(org.apache.calcite.linq4j.function.Functions) PrintWriter(java.io.PrintWriter) RelDataType(org.apache.calcite.rel.type.RelDataType) Litmus(org.apache.calcite.util.Litmus) Sarg(org.apache.calcite.util.Sarg) SqlKind(org.apache.calcite.sql.SqlKind) SqlTypeName(org.apache.calcite.sql.type.SqlTypeName) DateString(org.apache.calcite.util.DateString) NlsString(org.apache.calcite.util.NlsString) ByteString(org.apache.calcite.avatica.util.ByteString) TimeZone(java.util.TimeZone) TimestampString(org.apache.calcite.util.TimestampString) ConversionUtil(org.apache.calcite.util.ConversionUtil) RelNode(org.apache.calcite.rel.RelNode) SqlCollation(org.apache.calcite.sql.SqlCollation) CompositeList(org.apache.calcite.util.CompositeList) Objects(java.util.Objects) List(java.util.List) SqlStdOperatorTable(org.apache.calcite.sql.fun.SqlStdOperatorTable) FlatLists(org.apache.calcite.runtime.FlatLists) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) Preconditions(com.google.common.base.Preconditions) Util(org.apache.calcite.util.Util) SqlParserUtil(org.apache.calcite.sql.parser.SqlParserUtil) Sarg(org.apache.calcite.util.Sarg) TimeString(org.apache.calcite.util.TimeString) ByteString(org.apache.calcite.avatica.util.ByteString) Geometries(org.apache.calcite.runtime.Geometries) TimeString(org.apache.calcite.util.TimeString) DateString(org.apache.calcite.util.DateString) NlsString(org.apache.calcite.util.NlsString) ByteString(org.apache.calcite.avatica.util.ByteString) TimestampString(org.apache.calcite.util.TimestampString) BigDecimal(java.math.BigDecimal) DateString(org.apache.calcite.util.DateString) NlsString(org.apache.calcite.util.NlsString) ImmutableList(com.google.common.collect.ImmutableList) CompositeList(org.apache.calcite.util.CompositeList) List(java.util.List) TimestampString(org.apache.calcite.util.TimestampString)

Example 4 with Sarg

use of org.apache.calcite.util.Sarg in project herddb by diennea.

the class SQLExpressionCompiler method convertSearchOperator.

private static CompiledSQLExpression convertSearchOperator(RexCall p) {
    if (p.operands.size() != 2) {
        throw new StatementExecutionException("not implemented SEARCH with " + p.operands.size() + " operands");
    }
    CompiledSQLExpression left = compileExpression(p.operands.get(0));
    RexNode rexNode = p.operands.get(1);
    if (!(rexNode instanceof RexLiteral)) {
        throw new StatementExecutionException("not implemented SEARCH with " + rexNode.getClass());
    }
    RexLiteral searchArgument = (RexLiteral) rexNode;
    if (!SqlTypeName.SARG.equals(searchArgument.getTypeName())) {
        throw new StatementExecutionException("not implemented SEARCH with " + searchArgument);
    }
    Sarg<?> sarg = (Sarg) searchArgument.getValue();
    if (sarg == null) {
        throw new StatementExecutionException("not implemented SEARCH with " + searchArgument);
    }
    RangeSet<?> rangeSet = sarg.rangeSet;
    // pick the ranges in order
    List<? extends Range<?>> ranges = new ArrayList<>(rangeSet.asDescendingSetOfRanges());
    CompiledSQLExpression[] operands = new CompiledSQLExpression[ranges.size()];
    CompiledSQLExpression rawResult = null;
    if (ranges.size() == 2) {
        // very creative way for '<>'
        // x <> CONST -> x in (-INF, CONST) or x in (CONST, +INF)
        Range<?> firstRange = ranges.get(1);
        Range<?> secondRange = ranges.get(0);
        if (!firstRange.hasLowerBound() && firstRange.hasUpperBound() && secondRange.hasLowerBound() && !secondRange.hasUpperBound()) {
            Comparable from = firstRange.upperEndpoint();
            Comparable to = secondRange.lowerEndpoint();
            if (Objects.equals(from, to)) {
                ConstantExpression fromExpression = new ConstantExpression(safeValue(from, searchArgument.getType(), searchArgument.getTypeName()), CalcitePlanner.convertToHerdType(searchArgument.getType()));
                rawResult = new CompiledNotEqualsExpression(left, fromExpression);
            }
        }
    }
    if (rawResult == null) {
        int index = 0;
        for (Range<?> range : ranges) {
            if (!range.hasLowerBound() || !range.hasUpperBound()) {
                throw new StatementExecutionException("not implemented SEARCH with " + searchArgument + " without BOUNDS");
            }
            Comparable from = range.lowerEndpoint();
            Comparable to = range.upperEndpoint();
            CompiledSQLExpression result;
            if (from != null && Objects.equals(from, to)) {
                ConstantExpression fromExpression = new ConstantExpression(safeValue(from, searchArgument.getType(), searchArgument.getTypeName()), CalcitePlanner.convertToHerdType(searchArgument.getType()));
                result = new CompiledEqualsExpression(left, fromExpression);
            } else {
                ConstantExpression fromExpression = new ConstantExpression(safeValue(from, searchArgument.getType(), searchArgument.getTypeName()), CalcitePlanner.convertToHerdType(searchArgument.getType()));
                ConstantExpression toExpression = new ConstantExpression(safeValue(to, searchArgument.getType(), searchArgument.getTypeName()), CalcitePlanner.convertToHerdType(searchArgument.getType()));
                CompiledSQLExpression lowerBound;
                CompiledSQLExpression upperBound;
                switch(range.lowerBoundType()) {
                    case OPEN:
                        lowerBound = new CompiledGreaterThanExpression(left, fromExpression);
                        break;
                    case CLOSED:
                        lowerBound = new CompiledGreaterThanEqualsExpression(left, fromExpression);
                        break;
                    default:
                        throw new UnsupportedOperationException("FROM = " + from + " TO = " + to);
                }
                switch(range.upperBoundType()) {
                    case OPEN:
                        upperBound = new CompiledMinorThanExpression(left, toExpression);
                        break;
                    case CLOSED:
                        upperBound = new CompiledMinorThanEqualsExpression(left, toExpression);
                        break;
                    default:
                        throw new UnsupportedOperationException("FROM = " + from + " TO = " + to);
                }
                result = new CompiledAndExpression(lowerBound, upperBound);
            }
            operands[index++] = result;
        }
        if (operands.length == 1) {
            rawResult = operands[0];
        } else {
            rawResult = new CompiledMultiOrExpression(operands);
        }
    }
    switch(sarg.nullAs) {
        case UNKNOWN:
            return rawResult;
        case TRUE:
            // LEFT IS NULL OR (rawResult)
            return new CompiledOrExpression(new CompiledIsNullExpression(false, left), rawResult);
        case FALSE:
            // LEFT IS NOT NULL AND (rawResult)
            return new CompiledAndExpression(new CompiledIsNullExpression(true, left), rawResult);
        default:
            throw new UnsupportedOperationException("sarg.nullAs " + sarg.nullAs);
    }
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) Sarg(org.apache.calcite.util.Sarg) ArrayList(java.util.ArrayList) StatementExecutionException(herddb.model.StatementExecutionException) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

Sarg (org.apache.calcite.util.Sarg)4 ArrayList (java.util.ArrayList)2 RelDataType (org.apache.calcite.rel.type.RelDataType)2 RexNode (org.apache.calcite.rex.RexNode)2 Preconditions (com.google.common.base.Preconditions)1 ImmutableList (com.google.common.collect.ImmutableList)1 StatementExecutionException (herddb.model.StatementExecutionException)1 PrintWriter (java.io.PrintWriter)1 BigDecimal (java.math.BigDecimal)1 ByteBuffer (java.nio.ByteBuffer)1 Charset (java.nio.charset.Charset)1 SimpleDateFormat (java.text.SimpleDateFormat)1 Calendar (java.util.Calendar)1 List (java.util.List)1 Locale (java.util.Locale)1 Map (java.util.Map)1 Objects (java.util.Objects)1 TimeZone (java.util.TimeZone)1 ByteString (org.apache.calcite.avatica.util.ByteString)1 DateTimeUtils (org.apache.calcite.avatica.util.DateTimeUtils)1