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

org.jooq.impl.AbstractWindowFunction Maven / Gradle / Ivy

There is a newer version: 3.19.15
Show newest version
/*
 * Licensed 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
 *
 *  https://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.
 *
 * Other licenses:
 * -----------------------------------------------------------------------------
 * Commercial licenses for this work are available. These replace the above
 * Apache-2.0 and offer limited warranties, support, maintenance, and commercial
 * database integrations.
 *
 * For more information, please visit: https://www.jooq.org/legal/licensing
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */
package org.jooq.impl;

// ...
// ...
// ...
import static org.jooq.SQLDialect.MYSQL;
// ...
import static org.jooq.SQLDialect.POSTGRES;
import static org.jooq.SQLDialect.SQLITE;
// ...
import static org.jooq.SQLDialect.YUGABYTEDB;
import static org.jooq.impl.DSL.name;
import static org.jooq.impl.Keywords.K_FIRST;
import static org.jooq.impl.Keywords.K_FROM;
import static org.jooq.impl.Keywords.K_IGNORE_NULLS;
import static org.jooq.impl.Keywords.K_LAST;
import static org.jooq.impl.Keywords.K_OVER;
import static org.jooq.impl.Keywords.K_RESPECT_NULLS;
import static org.jooq.impl.SelectQueryImpl.NO_SUPPORT_WINDOW_CLAUSE;
import static org.jooq.impl.Tools.SimpleDataKey.DATA_WINDOW_DEFINITIONS;

import java.util.Collection;
import java.util.Set;

import org.jooq.Context;
import org.jooq.DataType;
import org.jooq.Field;
import org.jooq.GroupField;
import org.jooq.Name;
import org.jooq.OrderField;
// ...
import org.jooq.QueryPart;
import org.jooq.SQLDialect;
// ...
import org.jooq.WindowDefinition;
import org.jooq.WindowExcludeStep;
import org.jooq.WindowFinalStep;
import org.jooq.WindowFromFirstLastStep;
import org.jooq.WindowIgnoreNullsStep;
import org.jooq.WindowOrderByStep;
import org.jooq.WindowOverStep;
import org.jooq.WindowPartitionByStep;
import org.jooq.WindowRowsAndStep;
import org.jooq.WindowRowsStep;
import org.jooq.WindowSpecification;
import org.jooq.impl.QOM.FromFirstOrLast;
import org.jooq.impl.QOM.NullTreatment;
import org.jooq.impl.QOM.WindowFunction;
import org.jooq.impl.Tools.ExtendedDataKey;

/**
 * @author Lukas Eder
 */
