AnyExpression.java
/*
* Copyright 2018 gregorygraham.
*
* This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
* To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/
* or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
*
* You are free to:
* Share - copy and redistribute the material in any medium or format
* Adapt - remix, transform, and build upon the material
*
* The licensor cannot revoke these freedoms as long as you follow the license terms.
* Under the following terms:
*
* Attribution -
* You must give appropriate credit, provide a link to the license, and indicate if changes were made.
* You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
* NonCommercial -
* You may not use the material for commercial purposes.
* ShareAlike -
* If you remix, transform, or build upon the material,
* you must distribute your contributions under the same license as the original.
* No additional restrictions -
* You may not apply legal terms or technological measures that legally restrict others from doing anything the
* license permits.
*
* Check the Creative Commons website for any details, legalese, and updates.
*/
package nz.co.gregs.dbvolution.expressions;
import nz.co.gregs.dbvolution.expressions.windows.WindowFunctionFramable;
import nz.co.gregs.dbvolution.expressions.windows.CanBeWindowingFunctionWithFrame;
import nz.co.gregs.dbvolution.expressions.spatial2D.*;
import com.vividsolutions.jts.geom.LineSegment;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.MultiPoint;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
import java.io.Serializable;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import nz.co.gregs.dbvolution.DBRow;
import nz.co.gregs.dbvolution.databases.DBDatabase;
import nz.co.gregs.dbvolution.databases.definitions.DBDefinition;
import nz.co.gregs.dbvolution.results.AnyResult;
import nz.co.gregs.dbvolution.datatypes.QueryableDatatype;
import nz.co.gregs.dbvolution.expressions.windows.WindowFunctionRequiresOrderBy;
import nz.co.gregs.dbvolution.results.*;
import org.joda.time.Period;
import nz.co.gregs.dbvolution.expressions.windows.CanBeWindowingFunctionRequiresOrderBy;
/**
*
* @author gregorygraham
* @param <B> the base Java type of this expression, e.g. Integer
* @param <R> the Results type of this expression, e.g. IntegerExpression
* @param <D> the QDT of this expression, e.g. DBInteger
*/
public abstract class AnyExpression<B extends Object, R extends AnyResult<B>, D extends QueryableDatatype<B>> implements ExpressionColumn<D>, AnyResult<B>, Serializable {
private final static long serialVersionUID = 1l;
private final AnyResult<?> innerResult;
private final boolean nullProtectionRequired;
/**
* Returns an expression that will evaluate to NULL in SQL.
*
* @return an untyped expression that returns NULL
*/
public AnyExpression<?, ?, ?> nullExpression() {
return new StringExpression() {
private final static long serialVersionUID = 1l;
@Override
public String toSQLString(DBDefinition db) {
return db.getNull();
}
};
}
abstract public R expression(B value);
abstract public R expression(R value);
abstract public R expression(D value);
public R asResult() {
return (R) this;
}
@Override
public String createSQLForFromClause(DBDatabase database) {
return getInnerResult().createSQLForFromClause(database);
}
@Override
public Set<DBRow> getTablesInvolved() {
final AnyResult<?> inner = getInnerResult();
Set<DBRow> result = new HashSet<>(0);
if (inner != null) {
result = inner.getTablesInvolved();
}
return result;
}
@Override
public boolean isAggregator() {
final AnyResult<?> inner = getInnerResult();
return inner == null ? false : inner.isAggregator();
}
@Override
public boolean isWindowingFunction() {
final AnyResult<?> inner = getInnerResult();
return inner == null ? false : inner.isWindowingFunction();
}
@Override
public String toSQLString(DBDefinition db) {
if (getInnerResult() == null) {
return this.nullExpression().toSQLString(db);// db.getNull();
} else {
return getInnerResult().toSQLString(db);
}
}
/**
* A complex expression requires more than just a function call in the select
* clause.
*
* @return FALSE, unless you need a subtable to work out your expressions's
* value
*/
@Override
public boolean isComplexExpression() {
AnyResult<?> inner = getInnerResult();
if (inner == null) {
return false;
} else {
return inner.isComplexExpression();
}
}
@Override
public boolean isPurelyFunctional() {
if (getInnerResult() == null) {
return true;
} else {
return getInnerResult().isPurelyFunctional();
}
}
/**
* Does nothing
*
*/
public AnyExpression() {
innerResult = null;
/* This creates a terminator expression for null-safety chains */
nullProtectionRequired = false;
}
/**
*
* @param only an expression of any type
*/
public AnyExpression(AnyResult<?> only) {
innerResult = only;
nullProtectionRequired = only == null ? true : innerResult.getIncludesNull();
}
protected boolean isNullSafetyTerminator() {
return getInnerResult() == null && (getIncludesNull() == false);
}
public AnyResult<?> getInnerResult() {
return innerResult;
}
@Override
public boolean getIncludesNull() {
AnyResult<?> inner = getInnerResult();
return nullProtectionRequired || (inner == null ? false : inner.getIncludesNull());
}
/**
* Create An Appropriate Expression Object For This Object
*
* <p>
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
* <p>
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
* <p>
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
* <ul>
* <li>Only object classes that are appropriate need to be handle by the
* DBExpression subclass.<li>
* <li>The implementation should be {@code static}</li>
* </ul>
*
* @param value a literal value to use in the expression
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static BooleanExpression value(Boolean value) {
return new BooleanExpression(value);
}
/**
* Create An Appropriate Expression Object For This Object
*
* <p>
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
* <p>
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
* <p>
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
* <ul>
* <li>Only object classes that are appropriate need to be handle by the
* DBExpression subclass.<li>
* <li>The implementation should be {@code static}</li>
* </ul>
*
* @param integer a literal value to use in the expression
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static IntegerExpression value(Integer integer) {
if (integer == null) {
return nullInteger();
} else {
return new IntegerExpression(integer);
}
}
/**
* Create An Appropriate Expression Object For This Object
*
* <p>
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
* <p>
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
* <p>
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
* <ul>
* <li>Only object classes that are appropriate need to be handle by the
* DBExpression subclass.<li>
* <li>The implementation should be {@code static}</li>
* </ul>
*
* @param integer a literal value to use in the expression
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static IntegerExpression value(Long integer) {
return new IntegerExpression(integer);
}
/**
* Create An Appropriate Expression Object For This Object
*
* <p>
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
* <p>
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
* <p>
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
* <ul>
* <li>Only object classes that are appropriate need to be handle by the
* DBExpression subclass.<li>
* <li>The implementation should be {@code static}</li>
* </ul>
*
* @param integer a literal value to use in the expression
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static IntegerExpression value(int integer) {
return new IntegerExpression(integer);
}
/**
* Create An Appropriate Expression Object For This Object
*
* <p>
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
* <p>
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
* <p>
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
* <ul>
* <li>Only object classes that are appropriate need to be handle by the
* DBExpression subclass.<li>
* <li>The implementation should be {@code static}</li>
* </ul>
*
* @param integer a literal value to use in the expression
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static IntegerExpression value(long integer) {
return new IntegerExpression(integer);
}
/**
* Create An Appropriate Expression Object For This Object
*
* <p>
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
* <p>
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
* <p>
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
* <ul>
* <li>Only object classes that are appropriate need to be handle by the
* DBExpression subclass.<li>
* <li>The implementation should be {@code static}</li>
* </ul>
*
* @param number a literal value to use in the expression
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static NumberExpression value(Number number) {
return new NumberExpression(number);
}
/**
* Create An Appropriate Expression Object For This Object
*
* <p>
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
* <p>
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
* <p>
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
* <ul>
* <li>Only object classes that are appropriate need to be handle by the
* DBExpression subclass.<li>
* <li>The implementation should be {@code static}</li>
* </ul>
*
* @param string a literal value to use in the expression
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static StringLiteral value(String string) {
return new StringLiteral(string);
}
/**
* Create An Appropriate Expression Object For This Object
*
* <p>
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
* <p>
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
* <p>
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
* <ul>
* <li>Only object classes that are appropriate need to be handle by the
* DBExpression subclass.<li>
* <li>The implementation should be {@code static}</li>
* </ul>
*
* @param date a literal value to use in the expression
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static DateExpression value(Date date) {
return new DateExpression(date);
}
/**
* Create An Appropriate Expression Object For This Object
*
* <p>
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
* <p>
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
* <p>
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
* <ul>
* <li>Only object classes that are appropriate need to be handle by the
* DBExpression subclass.<li>
* <li>The implementation should be {@code static}</li>
* </ul>
*
* @param date a literal value to use in the expression
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static LocalDateExpression value(LocalDate date) {
return new LocalDateExpression(date);
}
/**
* Create An Appropriate Expression Object For This Object
*
* <p>
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
* <p>
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
* <p>
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
* <ul>
* <li>Only object classes that are appropriate need to be handle by the
* DBExpression subclass.<li>
* <li>The implementation should be {@code static}</li>
* </ul>
*
* @param date a literal value to use in the expression
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static LocalDateTimeExpression value(LocalDateTime date) {
return new LocalDateTimeExpression(date);
}
/**
* Create An Appropriate Expression Object For This Object
*
* <p>
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
* <p>
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
* <p>
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
* <ul>
* <li>Only object classes that are appropriate need to be handle by the
* DBExpression subclass.<li>
* <li>The implementation should be {@code static}</li>
* </ul>
*
* @param date a literal value to use in the expression
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static InstantExpression value(Instant date) {
return new InstantExpression(date);
}
/**
* Create An Appropriate Expression Object For This Object
*
* <p>
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
* <p>
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
* <p>
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
* <ul>
* <li>Only object classes that are appropriate need to be handle by the
* DBExpression subclass.<li>
* <li>The implementation should be {@code static}</li>
* </ul>
*
* @param period a literal value to use in the expression
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static DateRepeatExpression value(Period period) {
return new DateRepeatExpression(period);
}
/**
* Create An Appropriate Expression Object For This Object
*
* <p>
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
* <p>
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
* <p>
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
* <ul>
* <li>Only object classes that are appropriate need to be handle by the
* DBExpression subclass.<li>
* <li>The implementation should be {@code static}</li>
* </ul>
*
* @param duration a literal value to use in the expression
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static DurationExpression value(Duration duration) {
return new DurationExpression(duration);
}
/**
* Create An Appropriate Expression Object For This Object
*
* <p>
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
* <p>
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
* <p>
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
* <ul>
* <li>Only object classes that are appropriate need to be handle by the
* DBExpression subclass.<li>
* <li>The implementation should be {@code static}</li>
* </ul>
*
* @param value a literal value to use in the expression
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static BooleanExpression value(BooleanResult value) {
return new BooleanExpression(value);
}
/**
* Create An Appropriate Expression Object For This Object
*
* <p>
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
* <p>
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
* <p>
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
* <ul>
* <li>Only object classes that are appropriate need to be handle by the
* DBExpression subclass.<li>
* <li>The implementation should be {@code static}</li>
* </ul>
*
* @param integer a literal value to use in the expression
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static IntegerExpression value(IntegerResult integer) {
return new IntegerExpression(integer);
}
/**
* Create An Appropriate Expression Object For This Object
*
* <p>
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
* <p>
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
* <p>
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
* <ul>
* <li>Only object classes that are appropriate need to be handle by the
* DBExpression subclass.<li>
* <li>The implementation should be {@code static}</li>
* </ul>
*
* @param number a literal value to use in the expression
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static NumberExpression value(NumberResult number) {
return new NumberExpression(number);
}
/**
* Create An Appropriate Expression Object For This Object
*
* <p>
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
* <p>
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
* <p>
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
* <ul>
* <li>Only object classes that are appropriate need to be handle by the
* DBExpression subclass.<li>
* <li>The implementation should be {@code static}</li>
* </ul>
*
* @param string a literal value to use in the expression
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static StringExpression value(StringResult string) {
return new StringExpression(string);
}
/**
* Create An Appropriate Expression Object For This Object
*
* <p>
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
* <p>
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
* <p>
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
* <ul>
* <li>Only object classes that are appropriate need to be handle by the
* DBExpression subclass.<li>
* <li>The implementation should be {@code static}</li>
* </ul>
*
* @param date a literal value to use in the expression
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static DateExpression value(DateResult date) {
return new DateExpression(date);
}
/**
* Create An Appropriate Expression Object For This Object
*
* <p>
* The expression framework requires a *Expression to work with. The easiest
* way to get that is the {@code DBRow.column()} method.
*
* <p>
* However if you wish your expression to start with a literal value it is a
* little trickier.
*
* <p>
* This method provides the easy route to a *Expression from a literal value.
* Just call, for instance, {@code StringExpression.value("STARTING STRING")}
* to get a StringExpression and start the expression chain.
*
* <ul>
* <li>Only object classes that are appropriate need to be handle by the
* DBExpression subclass.<li>
* <li>The implementation should be {@code static}</li>
* </ul>
*
* @param period a literal value to use in the expression
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
* @return a DBExpression instance that is appropriate to the subclass and the
* value supplied.
*/
public final static DateRepeatExpression value(DateRepeatResult period) {
return new DateRepeatExpression(period);
}
public final static DurationExpression value(DurationResult period) {
return new DurationExpression(period);
}
public final static Point2DExpression value(Point point) {
return new Point2DExpression(point);
}
public final static MultiPoint2DExpression value(MultiPoint mpoint) {
return new MultiPoint2DExpression(mpoint);
}
public final static Line2DExpression value(LineString line) {
return new Line2DExpression(line);
}
public final static LineSegment2DExpression value(LineSegment linesegment) {
return new LineSegment2DExpression(linesegment);
}
public final static Polygon2DExpression value(Polygon polygon) {
return new Polygon2DExpression(polygon);
}
public final static BooleanExpression nullBoolean() {
return new BooleanExpression().nullExpression();
}
public final static IntegerExpression nullInteger() {
return new IntegerExpression().nullExpression();
}
public final static NumberExpression nullNumber() {
return new NumberExpression().nullExpression();
}
public final static StringExpression nullString() {
return new StringExpression().nullExpression();
}
public final static DateExpression nullDate() {
return new DateExpression().nullExpression();
}
public final static LocalDateExpression nullLocalDate() {
return new LocalDateExpression().nullExpression();
}
public final static LocalDateTimeExpression nullLocalDateTime() {
return new LocalDateTimeExpression().nullExpression();
}
public final static InstantExpression nullInstant() {
return new InstantExpression().nullExpression();
}
public final static DateRepeatExpression nullDateRepeat() {
return new DateRepeatExpression().nullExpression();
}
public final static DurationExpression nullDuration() {
return new DurationExpression().nullExpression();
}
public final static Point2DExpression nullPoint2D() {
return new Point2DExpression((Point2DResult) null).nullExpression();
}
public final static MultiPoint2DExpression nullMultiPoint2D() {
return new MultiPoint2DExpression().nullExpression();
}
public final static Line2DExpression nullLine2D() {
return new Line2DExpression((Point) null).nullExpression();
}
public final static LineSegment2DExpression nullLineSegment2D() {
return new LineSegment2DExpression((LineSegment2DResult) null).nullExpression();
}
public final static Polygon2DExpression nullPolygon2D() {
return new Polygon2DExpression((Polygon2DResult) null).nullExpression();
}
@Override
public String createSQLForGroupByClause(DBDatabase database) {
return "";
}
public SortProvider ascending() {
return new SortProvider.Ascending(this);
}
public SortProvider descending() {
return new SortProvider.Descending(this);
}
public SortProvider lowestFirst() {
return ascending();
}
public SortProvider highestFirst() {
return descending();
}
public SortProvider lowestLast() {
return descending();
}
public SortProvider highestLast() {
return ascending();
}
/**
* Synonym for {@link #countNotNull() }.
*
* <p>
* Creates an expression that will count all the values of the column
* supplied.</p>
*
* <p>
* Count is an aggregator function for use in DBReport or in a column
* expression.
*
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
*
* @return a number expression.
*/
public final CountExpression count() {
return countNotNull();
}
/**
* Creates an expression that will count all the rows with non-null values in
* the column supplied.
*
* <p>
* Count is an aggregator function for use in DBReport or in a column
* expression.
*
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
*
* @return a number expression.
*/
public CountExpression countNotNull() {
return new CountExpression(this);
}
/**
* Creates an expression that will count all the distinct values in the column
* supplied.
*
* <p>
* Count is an aggregator function for use in DBReport or in a column
* expression.
*
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
*
* @return a number expression.
*/
public CountDistinctExpression countDistinctValues() {
return new CountDistinctExpression(this);
}
/**
* Creates a running count expression based on the values specified.
*
* <p>
* This expression uses the windowing functions to create a partitioned count
* window which returns the value of the expression plus all the preceding
* counts.</p>
*
* <p>
* Please note that, like all windowing functions, the ordering on the
* expression is unrelated to the ordering on the query.</p>
*
* <p>
* If you would like more control over the running total use something like
* tableName.column(tableName.priceColumn).sum().over() to get started.</p>
*
* @param expressionsToPartitionBy the expression that defines the "partition by" clause of the running count
* @param expressionsToOrderBy the expression that defines the "order by" clause of the running count
* @return an integer expression that evaluated to a running count of some aspect of the query
*/
public IntegerExpression runningCount(RangeExpression<?, ?, ?>[] expressionsToPartitionBy, SortProvider... expressionsToOrderBy) {
return this.count().over().partition(expressionsToPartitionBy).orderBy(expressionsToOrderBy).withoutFrame();
}
public static WindowFunctionRequiresOrderBy<IntegerExpression> rank() {
return new RankExpression().over();
}
public static WindowFunctionRequiresOrderBy<NumberExpression> percentageRank() {
return new PercentageExpression().over();
}
public static WindowFunctionRequiresOrderBy<IntegerExpression> denseRank() {
return new DenseRankExpression().over();
}
public static WindowFunctionRequiresOrderBy<IntegerExpression> rowNumber() {
return new RowNumberExpression().over();
}
public static WindowFunctionRequiresOrderBy<IntegerExpression> nTile(Integer tiles) {
return new NTileExpression(tiles).over();
}
public static WindowFunctionRequiresOrderBy<IntegerExpression> nTile(IntegerExpression tiles) {
return new NTileExpression(tiles).over();
}
public static WindowFunctionRequiresOrderBy<IntegerExpression> nTile(Long tiles) {
return new NTileExpression(tiles).over();
}
public static class CountExpression extends IntegerExpression implements CanBeWindowingFunctionWithFrame<IntegerExpression> {
public CountExpression(AnyResult<?> only) {
super(only);
}
private final static long serialVersionUID = 1l;
@Override
public String toSQLString(DBDefinition db) {
return db.getCountFunctionName() + "(" + getInnerResult().toSQLString(db) + ")";
}
@Override
public boolean isAggregator() {
return true;
}
@Override
public CountExpression copy() {
return new CountExpression(
(AnyResult<?>) (getInnerResult() == null ? null : getInnerResult().copy())
);
}
@Override
public WindowFunctionFramable<IntegerExpression> over() {
return new WindowFunctionFramable<IntegerExpression>(new IntegerExpression(this));
}
}
public static class CountDistinctExpression extends IntegerExpression implements CanBeWindowingFunctionWithFrame<IntegerExpression> {
public CountDistinctExpression(AnyResult<?> only) {
super(only);
}
private final static long serialVersionUID = 1l;
@Override
public String toSQLString(DBDefinition db) {
return db.getCountFunctionName() + "(DISTINCT " + getInnerResult().toSQLString(db) + ")";
}
@Override
public boolean isAggregator() {
return true;
}
@Override
public CountDistinctExpression copy() {
return new CountDistinctExpression(
(AnyResult<?>) (getInnerResult() == null ? null : getInnerResult().copy())
);
}
@Override
public WindowFunctionFramable<IntegerExpression> over() {
return new WindowFunctionFramable<IntegerExpression>(new IntegerExpression(this));
}
}
/**
* Aggregrator that counts all the rows of the query.
*
* <p style="color: #F90;">Support DBvolution at
* <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
*
* @return the count of all the values from the column.
*/
public static CountAllExpression countAll() {
return new CountAllExpression();
}
public static class CountAllExpression extends IntegerExpression implements CanBeWindowingFunctionWithFrame<IntegerExpression> {
public CountAllExpression() {
super();
}
private final static long serialVersionUID = 1l;
@Override
public String toSQLString(DBDefinition db) {
return db.getCountFunctionName() + "(*)";
}
@Override
public boolean isAggregator() {
return true;
}
@Override
public CountAllExpression copy() {
return new CountAllExpression();
}
@Override
public WindowFunctionFramable<IntegerExpression> over() {
return new WindowFunctionFramable<IntegerExpression>(new IntegerExpression(this));
}
}
public static class RankExpression extends IntegerExpression implements CanBeWindowingFunctionRequiresOrderBy<IntegerExpression> {
public RankExpression() {
super();
}
private final static long serialVersionUID = 1l;
@Override
public String toSQLString(DBDefinition db) {
return db.getRankFunctionName() + "()";
}
@Override
public boolean isAggregator() {
return false;
}
@Override
public RankExpression copy() {
return new RankExpression();
}
@Override
public WindowFunctionRequiresOrderBy<IntegerExpression> over() {
return new WindowFunctionRequiresOrderBy<IntegerExpression>(new IntegerExpression(this));
}
}
public static class PercentageExpression extends NumberExpression implements CanBeWindowingFunctionRequiresOrderBy<NumberExpression> {
public PercentageExpression() {
super();
}
private final static long serialVersionUID = 1l;
@Override
public String toSQLString(DBDefinition db) {
return db.getPercentRankFunctionName() + "()";
}
@Override
public boolean isAggregator() {
return false;
}
@Override
public PercentageExpression copy() {
return new PercentageExpression();
}
@Override
public WindowFunctionRequiresOrderBy<NumberExpression> over() {
return new WindowFunctionRequiresOrderBy<NumberExpression>(new NumberExpression(this));
}
}
private static class DenseRankExpression extends IntegerExpression implements CanBeWindowingFunctionRequiresOrderBy<IntegerExpression> {
public DenseRankExpression() {
super();
}
private final static long serialVersionUID = 1l;
@Override
public String toSQLString(DBDefinition db) {
return db.getDenseRankFunctionName() + "()";
}
@Override
public boolean isAggregator() {
return false;
}
@Override
public DenseRankExpression copy() {
return new DenseRankExpression();
}
@Override
public WindowFunctionRequiresOrderBy<IntegerExpression> over() {
return new WindowFunctionRequiresOrderBy<IntegerExpression>(new IntegerExpression(this));
}
}
private static class RowNumberExpression extends IntegerExpression implements CanBeWindowingFunctionRequiresOrderBy<IntegerExpression> {
public RowNumberExpression() {
super();
}
private final static long serialVersionUID = 1l;
@Override
public String toSQLString(DBDefinition db) {
return db.getRowNumberFunctionName() + "()";
}
@Override
public boolean isAggregator() {
return false;
}
@Override
public RowNumberExpression copy() {
return new RowNumberExpression();
}
@Override
public WindowFunctionRequiresOrderBy<IntegerExpression> over() {
return new WindowFunctionRequiresOrderBy<IntegerExpression>(new IntegerExpression(this));
}
}
public static class NTileExpression extends IntegerExpression implements CanBeWindowingFunctionRequiresOrderBy<IntegerExpression> {
public NTileExpression(IntegerExpression only) {
super(only);
}
public NTileExpression(Long only) {
super(new IntegerExpression(only));
}
public NTileExpression(Integer only) {
super(new IntegerExpression(only));
}
private final static long serialVersionUID = 1l;
@Override
public String toSQLString(DBDefinition db) {
return db.getNTilesFunctionName() + "(" + getInnerResult().toSQLString(db) + ")";
}
@Override
public boolean isAggregator() {
return false;
}
@Override
public NTileExpression copy() {
return new NTileExpression(
(IntegerExpression) (getInnerResult() == null ? null : getInnerResult().copy())
);
}
@Override
public WindowFunctionRequiresOrderBy<IntegerExpression> over() {
return new WindowFunctionRequiresOrderBy<IntegerExpression>(new IntegerExpression(this));
}
}
}