/* * 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.eigenbase.sarg; import org.eigenbase.reltype.*; import org.eigenbase.rex.*; /** * SargIntervalBase is a common base for {@link SargInterval} and {@link * SargIntervalExpr}. */ public abstract class SargIntervalBase { //~ Instance fields -------------------------------------------------------- protected final SargFactory factory; protected final SargMutableEndpoint lowerBound; protected final SargMutableEndpoint upperBound; //~ Constructors ----------------------------------------------------------- /** * @see SargFactory#newIntervalExpr */ SargIntervalBase( SargFactory factory, RelDataType dataType) { this.factory = factory; lowerBound = factory.newEndpoint(dataType); upperBound = factory.newEndpoint(dataType); unsetLower(); unsetUpper(); } //~ Methods ---------------------------------------------------------------- /** * @return an immutable reference to the endpoint representing this * interval's lower bound */ public SargEndpoint getLowerBound() { return lowerBound; } /** * @return an immutable reference to the endpoint representing this * interval's upper bound */ public SargEndpoint getUpperBound() { return upperBound; } /** * @return whether this represents a single point */ public boolean isPoint() { return lowerBound.isClosed() && upperBound.isClosed() && lowerBound.isTouching(upperBound); } /** * @return whether this represents the empty interval */ public boolean isEmpty() { return !lowerBound.isClosed() && !upperBound.isClosed() && lowerBound.isNull() && upperBound.isNull(); } /** * @return whether this represents a (non-empty, non-point) range interval */ public boolean isRange() { return !isPoint() && !isEmpty(); } /** * @return whether this represents the universal set */ public boolean isUnconstrained() { return !lowerBound.isFinite() && !upperBound.isFinite(); } /** * @return the factory which produced this expression */ public SargFactory getFactory() { return factory; } /** * Sets this interval to represent a single point (possibly the null value). * * @param coordinate coordinate of point to set, or null for the null value */ void setPoint(RexNode coordinate) { setLower(coordinate, SargStrictness.CLOSED); setUpper(coordinate, SargStrictness.CLOSED); } /** * Sets this interval to represent a single point matching the null value. */ void setNull() { setPoint(factory.newNullLiteral()); } /** * Sets the lower bound for this interval. * * @param coordinate coordinate of point to set, must not be null * @param strictness strictness */ void setLower(RexNode coordinate, SargStrictness strictness) { lowerBound.setFinite( SargBoundType.LOWER, strictness, coordinate); } /** * Sets the upper bound for this interval. * * @param coordinate coordinate of point to set * @param strictness boundary strictness */ void setUpper(RexNode coordinate, SargStrictness strictness) { upperBound.setFinite( SargBoundType.UPPER, strictness, coordinate); } /** * Removes the lower bound for this interval, setting it to -infinity. */ void unsetLower() { lowerBound.setInfinity(-1); } /** * Removes the upper bound for this interval, setting it to +infinity. */ void unsetUpper() { upperBound.setInfinity(1); } /** * Sets this interval to unconstrained (matching everything, including * null). */ void setUnconstrained() { unsetLower(); unsetUpper(); } /** * Sets this interval to empty (matching nothing at all). */ void setEmpty() { setLower( factory.newNullLiteral(), SargStrictness.OPEN); setUpper( factory.newNullLiteral(), SargStrictness.OPEN); } public RelDataType getDataType() { return lowerBound.getDataType(); } // implement SargExpr public String toString() { StringBuilder sb = new StringBuilder(); if (lowerBound.isClosed()) { sb.append("["); } else { sb.append("("); } if (!isEmpty()) { printBound(sb, lowerBound); if (isPoint()) { // point has both endpoints same; don't repeat } else { sb.append(", "); printBound(sb, upperBound); } } if (upperBound.isClosed()) { sb.append("]"); } else { sb.append(")"); } return sb.toString(); } private void printBound(StringBuilder sb, SargEndpoint endpoint) { if (endpoint.isFinite()) { sb.append(endpoint.getCoordinate().toString()); } else { sb.append(endpoint); } } } // End SargIntervalBase.java