abstract class AbstractWindowFunction
extends AbstractField
implements
    WindowFromFirstLastStep,
    WindowPartitionByStep,
    WindowRowsStep,
    WindowRowsAndStep,
    WindowExcludeStep,
    WindowFunction,
    ScopeMappable
{
    private static final Set SUPPORT_NO_PARENS_WINDOW_REFERENCE = SQLDialect.supportedBy(MYSQL, POSTGRES, SQLITE, YUGABYTEDB);

    // Other attributes
    WindowSpecificationImpl              windowSpecification;
    WindowDefinitionImpl                 windowDefinition;
    Name                                 windowName;

    NullTreatment                        nullTreatment;
    FromFirstOrLast                      fromFirstOrLast;

    AbstractWindowFunction(Name name, DataType type) {
        super(name, type);
    }

    // -------------------------------------------------------------------------
    // XXX QueryPart API
    // -------------------------------------------------------------------------













    @SuppressWarnings("unchecked")
    final QueryPart window(Context ctx) {
        if (windowSpecification != null)
            return CustomQueryPart.of(c -> c.sql('(').visit(windowSpecification).sql(')'));

        // [#3727] Referenced WindowDefinitions that contain a frame clause
        // shouldn't be referenced from within parentheses (in MySQL and PostgreSQL)
        if (windowDefinition != null)
            if (SUPPORT_NO_PARENS_WINDOW_REFERENCE.contains(ctx.dialect()) && !NO_SUPPORT_WINDOW_CLAUSE.contains(ctx.dialect()))
                return windowDefinition;
            else
                return CustomQueryPart.of(c -> c.sql('(').visit(windowDefinition).sql(')'));

        // [#531] Inline window specifications if the WINDOW clause is not supported
        if (windowName != null) {
            if (!NO_SUPPORT_WINDOW_CLAUSE.contains(ctx.dialect()))
                return windowName;

            QueryPartList windows = (QueryPartList) ctx.data(DATA_WINDOW_DEFINITIONS);

            if (windows != null) {
                for (WindowDefinition window : windows)
                    if (((WindowDefinitionImpl) window).getName().equals(windowName))
                        return CustomQueryPart.of(c -> c.sql('(').visit(window).sql(')'));
            }

            // [#3162] If a window specification is missing from the query's WINDOW clause,
            // jOOQ should just render the window name regardless of the SQL dialect
            else
                return windowName;
        }

        return null;
    }

    final boolean isWindow() {
        return windowSpecification != null || windowDefinition != null || windowName != null;
    }

    final void acceptOverClause(Context ctx) {
        QueryPart window = window(ctx);

        // Render this clause only if needed
        if (window == null)
            return;

        switch (ctx.family()) {












            default:
                ctx.sql(' ')
                   .visit(K_OVER)
                   .sql(' ');

                ctx.data(ExtendedDataKey.DATA_WINDOW_FUNCTION, this, c -> c.visit(window));
                break;
        }
    }






























    final void acceptNullTreatment(Context ctx) {
        switch (ctx.family()) {















            default:
                acceptNullTreatmentStandard(ctx);
                break;
        }
    }

    final void acceptNullTreatmentStandard(Context ctx) {
        switch (ctx.family()) {






            default:
                if (nullTreatment == NullTreatment.IGNORE_NULLS)
                    ctx.sql(' ').visit(K_IGNORE_NULLS);
                else if (nullTreatment == NullTreatment.RESPECT_NULLS)
                    ctx.sql(' ').visit(K_RESPECT_NULLS);

                break;
        }
    }

    final void acceptFromFirstOrLast(Context ctx) {
        switch (ctx.family()) {










            default:
                if (fromFirstOrLast == FromFirstOrLast.FROM_LAST)
                    ctx.sql(' ').visit(K_FROM).sql(' ').visit(K_LAST);
                else if (fromFirstOrLast == FromFirstOrLast.FROM_FIRST)
                    ctx.sql(' ').visit(K_FROM).sql(' ').visit(K_FIRST);

                break;
        }
    }

    // -------------------------------------------------------------------------
    // XXX Window function fluent API methods
    // -------------------------------------------------------------------------

    @Override
    public final WindowOverStep ignoreNulls() {
        nullTreatment = NullTreatment.IGNORE_NULLS;
        return this;
    }

    @Override
    public final WindowOverStep respectNulls() {
        nullTreatment = NullTreatment.RESPECT_NULLS;
        return this;
    }

    @Override
    public final WindowIgnoreNullsStep fromFirst() {
        fromFirstOrLast = FromFirstOrLast.FROM_FIRST;
        return this;
    }

    @Override
    public final WindowIgnoreNullsStep fromLast() {
        fromFirstOrLast = FromFirstOrLast.FROM_LAST;
        return this;
    }

    @Override
    public final WindowPartitionByStep over() {
        windowSpecification = new WindowSpecificationImpl();
        return this;
    }

    @Override
    public final WindowFinalStep over(WindowSpecification specification) {
        this.windowSpecification = specification instanceof WindowSpecificationImpl w
            ? w
            : new WindowSpecificationImpl((WindowDefinitionImpl) specification);

        return this;
    }

    @Override
    public final WindowFinalStep over(WindowDefinition definition) {
        this.windowDefinition = (WindowDefinitionImpl) definition;
        return this;
    }

    @Override
    public final WindowFinalStep over(String n) {
        return over(name(n));
    }

    @Override
    public final WindowFinalStep over(Name n) {
        this.windowName = n;
        return this;
    }

    @Override
    public final WindowOrderByStep partitionBy(GroupField... fields) {
        windowSpecification.partitionBy(fields);
        return this;
    }

    @Override
    public final WindowOrderByStep partitionBy(Collection fields) {
        windowSpecification.partitionBy(fields);
        return this;
    }

    @Override
    @Deprecated
    public final WindowOrderByStep partitionByOne() {
        windowSpecification.partitionByOne();
        return this;
    }

    @Override
    public /* non-final */ AbstractWindowFunction orderBy(OrderField... fields) {
        windowSpecification.orderBy(fields);
        return this;
    }

    @Override
    public /* non-final */ AbstractWindowFunction orderBy(Collection> fields) {
        windowSpecification.orderBy(fields);
        return this;
    }

    @Override
    public final WindowExcludeStep rowsUnboundedPreceding() {
        windowSpecification.rowsUnboundedPreceding();
        return this;
    }

    @Override
    public final WindowExcludeStep rowsPreceding(int number) {
        windowSpecification.rowsPreceding(number);
        return this;
    }

    @Override
    public final WindowExcludeStep rowsCurrentRow() {
        windowSpecification.rowsCurrentRow();
        return this;
    }

    @Override
    public final WindowExcludeStep rowsUnboundedFollowing() {
        windowSpecification.rowsUnboundedFollowing();
        return this;
    }

    @Override
    public final WindowExcludeStep rowsFollowing(int number) {
        windowSpecification.rowsFollowing(number);
        return this;
    }

    @Override
    public final WindowRowsAndStep rowsBetweenUnboundedPreceding() {
        windowSpecification.rowsBetweenUnboundedPreceding();
        return this;
    }

    @Override
    public final WindowRowsAndStep rowsBetweenPreceding(int number) {
        windowSpecification.rowsBetweenPreceding(number);
        return this;
    }

    @Override
    public final WindowRowsAndStep rowsBetweenCurrentRow() {
        windowSpecification.rowsBetweenCurrentRow();
        return this;
    }

    @Override
    public final WindowRowsAndStep rowsBetweenUnboundedFollowing() {
        windowSpecification.rowsBetweenUnboundedFollowing();
        return this;
    }

    @Override
    public final WindowRowsAndStep rowsBetweenFollowing(int number) {
        windowSpecification.rowsBetweenFollowing(number);
        return this;
    }

    @Override
    public final WindowExcludeStep rangeUnboundedPreceding() {
        windowSpecification.rangeUnboundedPreceding();
        return this;
    }

    @Override
    public final WindowExcludeStep rangePreceding(int number) {
        windowSpecification.rangePreceding(number);
        return this;
    }

    @Override
    public final WindowExcludeStep rangeCurrentRow() {
        windowSpecification.rangeCurrentRow();
        return this;
    }

    @Override
    public final WindowExcludeStep rangeUnboundedFollowing() {
        windowSpecification.rangeUnboundedFollowing();
        return this;
    }

    @Override
    public final WindowExcludeStep rangeFollowing(int number) {
        windowSpecification.rangeFollowing(number);
        return this;
    }

    @Override
    public final WindowRowsAndStep rangeBetweenUnboundedPreceding() {
        windowSpecification.rangeBetweenUnboundedPreceding();
        return this;
    }

    @Override
    public final WindowRowsAndStep rangeBetweenPreceding(int number) {
        windowSpecification.rangeBetweenPreceding(number);
        return this;
    }

    @Override
    public final WindowRowsAndStep rangeBetweenCurrentRow() {
        windowSpecification.rangeBetweenCurrentRow();
        return this;
    }

    @Override
    public final WindowRowsAndStep rangeBetweenUnboundedFollowing() {
        windowSpecification.rangeBetweenUnboundedFollowing();
        return this;
    }

    @Override
    public final WindowRowsAndStep rangeBetweenFollowing(int number) {
        windowSpecification.rangeBetweenFollowing(number);
        return this;
    }

    @Override
    public final WindowExcludeStep groupsUnboundedPreceding() {
        windowSpecification.groupsUnboundedPreceding();
        return this;
    }

    @Override
    public final WindowExcludeStep groupsPreceding(int number) {
        windowSpecification.groupsPreceding(number);
        return this;
    }

    @Override
    public final WindowExcludeStep groupsCurrentRow() {
        windowSpecification.groupsCurrentRow();
        return this;
    }

    @Override
    public final WindowExcludeStep groupsUnboundedFollowing() {
        windowSpecification.groupsUnboundedFollowing();
        return this;
    }

    @Override
    public final WindowExcludeStep groupsFollowing(int number) {
        windowSpecification.groupsFollowing(number);
        return this;
    }

    @Override
    public final WindowRowsAndStep groupsBetweenUnboundedPreceding() {
        windowSpecification.groupsBetweenUnboundedPreceding();
        return this;
    }

    @Override
    public final WindowRowsAndStep groupsBetweenPreceding(int number) {
        windowSpecification.groupsBetweenPreceding(number);
        return this;
    }

    @Override
    public final WindowRowsAndStep groupsBetweenCurrentRow() {
        windowSpecification.groupsBetweenCurrentRow();
        return this;
    }

    @Override
    public final WindowRowsAndStep groupsBetweenUnboundedFollowing() {
        windowSpecification.groupsBetweenUnboundedFollowing();
        return this;
    }

    @Override
    public final WindowRowsAndStep groupsBetweenFollowing(int number) {
        windowSpecification.groupsBetweenFollowing(number);
        return this;
    }

    @Override
    public final WindowExcludeStep andUnboundedPreceding() {
        windowSpecification.andUnboundedPreceding();
        return this;
    }

    @Override
    public final WindowExcludeStep andPreceding(int number) {
        windowSpecification.andPreceding(number);
        return this;
    }

    @Override
    public final WindowExcludeStep andCurrentRow() {
        windowSpecification.andCurrentRow();
        return this;
    }

    @Override
    public final WindowExcludeStep andUnboundedFollowing() {
        windowSpecification.andUnboundedFollowing();
        return this;
    }

    @Override
    public final WindowExcludeStep andFollowing(int number) {
        windowSpecification.andFollowing(number);
        return this;
    }

    @Override
    public final WindowFinalStep excludeCurrentRow() {
        windowSpecification.excludeCurrentRow();
        return this;
    }

    @Override
    public final WindowFinalStep excludeGroup() {
        windowSpecification.excludeGroup();
        return this;
    }

    @Override
    public final WindowFinalStep excludeTies() {
        windowSpecification.excludeTies();
        return this;
    }

    @Override
    public final WindowFinalStep excludeNoOthers() {
        windowSpecification.excludeNoOthers();
        return this;
    }

    // -------------------------------------------------------------------------
    // XXX: Query Object Model
    // -------------------------------------------------------------------------

    @Override
    public final WindowSpecification $windowSpecification() {
        return windowSpecification;
    }

    final AbstractWindowFunction $windowSpecification(WindowSpecification s) {
        windowSpecification = (WindowSpecificationImpl) s;
        return this;
    }

    @Override
    public final WindowDefinition $windowDefinition() {
        return windowDefinition;
    }

    final AbstractWindowFunction $windowDefinition(WindowDefinition d) {
        windowDefinition = (WindowDefinitionImpl) d;
        return this;
    }

    public final NullTreatment $nullTreatment() {
        return nullTreatment;
    }

    final AbstractWindowFunction $nullTreatment(NullTreatment n) {
        nullTreatment = n;
        return this;
    }

    public final FromFirstOrLast $fromFirstOrLast() {
        return fromFirstOrLast;
    }

    final AbstractWindowFunction $fromFirstOrLast(FromFirstOrLast f) {
        fromFirstOrLast = f;
        return this;
    }













}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy