AnyExpression.java

  1. /*
  2.  * Copyright 2018 gregorygraham.
  3.  *
  4.  * This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
  5.  * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/
  6.  * or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
  7.  *
  8.  * You are free to:
  9.  *     Share - copy and redistribute the material in any medium or format
  10.  *     Adapt - remix, transform, and build upon the material
  11.  *
  12.  *     The licensor cannot revoke these freedoms as long as you follow the license terms.              
  13.  *     Under the following terms:
  14.  *                
  15.  *         Attribution -
  16.  *             You must give appropriate credit, provide a link to the license, and indicate if changes were made.
  17.  *             You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
  18.  *         NonCommercial -
  19.  *             You may not use the material for commercial purposes.
  20.  *         ShareAlike -
  21.  *             If you remix, transform, or build upon the material,
  22.  *             you must distribute your contributions under the same license as the original.
  23.  *         No additional restrictions -
  24.  *             You may not apply legal terms or technological measures that legally restrict others from doing anything the
  25.  *             license permits.
  26.  *
  27.  * Check the Creative Commons website for any details, legalese, and updates.
  28.  */
  29. package nz.co.gregs.dbvolution.expressions;

  30. import nz.co.gregs.dbvolution.expressions.windows.WindowFunctionFramable;
  31. import nz.co.gregs.dbvolution.expressions.windows.CanBeWindowingFunctionWithFrame;
  32. import nz.co.gregs.dbvolution.expressions.spatial2D.*;
  33. import com.vividsolutions.jts.geom.LineSegment;
  34. import com.vividsolutions.jts.geom.LineString;
  35. import com.vividsolutions.jts.geom.MultiPoint;
  36. import com.vividsolutions.jts.geom.Point;
  37. import com.vividsolutions.jts.geom.Polygon;
  38. import java.io.Serializable;
  39. import java.time.Duration;
  40. import java.time.Instant;
  41. import java.time.LocalDate;
  42. import java.time.LocalDateTime;
  43. import java.util.*;
  44. import nz.co.gregs.dbvolution.DBRow;
  45. import nz.co.gregs.dbvolution.databases.DBDatabase;
  46. import nz.co.gregs.dbvolution.databases.definitions.DBDefinition;
  47. import nz.co.gregs.dbvolution.results.AnyResult;
  48. import nz.co.gregs.dbvolution.datatypes.QueryableDatatype;
  49. import nz.co.gregs.dbvolution.expressions.windows.WindowFunctionRequiresOrderBy;
  50. import nz.co.gregs.dbvolution.results.*;
  51. import org.joda.time.Period;
  52. import nz.co.gregs.dbvolution.expressions.windows.CanBeWindowingFunctionRequiresOrderBy;

  53. /**
  54.  *
  55.  * @author gregorygraham
  56.  * @param <B> the base Java type of this expression, e.g. Integer
  57.  * @param <R> the Results type of this expression, e.g. IntegerExpression
  58.  * @param <D> the QDT of this expression, e.g. DBInteger
  59.  */
  60. public abstract class AnyExpression<B extends Object, R extends AnyResult<B>, D extends QueryableDatatype<B>> implements ExpressionColumn<D>, AnyResult<B>, Serializable {

  61.     private final static long serialVersionUID = 1l;

  62.     private final AnyResult<?> innerResult;
  63.     private final boolean nullProtectionRequired;

  64.     /**
  65.      * Returns an expression that will evaluate to NULL in SQL.
  66.      *
  67.      * @return an untyped expression that returns NULL
  68.      */
  69.     public AnyExpression<?, ?, ?> nullExpression() {
  70.         return new StringExpression() {
  71.             private final static long serialVersionUID = 1l;

  72.             @Override
  73.             public String toSQLString(DBDefinition db) {
  74.                 return db.getNull();
  75.             }

  76.         };
  77.     }

  78.     abstract public R expression(B value);

  79.     abstract public R expression(R value);

  80.     abstract public R expression(D value);

  81.     public R asResult() {
  82.         return (R) this;
  83.     }

  84.     @Override
  85.     public String createSQLForFromClause(DBDatabase database) {
  86.         return getInnerResult().createSQLForFromClause(database);
  87.     }

  88.     @Override
  89.     public Set<DBRow> getTablesInvolved() {
  90.         final AnyResult<?> inner = getInnerResult();
  91.         Set<DBRow> result = new HashSet<>(0);
  92.         if (inner != null) {
  93.             result = inner.getTablesInvolved();
  94.         }
  95.         return result;
  96.     }

  97.     @Override
  98.     public boolean isAggregator() {
  99.         final AnyResult<?> inner = getInnerResult();
  100.         return inner == null ? false : inner.isAggregator();
  101.     }

  102.     @Override
  103.     public boolean isWindowingFunction() {
  104.         final AnyResult<?> inner = getInnerResult();
  105.         return inner == null ? false : inner.isWindowingFunction();
  106.     }

  107.     @Override
  108.     public String toSQLString(DBDefinition db) {
  109.         if (getInnerResult() == null) {
  110.             return this.nullExpression().toSQLString(db);// db.getNull();
  111.         } else {
  112.             return getInnerResult().toSQLString(db);
  113.         }
  114.     }

  115.     /**
  116.      * A complex expression requires more than just a function call in the select
  117.      * clause.
  118.      *
  119.      * @return FALSE, unless you need a subtable to work out your expressions's
  120.      * value
  121.      */
  122.     @Override
  123.     public boolean isComplexExpression() {
  124.         AnyResult<?> inner = getInnerResult();
  125.         if (inner == null) {
  126.             return false;
  127.         } else {
  128.             return inner.isComplexExpression();
  129.         }
  130.     }

  131.     @Override
  132.     public boolean isPurelyFunctional() {
  133.         if (getInnerResult() == null) {
  134.             return true;
  135.         } else {
  136.             return getInnerResult().isPurelyFunctional();
  137.         }
  138.     }

  139.     /**
  140.      * Does nothing
  141.      *
  142.      */
  143.     public AnyExpression() {
  144.         innerResult = null;
  145.         /* This creates a terminator expression for null-safety chains */
  146.         nullProtectionRequired = false;
  147.     }

  148.     /**
  149.      *
  150.      * @param only an expression of any type
  151.      */
  152.     public AnyExpression(AnyResult<?> only) {
  153.         innerResult = only;
  154.         nullProtectionRequired = only == null ? true : innerResult.getIncludesNull();
  155.     }

  156.     protected boolean isNullSafetyTerminator() {
  157.         return getInnerResult() == null && (getIncludesNull() == false);
  158.     }

  159.     public AnyResult<?> getInnerResult() {
  160.         return innerResult;
  161.     }

  162.     @Override
  163.     public boolean getIncludesNull() {
  164.         AnyResult<?> inner = getInnerResult();
  165.         return nullProtectionRequired || (inner == null ? false : inner.getIncludesNull());
  166.     }

  167.     /**
  168.      * Create An Appropriate Expression Object For This Object
  169.      *
  170.      * <p>
  171.      * The expression framework requires a *Expression to work with. The easiest
  172.      * way to get that is the {@code DBRow.column()} method.
  173.      *
  174.      * <p>
  175.      * However if you wish your expression to start with a literal value it is a
  176.      * little trickier.
  177.      *
  178.      * <p>
  179.      * This method provides the easy route to a *Expression from a literal value.
  180.      * Just call, for instance, {@code StringExpression.value("STARTING STRING")}
  181.      * to get a StringExpression and start the expression chain.
  182.      *
  183.      * <ul>
  184.      * <li>Only object classes that are appropriate need to be handle by the
  185.      * DBExpression subclass.<li>
  186.      * <li>The implementation should be {@code static}</li>
  187.      * </ul>
  188.      *
  189.      * @param value a literal value to use in the expression
  190.      * <p style="color: #F90;">Support DBvolution at
  191.      * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  192.      * @return a DBExpression instance that is appropriate to the subclass and the
  193.      * value supplied.
  194.      */
  195.     public final static BooleanExpression value(Boolean value) {
  196.         return new BooleanExpression(value);
  197.     }

  198.     /**
  199.      * Create An Appropriate Expression Object For This Object
  200.      *
  201.      * <p>
  202.      * The expression framework requires a *Expression to work with. The easiest
  203.      * way to get that is the {@code DBRow.column()} method.
  204.      *
  205.      * <p>
  206.      * However if you wish your expression to start with a literal value it is a
  207.      * little trickier.
  208.      *
  209.      * <p>
  210.      * This method provides the easy route to a *Expression from a literal value.
  211.      * Just call, for instance, {@code StringExpression.value("STARTING STRING")}
  212.      * to get a StringExpression and start the expression chain.
  213.      *
  214.      * <ul>
  215.      * <li>Only object classes that are appropriate need to be handle by the
  216.      * DBExpression subclass.<li>
  217.      * <li>The implementation should be {@code static}</li>
  218.      * </ul>
  219.      *
  220.      * @param integer a literal value to use in the expression
  221.      * <p style="color: #F90;">Support DBvolution at
  222.      * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  223.      * @return a DBExpression instance that is appropriate to the subclass and the
  224.      * value supplied.
  225.      */
  226.     public final static IntegerExpression value(Integer integer) {
  227.         if (integer == null) {
  228.             return nullInteger();
  229.         } else {
  230.             return new IntegerExpression(integer);
  231.         }
  232.     }

  233.     /**
  234.      * Create An Appropriate Expression Object For This Object
  235.      *
  236.      * <p>
  237.      * The expression framework requires a *Expression to work with. The easiest
  238.      * way to get that is the {@code DBRow.column()} method.
  239.      *
  240.      * <p>
  241.      * However if you wish your expression to start with a literal value it is a
  242.      * little trickier.
  243.      *
  244.      * <p>
  245.      * This method provides the easy route to a *Expression from a literal value.
  246.      * Just call, for instance, {@code StringExpression.value("STARTING STRING")}
  247.      * to get a StringExpression and start the expression chain.
  248.      *
  249.      * <ul>
  250.      * <li>Only object classes that are appropriate need to be handle by the
  251.      * DBExpression subclass.<li>
  252.      * <li>The implementation should be {@code static}</li>
  253.      * </ul>
  254.      *
  255.      * @param integer a literal value to use in the expression
  256.      * <p style="color: #F90;">Support DBvolution at
  257.      * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  258.      * @return a DBExpression instance that is appropriate to the subclass and the
  259.      * value supplied.
  260.      */
  261.     public final static IntegerExpression value(Long integer) {
  262.         return new IntegerExpression(integer);
  263.     }

  264.     /**
  265.      * Create An Appropriate Expression Object For This Object
  266.      *
  267.      * <p>
  268.      * The expression framework requires a *Expression to work with. The easiest
  269.      * way to get that is the {@code DBRow.column()} method.
  270.      *
  271.      * <p>
  272.      * However if you wish your expression to start with a literal value it is a
  273.      * little trickier.
  274.      *
  275.      * <p>
  276.      * This method provides the easy route to a *Expression from a literal value.
  277.      * Just call, for instance, {@code StringExpression.value("STARTING STRING")}
  278.      * to get a StringExpression and start the expression chain.
  279.      *
  280.      * <ul>
  281.      * <li>Only object classes that are appropriate need to be handle by the
  282.      * DBExpression subclass.<li>
  283.      * <li>The implementation should be {@code static}</li>
  284.      * </ul>
  285.      *
  286.      * @param integer a literal value to use in the expression
  287.      * <p style="color: #F90;">Support DBvolution at
  288.      * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  289.      * @return a DBExpression instance that is appropriate to the subclass and the
  290.      * value supplied.
  291.      */
  292.     public final static IntegerExpression value(int integer) {
  293.         return new IntegerExpression(integer);
  294.     }

  295.     /**
  296.      * Create An Appropriate Expression Object For This Object
  297.      *
  298.      * <p>
  299.      * The expression framework requires a *Expression to work with. The easiest
  300.      * way to get that is the {@code DBRow.column()} method.
  301.      *
  302.      * <p>
  303.      * However if you wish your expression to start with a literal value it is a
  304.      * little trickier.
  305.      *
  306.      * <p>
  307.      * This method provides the easy route to a *Expression from a literal value.
  308.      * Just call, for instance, {@code StringExpression.value("STARTING STRING")}
  309.      * to get a StringExpression and start the expression chain.
  310.      *
  311.      * <ul>
  312.      * <li>Only object classes that are appropriate need to be handle by the
  313.      * DBExpression subclass.<li>
  314.      * <li>The implementation should be {@code static}</li>
  315.      * </ul>
  316.      *
  317.      * @param integer a literal value to use in the expression
  318.      * <p style="color: #F90;">Support DBvolution at
  319.      * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  320.      * @return a DBExpression instance that is appropriate to the subclass and the
  321.      * value supplied.
  322.      */
  323.     public final static IntegerExpression value(long integer) {
  324.         return new IntegerExpression(integer);
  325.     }

  326.     /**
  327.      * Create An Appropriate Expression Object For This Object
  328.      *
  329.      * <p>
  330.      * The expression framework requires a *Expression to work with. The easiest
  331.      * way to get that is the {@code DBRow.column()} method.
  332.      *
  333.      * <p>
  334.      * However if you wish your expression to start with a literal value it is a
  335.      * little trickier.
  336.      *
  337.      * <p>
  338.      * This method provides the easy route to a *Expression from a literal value.
  339.      * Just call, for instance, {@code StringExpression.value("STARTING STRING")}
  340.      * to get a StringExpression and start the expression chain.
  341.      *
  342.      * <ul>
  343.      * <li>Only object classes that are appropriate need to be handle by the
  344.      * DBExpression subclass.<li>
  345.      * <li>The implementation should be {@code static}</li>
  346.      * </ul>
  347.      *
  348.      * @param number a literal value to use in the expression
  349.      * <p style="color: #F90;">Support DBvolution at
  350.      * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  351.      * @return a DBExpression instance that is appropriate to the subclass and the
  352.      * value supplied.
  353.      */
  354.     public final static NumberExpression value(Number number) {
  355.         return new NumberExpression(number);
  356.     }

  357.     /**
  358.      * Create An Appropriate Expression Object For This Object
  359.      *
  360.      * <p>
  361.      * The expression framework requires a *Expression to work with. The easiest
  362.      * way to get that is the {@code DBRow.column()} method.
  363.      *
  364.      * <p>
  365.      * However if you wish your expression to start with a literal value it is a
  366.      * little trickier.
  367.      *
  368.      * <p>
  369.      * This method provides the easy route to a *Expression from a literal value.
  370.      * Just call, for instance, {@code StringExpression.value("STARTING STRING")}
  371.      * to get a StringExpression and start the expression chain.
  372.      *
  373.      * <ul>
  374.      * <li>Only object classes that are appropriate need to be handle by the
  375.      * DBExpression subclass.<li>
  376.      * <li>The implementation should be {@code static}</li>
  377.      * </ul>
  378.      *
  379.      * @param string a literal value to use in the expression
  380.      * <p style="color: #F90;">Support DBvolution at
  381.      * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  382.      * @return a DBExpression instance that is appropriate to the subclass and the
  383.      * value supplied.
  384.      */
  385.     public final static StringLiteral value(String string) {
  386.         return new StringLiteral(string);
  387.     }

  388.     /**
  389.      * Create An Appropriate Expression Object For This Object
  390.      *
  391.      * <p>
  392.      * The expression framework requires a *Expression to work with. The easiest
  393.      * way to get that is the {@code DBRow.column()} method.
  394.      *
  395.      * <p>
  396.      * However if you wish your expression to start with a literal value it is a
  397.      * little trickier.
  398.      *
  399.      * <p>
  400.      * This method provides the easy route to a *Expression from a literal value.
  401.      * Just call, for instance, {@code StringExpression.value("STARTING STRING")}
  402.      * to get a StringExpression and start the expression chain.
  403.      *
  404.      * <ul>
  405.      * <li>Only object classes that are appropriate need to be handle by the
  406.      * DBExpression subclass.<li>
  407.      * <li>The implementation should be {@code static}</li>
  408.      * </ul>
  409.      *
  410.      * @param date a literal value to use in the expression
  411.      * <p style="color: #F90;">Support DBvolution at
  412.      * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  413.      * @return a DBExpression instance that is appropriate to the subclass and the
  414.      * value supplied.
  415.      */
  416.     public final static DateExpression value(Date date) {
  417.         return new DateExpression(date);
  418.     }

  419.     /**
  420.      * Create An Appropriate Expression Object For This Object
  421.      *
  422.      * <p>
  423.      * The expression framework requires a *Expression to work with. The easiest
  424.      * way to get that is the {@code DBRow.column()} method.
  425.      *
  426.      * <p>
  427.      * However if you wish your expression to start with a literal value it is a
  428.      * little trickier.
  429.      *
  430.      * <p>
  431.      * This method provides the easy route to a *Expression from a literal value.
  432.      * Just call, for instance, {@code StringExpression.value("STARTING STRING")}
  433.      * to get a StringExpression and start the expression chain.
  434.      *
  435.      * <ul>
  436.      * <li>Only object classes that are appropriate need to be handle by the
  437.      * DBExpression subclass.<li>
  438.      * <li>The implementation should be {@code static}</li>
  439.      * </ul>
  440.      *
  441.      * @param date a literal value to use in the expression
  442.      * <p style="color: #F90;">Support DBvolution at
  443.      * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  444.      * @return a DBExpression instance that is appropriate to the subclass and the
  445.      * value supplied.
  446.      */
  447.     public final static LocalDateExpression value(LocalDate date) {
  448.         return new LocalDateExpression(date);
  449.     }

  450.     /**
  451.      * Create An Appropriate Expression Object For This Object
  452.      *
  453.      * <p>
  454.      * The expression framework requires a *Expression to work with. The easiest
  455.      * way to get that is the {@code DBRow.column()} method.
  456.      *
  457.      * <p>
  458.      * However if you wish your expression to start with a literal value it is a
  459.      * little trickier.
  460.      *
  461.      * <p>
  462.      * This method provides the easy route to a *Expression from a literal value.
  463.      * Just call, for instance, {@code StringExpression.value("STARTING STRING")}
  464.      * to get a StringExpression and start the expression chain.
  465.      *
  466.      * <ul>
  467.      * <li>Only object classes that are appropriate need to be handle by the
  468.      * DBExpression subclass.<li>
  469.      * <li>The implementation should be {@code static}</li>
  470.      * </ul>
  471.      *
  472.      * @param date a literal value to use in the expression
  473.      * <p style="color: #F90;">Support DBvolution at
  474.      * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  475.      * @return a DBExpression instance that is appropriate to the subclass and the
  476.      * value supplied.
  477.      */
  478.     public final static LocalDateTimeExpression value(LocalDateTime date) {
  479.         return new LocalDateTimeExpression(date);
  480.     }

  481.     /**
  482.      * Create An Appropriate Expression Object For This Object
  483.      *
  484.      * <p>
  485.      * The expression framework requires a *Expression to work with. The easiest
  486.      * way to get that is the {@code DBRow.column()} method.
  487.      *
  488.      * <p>
  489.      * However if you wish your expression to start with a literal value it is a
  490.      * little trickier.
  491.      *
  492.      * <p>
  493.      * This method provides the easy route to a *Expression from a literal value.
  494.      * Just call, for instance, {@code StringExpression.value("STARTING STRING")}
  495.      * to get a StringExpression and start the expression chain.
  496.      *
  497.      * <ul>
  498.      * <li>Only object classes that are appropriate need to be handle by the
  499.      * DBExpression subclass.<li>
  500.      * <li>The implementation should be {@code static}</li>
  501.      * </ul>
  502.      *
  503.      * @param date a literal value to use in the expression
  504.      * <p style="color: #F90;">Support DBvolution at
  505.      * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  506.      * @return a DBExpression instance that is appropriate to the subclass and the
  507.      * value supplied.
  508.      */
  509.     public final static InstantExpression value(Instant date) {
  510.         return new InstantExpression(date);
  511.     }

  512.     /**
  513.      * Create An Appropriate Expression Object For This Object
  514.      *
  515.      * <p>
  516.      * The expression framework requires a *Expression to work with. The easiest
  517.      * way to get that is the {@code DBRow.column()} method.
  518.      *
  519.      * <p>
  520.      * However if you wish your expression to start with a literal value it is a
  521.      * little trickier.
  522.      *
  523.      * <p>
  524.      * This method provides the easy route to a *Expression from a literal value.
  525.      * Just call, for instance, {@code StringExpression.value("STARTING STRING")}
  526.      * to get a StringExpression and start the expression chain.
  527.      *
  528.      * <ul>
  529.      * <li>Only object classes that are appropriate need to be handle by the
  530.      * DBExpression subclass.<li>
  531.      * <li>The implementation should be {@code static}</li>
  532.      * </ul>
  533.      *
  534.      * @param period a literal value to use in the expression
  535.      * <p style="color: #F90;">Support DBvolution at
  536.      * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  537.      * @return a DBExpression instance that is appropriate to the subclass and the
  538.      * value supplied.
  539.      */
  540.     public final static DateRepeatExpression value(Period period) {
  541.         return new DateRepeatExpression(period);
  542.     }

  543.     /**
  544.      * Create An Appropriate Expression Object For This Object
  545.      *
  546.      * <p>
  547.      * The expression framework requires a *Expression to work with. The easiest
  548.      * way to get that is the {@code DBRow.column()} method.
  549.      *
  550.      * <p>
  551.      * However if you wish your expression to start with a literal value it is a
  552.      * little trickier.
  553.      *
  554.      * <p>
  555.      * This method provides the easy route to a *Expression from a literal value.
  556.      * Just call, for instance, {@code StringExpression.value("STARTING STRING")}
  557.      * to get a StringExpression and start the expression chain.
  558.      *
  559.      * <ul>
  560.      * <li>Only object classes that are appropriate need to be handle by the
  561.      * DBExpression subclass.<li>
  562.      * <li>The implementation should be {@code static}</li>
  563.      * </ul>
  564.      *
  565.      * @param duration a literal value to use in the expression
  566.      * <p style="color: #F90;">Support DBvolution at
  567.      * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  568.      * @return a DBExpression instance that is appropriate to the subclass and the
  569.      * value supplied.
  570.      */
  571.     public final static DurationExpression value(Duration duration) {
  572.         return new DurationExpression(duration);
  573.     }

  574.     /**
  575.      * Create An Appropriate Expression Object For This Object
  576.      *
  577.      * <p>
  578.      * The expression framework requires a *Expression to work with. The easiest
  579.      * way to get that is the {@code DBRow.column()} method.
  580.      *
  581.      * <p>
  582.      * However if you wish your expression to start with a literal value it is a
  583.      * little trickier.
  584.      *
  585.      * <p>
  586.      * This method provides the easy route to a *Expression from a literal value.
  587.      * Just call, for instance, {@code StringExpression.value("STARTING STRING")}
  588.      * to get a StringExpression and start the expression chain.
  589.      *
  590.      * <ul>
  591.      * <li>Only object classes that are appropriate need to be handle by the
  592.      * DBExpression subclass.<li>
  593.      * <li>The implementation should be {@code static}</li>
  594.      * </ul>
  595.      *
  596.      * @param value a literal value to use in the expression
  597.      * <p style="color: #F90;">Support DBvolution at
  598.      * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  599.      * @return a DBExpression instance that is appropriate to the subclass and the
  600.      * value supplied.
  601.      */
  602.     public final static BooleanExpression value(BooleanResult value) {
  603.         return new BooleanExpression(value);
  604.     }

  605.     /**
  606.      * Create An Appropriate Expression Object For This Object
  607.      *
  608.      * <p>
  609.      * The expression framework requires a *Expression to work with. The easiest
  610.      * way to get that is the {@code DBRow.column()} method.
  611.      *
  612.      * <p>
  613.      * However if you wish your expression to start with a literal value it is a
  614.      * little trickier.
  615.      *
  616.      * <p>
  617.      * This method provides the easy route to a *Expression from a literal value.
  618.      * Just call, for instance, {@code StringExpression.value("STARTING STRING")}
  619.      * to get a StringExpression and start the expression chain.
  620.      *
  621.      * <ul>
  622.      * <li>Only object classes that are appropriate need to be handle by the
  623.      * DBExpression subclass.<li>
  624.      * <li>The implementation should be {@code static}</li>
  625.      * </ul>
  626.      *
  627.      * @param integer a literal value to use in the expression
  628.      * <p style="color: #F90;">Support DBvolution at
  629.      * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  630.      * @return a DBExpression instance that is appropriate to the subclass and the
  631.      * value supplied.
  632.      */
  633.     public final static IntegerExpression value(IntegerResult integer) {
  634.         return new IntegerExpression(integer);
  635.     }

  636.     /**
  637.      * Create An Appropriate Expression Object For This Object
  638.      *
  639.      * <p>
  640.      * The expression framework requires a *Expression to work with. The easiest
  641.      * way to get that is the {@code DBRow.column()} method.
  642.      *
  643.      * <p>
  644.      * However if you wish your expression to start with a literal value it is a
  645.      * little trickier.
  646.      *
  647.      * <p>
  648.      * This method provides the easy route to a *Expression from a literal value.
  649.      * Just call, for instance, {@code StringExpression.value("STARTING STRING")}
  650.      * to get a StringExpression and start the expression chain.
  651.      *
  652.      * <ul>
  653.      * <li>Only object classes that are appropriate need to be handle by the
  654.      * DBExpression subclass.<li>
  655.      * <li>The implementation should be {@code static}</li>
  656.      * </ul>
  657.      *
  658.      * @param number a literal value to use in the expression
  659.      * <p style="color: #F90;">Support DBvolution at
  660.      * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  661.      * @return a DBExpression instance that is appropriate to the subclass and the
  662.      * value supplied.
  663.      */
  664.     public final static NumberExpression value(NumberResult number) {
  665.         return new NumberExpression(number);
  666.     }

  667.     /**
  668.      * Create An Appropriate Expression Object For This Object
  669.      *
  670.      * <p>
  671.      * The expression framework requires a *Expression to work with. The easiest
  672.      * way to get that is the {@code DBRow.column()} method.
  673.      *
  674.      * <p>
  675.      * However if you wish your expression to start with a literal value it is a
  676.      * little trickier.
  677.      *
  678.      * <p>
  679.      * This method provides the easy route to a *Expression from a literal value.
  680.      * Just call, for instance, {@code StringExpression.value("STARTING STRING")}
  681.      * to get a StringExpression and start the expression chain.
  682.      *
  683.      * <ul>
  684.      * <li>Only object classes that are appropriate need to be handle by the
  685.      * DBExpression subclass.<li>
  686.      * <li>The implementation should be {@code static}</li>
  687.      * </ul>
  688.      *
  689.      * @param string a literal value to use in the expression
  690.      * <p style="color: #F90;">Support DBvolution at
  691.      * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  692.      * @return a DBExpression instance that is appropriate to the subclass and the
  693.      * value supplied.
  694.      */
  695.     public final static StringExpression value(StringResult string) {
  696.         return new StringExpression(string);
  697.     }

  698.     /**
  699.      * Create An Appropriate Expression Object For This Object
  700.      *
  701.      * <p>
  702.      * The expression framework requires a *Expression to work with. The easiest
  703.      * way to get that is the {@code DBRow.column()} method.
  704.      *
  705.      * <p>
  706.      * However if you wish your expression to start with a literal value it is a
  707.      * little trickier.
  708.      *
  709.      * <p>
  710.      * This method provides the easy route to a *Expression from a literal value.
  711.      * Just call, for instance, {@code StringExpression.value("STARTING STRING")}
  712.      * to get a StringExpression and start the expression chain.
  713.      *
  714.      * <ul>
  715.      * <li>Only object classes that are appropriate need to be handle by the
  716.      * DBExpression subclass.<li>
  717.      * <li>The implementation should be {@code static}</li>
  718.      * </ul>
  719.      *
  720.      * @param date a literal value to use in the expression
  721.      * <p style="color: #F90;">Support DBvolution at
  722.      * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  723.      * @return a DBExpression instance that is appropriate to the subclass and the
  724.      * value supplied.
  725.      */
  726.     public final static DateExpression value(DateResult date) {
  727.         return new DateExpression(date);
  728.     }

  729.     /**
  730.      * Create An Appropriate Expression Object For This Object
  731.      *
  732.      * <p>
  733.      * The expression framework requires a *Expression to work with. The easiest
  734.      * way to get that is the {@code DBRow.column()} method.
  735.      *
  736.      * <p>
  737.      * However if you wish your expression to start with a literal value it is a
  738.      * little trickier.
  739.      *
  740.      * <p>
  741.      * This method provides the easy route to a *Expression from a literal value.
  742.      * Just call, for instance, {@code StringExpression.value("STARTING STRING")}
  743.      * to get a StringExpression and start the expression chain.
  744.      *
  745.      * <ul>
  746.      * <li>Only object classes that are appropriate need to be handle by the
  747.      * DBExpression subclass.<li>
  748.      * <li>The implementation should be {@code static}</li>
  749.      * </ul>
  750.      *
  751.      * @param period a literal value to use in the expression
  752.      * <p style="color: #F90;">Support DBvolution at
  753.      * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  754.      * @return a DBExpression instance that is appropriate to the subclass and the
  755.      * value supplied.
  756.      */
  757.     public final static DateRepeatExpression value(DateRepeatResult period) {
  758.         return new DateRepeatExpression(period);
  759.     }

  760.     public final static DurationExpression value(DurationResult period) {
  761.         return new DurationExpression(period);
  762.     }

  763.     public final static Point2DExpression value(Point point) {
  764.         return new Point2DExpression(point);
  765.     }

  766.     public final static MultiPoint2DExpression value(MultiPoint mpoint) {
  767.         return new MultiPoint2DExpression(mpoint);
  768.     }

  769.     public final static Line2DExpression value(LineString line) {
  770.         return new Line2DExpression(line);
  771.     }

  772.     public final static LineSegment2DExpression value(LineSegment linesegment) {
  773.         return new LineSegment2DExpression(linesegment);
  774.     }

  775.     public final static Polygon2DExpression value(Polygon polygon) {
  776.         return new Polygon2DExpression(polygon);
  777.     }

  778.     public final static BooleanExpression nullBoolean() {
  779.         return new BooleanExpression().nullExpression();
  780.     }

  781.     public final static IntegerExpression nullInteger() {
  782.         return new IntegerExpression().nullExpression();
  783.     }

  784.     public final static NumberExpression nullNumber() {
  785.         return new NumberExpression().nullExpression();
  786.     }

  787.     public final static StringExpression nullString() {
  788.         return new StringExpression().nullExpression();
  789.     }

  790.     public final static DateExpression nullDate() {
  791.         return new DateExpression().nullExpression();
  792.     }

  793.     public final static LocalDateExpression nullLocalDate() {
  794.         return new LocalDateExpression().nullExpression();
  795.     }

  796.     public final static LocalDateTimeExpression nullLocalDateTime() {
  797.         return new LocalDateTimeExpression().nullExpression();
  798.     }

  799.     public final static InstantExpression nullInstant() {
  800.         return new InstantExpression().nullExpression();
  801.     }

  802.     public final static DateRepeatExpression nullDateRepeat() {
  803.         return new DateRepeatExpression().nullExpression();
  804.     }

  805.     public final static DurationExpression nullDuration() {
  806.         return new DurationExpression().nullExpression();
  807.     }

  808.     public final static Point2DExpression nullPoint2D() {
  809.         return new Point2DExpression((Point2DResult) null).nullExpression();
  810.     }

  811.     public final static MultiPoint2DExpression nullMultiPoint2D() {
  812.         return new MultiPoint2DExpression().nullExpression();
  813.     }

  814.     public final static Line2DExpression nullLine2D() {
  815.         return new Line2DExpression((Point) null).nullExpression();
  816.     }

  817.     public final static LineSegment2DExpression nullLineSegment2D() {
  818.         return new LineSegment2DExpression((LineSegment2DResult) null).nullExpression();
  819.     }

  820.     public final static Polygon2DExpression nullPolygon2D() {
  821.         return new Polygon2DExpression((Polygon2DResult) null).nullExpression();
  822.     }

  823.     @Override
  824.     public String createSQLForGroupByClause(DBDatabase database) {
  825.         return "";
  826.     }

  827.     public SortProvider ascending() {
  828.         return new SortProvider.Ascending(this);
  829.     }

  830.     public SortProvider descending() {
  831.         return new SortProvider.Descending(this);
  832.     }

  833.     public SortProvider lowestFirst() {
  834.         return ascending();
  835.     }

  836.     public SortProvider highestFirst() {
  837.         return descending();
  838.     }

  839.     public SortProvider lowestLast() {
  840.         return descending();
  841.     }

  842.     public SortProvider highestLast() {
  843.         return ascending();
  844.     }

  845.     /**
  846.      * Synonym for {@link #countNotNull() }.
  847.      *
  848.      * <p>
  849.      * Creates an expression that will count all the values of the column
  850.      * supplied.</p>
  851.      *
  852.      * <p>
  853.      * Count is an aggregator function for use in DBReport or in a column
  854.      * expression.
  855.      *
  856.      * <p style="color: #F90;">Support DBvolution at
  857.      * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  858.      *
  859.      * @return a number expression.
  860.      */
  861.     public final CountExpression count() {
  862.         return countNotNull();
  863.     }

  864.     /**
  865.      * Creates an expression that will count all the rows with non-null values in
  866.      * the column supplied.
  867.      *
  868.      * <p>
  869.      * Count is an aggregator function for use in DBReport or in a column
  870.      * expression.
  871.      *
  872.      * <p style="color: #F90;">Support DBvolution at
  873.      * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  874.      *
  875.      * @return a number expression.
  876.      */
  877.     public CountExpression countNotNull() {
  878.         return new CountExpression(this);
  879.     }

  880.     /**
  881.      * Creates an expression that will count all the distinct values in the column
  882.      * supplied.
  883.      *
  884.      * <p>
  885.      * Count is an aggregator function for use in DBReport or in a column
  886.      * expression.
  887.      *
  888.      * <p style="color: #F90;">Support DBvolution at
  889.      * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  890.      *
  891.      * @return a number expression.
  892.      */
  893.     public CountDistinctExpression countDistinctValues() {
  894.         return new CountDistinctExpression(this);
  895.     }

  896.     /**
  897.      * Creates a running count expression based on the values specified.
  898.      *
  899.      * <p>
  900.      * This expression uses the windowing functions to create a partitioned count
  901.      * window which returns the value of the expression plus all the preceding
  902.      * counts.</p>
  903.      *
  904.      * <p>
  905.      * Please note that, like all windowing functions, the ordering on the
  906.      * expression is unrelated to the ordering on the query.</p>
  907.      *
  908.      * <p>
  909.      * If you would like more control over the running total use something like
  910.      * tableName.column(tableName.priceColumn).sum().over() to get started.</p>
  911.      *
  912.      * @param expressionsToPartitionBy the expression that defines the "partition by" clause of the running count
  913.      * @param expressionsToOrderBy the expression that defines the "order by" clause of the running count
  914.      * @return an integer expression that evaluated to a running count of some aspect of the query
  915.      */
  916.     public IntegerExpression runningCount(RangeExpression<?, ?, ?>[] expressionsToPartitionBy, SortProvider... expressionsToOrderBy) {
  917.         return this.count().over().partition(expressionsToPartitionBy).orderBy(expressionsToOrderBy).withoutFrame();
  918.     }

  919.     public static WindowFunctionRequiresOrderBy<IntegerExpression> rank() {
  920.         return new RankExpression().over();
  921.     }

  922.     public static WindowFunctionRequiresOrderBy<NumberExpression> percentageRank() {
  923.         return new PercentageExpression().over();
  924.     }

  925.     public static WindowFunctionRequiresOrderBy<IntegerExpression> denseRank() {
  926.         return new DenseRankExpression().over();
  927.     }

  928.     public static WindowFunctionRequiresOrderBy<IntegerExpression> rowNumber() {
  929.         return new RowNumberExpression().over();
  930.     }

  931.     public static WindowFunctionRequiresOrderBy<IntegerExpression> nTile(Integer tiles) {
  932.         return new NTileExpression(tiles).over();
  933.     }

  934.     public static WindowFunctionRequiresOrderBy<IntegerExpression> nTile(IntegerExpression tiles) {
  935.         return new NTileExpression(tiles).over();
  936.     }

  937.     public static WindowFunctionRequiresOrderBy<IntegerExpression> nTile(Long tiles) {
  938.         return new NTileExpression(tiles).over();
  939.     }

  940.     public static class CountExpression extends IntegerExpression implements CanBeWindowingFunctionWithFrame<IntegerExpression> {

  941.         public CountExpression(AnyResult<?> only) {
  942.             super(only);
  943.         }
  944.         private final static long serialVersionUID = 1l;

  945.         @Override
  946.         public String toSQLString(DBDefinition db) {
  947.             return db.getCountFunctionName() + "(" + getInnerResult().toSQLString(db) + ")";
  948.         }

  949.         @Override
  950.         public boolean isAggregator() {
  951.             return true;
  952.         }

  953.         @Override
  954.         public CountExpression copy() {
  955.             return new CountExpression(
  956.                     (AnyResult<?>) (getInnerResult() == null ? null : getInnerResult().copy())
  957.             );
  958.         }

  959.         @Override
  960.         public WindowFunctionFramable<IntegerExpression> over() {
  961.             return new WindowFunctionFramable<IntegerExpression>(new IntegerExpression(this));
  962.         }

  963.     }

  964.     public static class CountDistinctExpression extends IntegerExpression implements CanBeWindowingFunctionWithFrame<IntegerExpression> {

  965.         public CountDistinctExpression(AnyResult<?> only) {
  966.             super(only);
  967.         }
  968.         private final static long serialVersionUID = 1l;

  969.         @Override
  970.         public String toSQLString(DBDefinition db) {
  971.             return db.getCountFunctionName() + "(DISTINCT " + getInnerResult().toSQLString(db) + ")";
  972.         }

  973.         @Override
  974.         public boolean isAggregator() {
  975.             return true;
  976.         }

  977.         @Override
  978.         public CountDistinctExpression copy() {
  979.             return new CountDistinctExpression(
  980.                     (AnyResult<?>) (getInnerResult() == null ? null : getInnerResult().copy())
  981.             );
  982.         }

  983.         @Override
  984.         public WindowFunctionFramable<IntegerExpression> over() {
  985.             return new WindowFunctionFramable<IntegerExpression>(new IntegerExpression(this));
  986.         }

  987.     }

  988.     /**
  989.      * Aggregrator that counts all the rows of the query.
  990.      *
  991.      * <p style="color: #F90;">Support DBvolution at
  992.      * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  993.      *
  994.      * @return the count of all the values from the column.
  995.      */
  996.     public static CountAllExpression countAll() {
  997.         return new CountAllExpression();
  998.     }

  999.     public static class CountAllExpression extends IntegerExpression implements CanBeWindowingFunctionWithFrame<IntegerExpression> {

  1000.         public CountAllExpression() {
  1001.             super();
  1002.         }
  1003.         private final static long serialVersionUID = 1l;

  1004.         @Override
  1005.         public String toSQLString(DBDefinition db) {
  1006.             return db.getCountFunctionName() + "(*)";
  1007.         }

  1008.         @Override
  1009.         public boolean isAggregator() {
  1010.             return true;
  1011.         }

  1012.         @Override
  1013.         public CountAllExpression copy() {
  1014.             return new CountAllExpression();
  1015.         }

  1016.         @Override
  1017.         public WindowFunctionFramable<IntegerExpression> over() {
  1018.             return new WindowFunctionFramable<IntegerExpression>(new IntegerExpression(this));
  1019.         }
  1020.     }

  1021.     public static class RankExpression extends IntegerExpression implements CanBeWindowingFunctionRequiresOrderBy<IntegerExpression> {

  1022.         public RankExpression() {
  1023.             super();
  1024.         }
  1025.         private final static long serialVersionUID = 1l;

  1026.         @Override
  1027.         public String toSQLString(DBDefinition db) {
  1028.             return db.getRankFunctionName() + "()";
  1029.         }

  1030.         @Override
  1031.         public boolean isAggregator() {
  1032.             return false;
  1033.         }

  1034.         @Override
  1035.         public RankExpression copy() {
  1036.             return new RankExpression();
  1037.         }

  1038.         @Override
  1039.         public WindowFunctionRequiresOrderBy<IntegerExpression> over() {
  1040.             return new WindowFunctionRequiresOrderBy<IntegerExpression>(new IntegerExpression(this));
  1041.         }
  1042.     }

  1043.     public static class PercentageExpression extends NumberExpression implements CanBeWindowingFunctionRequiresOrderBy<NumberExpression> {

  1044.         public PercentageExpression() {
  1045.             super();
  1046.         }
  1047.         private final static long serialVersionUID = 1l;

  1048.         @Override
  1049.         public String toSQLString(DBDefinition db) {
  1050.             return db.getPercentRankFunctionName() + "()";
  1051.         }

  1052.         @Override
  1053.         public boolean isAggregator() {
  1054.             return false;
  1055.         }

  1056.         @Override
  1057.         public PercentageExpression copy() {
  1058.             return new PercentageExpression();
  1059.         }

  1060.         @Override
  1061.         public WindowFunctionRequiresOrderBy<NumberExpression> over() {
  1062.             return new WindowFunctionRequiresOrderBy<NumberExpression>(new NumberExpression(this));
  1063.         }
  1064.     }

  1065.     private static class DenseRankExpression extends IntegerExpression implements CanBeWindowingFunctionRequiresOrderBy<IntegerExpression> {

  1066.         public DenseRankExpression() {
  1067.             super();
  1068.         }
  1069.         private final static long serialVersionUID = 1l;

  1070.         @Override
  1071.         public String toSQLString(DBDefinition db) {
  1072.             return db.getDenseRankFunctionName() + "()";
  1073.         }

  1074.         @Override
  1075.         public boolean isAggregator() {
  1076.             return false;
  1077.         }

  1078.         @Override
  1079.         public DenseRankExpression copy() {
  1080.             return new DenseRankExpression();
  1081.         }

  1082.         @Override
  1083.         public WindowFunctionRequiresOrderBy<IntegerExpression> over() {
  1084.             return new WindowFunctionRequiresOrderBy<IntegerExpression>(new IntegerExpression(this));
  1085.         }
  1086.     }

  1087.     private static class RowNumberExpression extends IntegerExpression implements CanBeWindowingFunctionRequiresOrderBy<IntegerExpression> {

  1088.         public RowNumberExpression() {
  1089.             super();
  1090.         }
  1091.         private final static long serialVersionUID = 1l;

  1092.         @Override
  1093.         public String toSQLString(DBDefinition db) {
  1094.             return db.getRowNumberFunctionName() + "()";
  1095.         }

  1096.         @Override
  1097.         public boolean isAggregator() {
  1098.             return false;
  1099.         }

  1100.         @Override
  1101.         public RowNumberExpression copy() {
  1102.             return new RowNumberExpression();
  1103.         }

  1104.         @Override
  1105.         public WindowFunctionRequiresOrderBy<IntegerExpression> over() {
  1106.             return new WindowFunctionRequiresOrderBy<IntegerExpression>(new IntegerExpression(this));
  1107.         }
  1108.     }

  1109.     public static class NTileExpression extends IntegerExpression implements CanBeWindowingFunctionRequiresOrderBy<IntegerExpression> {

  1110.         public NTileExpression(IntegerExpression only) {
  1111.             super(only);
  1112.         }

  1113.         public NTileExpression(Long only) {
  1114.             super(new IntegerExpression(only));
  1115.         }

  1116.         public NTileExpression(Integer only) {
  1117.             super(new IntegerExpression(only));
  1118.         }
  1119.         private final static long serialVersionUID = 1l;

  1120.         @Override
  1121.         public String toSQLString(DBDefinition db) {
  1122.             return db.getNTilesFunctionName() + "(" + getInnerResult().toSQLString(db) + ")";
  1123.         }

  1124.         @Override
  1125.         public boolean isAggregator() {
  1126.             return false;
  1127.         }

  1128.         @Override
  1129.         public NTileExpression copy() {
  1130.             return new NTileExpression(
  1131.                     (IntegerExpression) (getInnerResult() == null ? null : getInnerResult().copy())
  1132.             );
  1133.         }

  1134.         @Override
  1135.         public WindowFunctionRequiresOrderBy<IntegerExpression> over() {
  1136.             return new WindowFunctionRequiresOrderBy<IntegerExpression>(new IntegerExpression(this));
  1137.         }
  1138.     }
  1139. }